xlib_playground

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 6652ec59c457c3f0a70aa89302279c52abd85f62
parent 60689a306dbcf75ea03418b7893fcf0933ff01d4
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Thu, 15 Dec 2022 14:32:09 +0900

add key control

Diffstat:
M.gitignore | 1+
Mmain.c | 110++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Mobj.c | 2++
Mobj.h | 1+
4 files changed, 85 insertions(+), 29 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1 +1,2 @@ main +main.core diff --git a/main.c b/main.c @@ -11,23 +11,42 @@ #define INIT_HEIGHT 600 #define FPS 60 + /* variables */ Display *display; Window window; unsigned int win_width = INIT_WIDTH, win_height = INIT_HEIGHT; GC gc; Atom wm_delete_window; -Obj square = {1, 1, 100, 100, 20, 20}; +Obj square = {100, 100, 0, 0, 0, 0, 20, 20}; int quit = 0; +enum Keys { + Key_D, + Key_S, + Key_A, + Key_W, + Num_Key, +}; +enum Key_State { + Key_Down, + Key_Up, +}; +int key_state[Num_Key]; + + /* function prototypes */ void setup(void); +void next_tick(void); void cleanup(void); void setup(void) { + for(int i = 0; i < Num_Key; i++) + key_state[i] = Key_Up; + if((display = XOpenDisplay(NULL)) == NULL){ fprintf(stderr, "ERROR: could not open display\n"); exit(1); @@ -45,14 +64,51 @@ setup(void) wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); XSetWMProtocols(display, window, &wm_delete_window, 1); - XSelectInput(display, window, KeyPressMask); - + XSelectInput(display, window, KeyPressMask | KeyReleaseMask); + + XSetForeground(display, gc, 0x00FF00); XMapWindow(display, window); } void +next_tick(void) +{ + square.vx = 0; + if(key_state[Key_D] == Key_Down) + square.vx += 300; + if(key_state[Key_A] == Key_Down) + square.vx += -300; + if(key_state[Key_D] == Key_Up && key_state[Key_A] == Key_Up) + square.vx = 0; + + if(key_state[Key_W] == Key_Down && win_height <= square.py + square.height){ + square.vy = -400; + } + + obj_next_tick(&square, 1.0/FPS); + + if(square.px <= 0){ + square.px = 0; + } + if(win_width <= square.px + square.width){ + square.px = win_width - square.width; + } + + square.ay = 980; + if(square.py <= 0){ + square.py = 0; + square.vy = 0; + } + if(win_height <= square.py + square.height){ + square.py = win_height - square.height; + square.vy = 0; + } +} + +void cleanup(void) { + XCloseDisplay(display); } @@ -63,7 +119,7 @@ main(void) while (!quit) { while (XPending(display) > 0) { - XEvent event = {0}; + XEvent event; XNextEvent(display, &event); switch (event.type) { case KeyPress: { @@ -72,21 +128,37 @@ main(void) quit = 1; break; case 'd': - square.vx += 10; + key_state[Key_D] = Key_Down; break; case 'a': - square.vx -= 10; + key_state[Key_A] = Key_Down; break; case 'w': - square.vy -= 10; + key_state[Key_W] = Key_Down; break; case 's': - square.vy += 10; + key_state[Key_S] = Key_Down; break; default: break; } } break; + case KeyRelease: { + switch (XLookupKeysym(&event.xkey, 0)) { + case 'd': + key_state[Key_D] = Key_Up; + break; + case 'a': + key_state[Key_A] = Key_Up; + break; + case 'w': + key_state[Key_W] = Key_Up; + break; + case 's': + key_state[Key_S] = Key_Up; + break; + } + } break; case ClientMessage: { if ((Atom) event.xclient.data.l[0] == wm_delete_window) { quit = 1; @@ -95,34 +167,14 @@ main(void) } } - XWindowAttributes window_attributes_return; XGetWindowAttributes(display, window, &window_attributes_return); win_width = window_attributes_return.width; win_height = window_attributes_return.height; - if(square.px <= 0){ - square.px = 0; - square.vx *= -1; - } - if(win_width <= square.px + square.width){ - square.px = win_width - square.width; - square.vx *= -1; - } - if(square.py <= 0){ - square.py = 0; - square.vy *= -1; - } - if(win_height <= square.py + square.height){ - square.py = win_height - square.height; - square.vy *= -1; - } - obj_accel(&square, 0, 9.8); - obj_next_tick(&square, 1.0/FPS); - + next_tick(); XClearArea(display, window, 0, 0, win_width, win_height, False); - XSetForeground(display, gc, 0x00FF00); XFillRectangle(display, window, gc, square.px, square.py, square.width, square.height); struct timespec timetosleep = {0, 1000*1000*1000/FPS}; //not accurate diff --git a/obj.c b/obj.c @@ -10,6 +10,8 @@ obj_move(Obj *obj, float px, float py) void obj_next_tick(Obj *obj, float dt) { + obj->vx += obj->ax * dt; + obj->vy += obj->ay * dt; obj->px += obj->vx * dt; obj->py += obj->vy * dt; } diff --git a/obj.h b/obj.h @@ -1,6 +1,7 @@ typedef struct Obj{ float px, py; float vx, vy; + float ax, ay; float width, height; } Obj;