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 | + |
M | main.c | | | 110 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- |
M | obj.c | | | 2 | ++ |
M | obj.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;