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;