commit bf99ee5e45e20f75539e34d4cae7a236a5638430
parent fcd90e72f24211f1accd6c1413711e1169591e54
Author: Matsuda Kenji <info@mtkn.jp>
Date: Thu, 5 Jan 2023 07:54:24 +0900
delete original
Diffstat:
D | Makefile | | | 14 | -------------- |
D | main.c | | | 393 | ------------------------------------------------------------------------------- |
D | obj.h | | | 101 | ------------------------------------------------------------------------------- |
3 files changed, 0 insertions(+), 508 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,14 +0,0 @@
-INCS=-I/usr/X11R6/include
-CFLAGS=-Wall -W -Wextra -Wpointer-arith -Wbad-function-cast -std=c11
-LIBS=-L/usr/X11R6/lib -lX11 -lXext
-IN=*.c
-OUT=main
-
-all: $(IN)
- $(CC) $(INCS) $(CFLAGS) -o $(OUT) $(IN) $(LIBS)
-
-run: all
- ./$(OUT)
-
-clean:
- rm -f $(OUT)
diff --git a/main.c b/main.c
@@ -1,393 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <string.h>
-
-#include <X11/Xlib.h>
-
-#include "obj.h"
-
-/* macros */
-#define INIT_WIDTH 800
-#define INIT_HEIGHT 600
-#define FPS 60
-#define BLOCK_COUNT 3
-
-
-/* variables */
-Display *display;
-Window window;
-unsigned int win_width = INIT_WIDTH, win_height = INIT_HEIGHT;
-GC pgc, fgc, bgc;
-Atom wm_delete_window;
-Obj *square;
-Obj *blocks[BLOCK_COUNT];
-int quit = 0;
-enum Keys {
- Key_D,
- Key_S,
- Key_A,
- Key_W,
- Key_Space,
- Num_Key, //number of keys in this enum
-};
-enum Key_State {
- Key_Up,
- Key_Down,
-};
-int key_state[Num_Key];
-enum Next_Menu {
- Start_Menu,
- Game_Play,
- End_Menu,
- Quit,
-};
-int next_menu = Start_Menu;
-
-
-/* function prototypes */
-void setup(void);
-void start_menu(void);
-void game_init(void);
-void game_play(void);
-void draw_object(Obj *, GC);
-void handle_collision(void);
-void handle_inputs(void);
-void end_menu(void);
-void next_tick(float);
-void cleanup(void);
-
-
-void
-setup(void)
-{
- if ((display = XOpenDisplay(NULL)) == NULL){
- fprintf(stderr, "ERROR: could not open display\n");
- exit(1);
- }
- window = XCreateSimpleWindow(
- display,
- XDefaultRootWindow(display),
- 0, 0,
- win_width, win_height,
- 0, 0,
- 0);
- XStoreName(display, window, "UNKO");
- pgc = XCreateGC(display, window, 0, NULL);
- fgc = XCreateGC(display, window, 0, NULL);
- bgc = XCreateGC(display, window, 0, NULL);
-
- wm_delete_window = XInternAtom(display,
- "WM_DELETE_WINDOW", False);
- XSetWMProtocols(display, window, &wm_delete_window, 1);
-
- XSelectInput(display, window,
- ExposureMask|KeyPressMask|KeyReleaseMask);
-
- XSetForeground(display, pgc, 0x00FF00);
- XSetForeground(display, fgc, 0xFFFFFF);
- XSetForeground(display, bgc, 0x0000FF);
- XMapWindow(display, window);
-}
-
-void
-start_menu(void)
-{
- XEvent event;
- char *menu_char_q = "press q to quit.";
- char *menu_char_s = "press <space> to start.";
-
- XClearArea(display, window, 0, 0, win_width, win_height, False);
-
- XDrawString(display, window, fgc,
- win_width/2 - strlen(menu_char_q)/2, win_height/2,
- menu_char_q, strlen(menu_char_q));
- XDrawString(display, window, fgc,
- win_width/2 - strlen(menu_char_s)/2, win_height/2 + 20,
- menu_char_s, strlen(menu_char_s));
-
- while (next_menu == Start_Menu) {
- XNextEvent(display, &event);
- switch (event.type) {
- case Expose: {
- XDrawString(display, window, fgc,
- win_width/2 - strlen(menu_char_q)/2, win_height/2,
- menu_char_q, strlen(menu_char_q));
- XDrawString(display, window, fgc,
- win_width/2 - strlen(menu_char_s)/2, win_height/2 + 20,
- menu_char_s, strlen(menu_char_s));
-
- } break;
- case KeyPress: {
- switch (XLookupKeysym(&event.xkey, 0)) {
- case 'q':
- next_menu = Quit;
- break;
- case ' ':
- next_menu = Game_Play;
- break;
- default:
- break;
- }
- } break;
- case ClientMessage: {
- if ((Atom) event.xclient.data.l[0] == wm_delete_window) {
- next_menu = Quit;
- }
- } break;
- default:
- break;
- }
- }
-}
-
-void
-game_init(void)
-{
- if(!square) // not allocated
- if(!(square = obj_create(100, 100, 0, 0, 0, 0, 400, 20, 20))){
- fprintf(stderr, "couldn't create object: square");
- exit(1);
- }
- for (int i = 0; i < BLOCK_COUNT; i++){
- struct timespec t;
- clock_gettime(CLOCK_REALTIME, &t);
- srand(t.tv_nsec);
- if(!blocks[i]) // not allocated
- if(!(blocks[i] = obj_create((i + 1) * 100,
- 200,
- 0, 0,
- 0, 0, 100, 10, 10))){
- fprintf(stderr, "couldn't create object: block");
- exit(1);
- }
- }
-
- square->px = 100;
- square->py = 100;
- square->vx = square->vy = 0;
- square->ax = square->ay = 0;
-}
-
-void
-game_play(void)
-{
- long t0, t1, dt;
- struct timespec ts;
-
- game_init();
-
- clock_gettime(CLOCK_MONOTONIC, &ts);
- t0 = ts.tv_nsec;
-
- while (next_menu == Game_Play){
- XWindowAttributes window_attributes_return;
- XGetWindowAttributes(display, window, &window_attributes_return);
- win_width = window_attributes_return.width;
- win_height = window_attributes_return.height;
-
- clock_gettime(CLOCK_MONOTONIC, &ts);
- t1 = ts.tv_nsec;
- dt = t1 - t0 > 0 ? t1 - t0 : t1 - t0 + 1000 * 1000 * 1000;
- while(dt < 1.0/FPS * 1000 * 1000 * 1000){
- clock_gettime(CLOCK_MONOTONIC, &ts);
- t1 = ts.tv_nsec;
- dt = t1 - t0 > 0 ? t1 - t0 : t1 - t0 + 1000 * 1000 * 1000;
- }
-
- //handle_interactions(); //handle interactions between objects
- handle_inputs();
- obj_next_tick(square, 1.0/FPS);
- for (int i = 0; i < BLOCK_COUNT; i++)
- obj_next_tick(blocks[i], 1.0/FPS);
- handle_collision();
-
- clock_gettime(CLOCK_MONOTONIC, &ts);
- t0 = ts.tv_nsec;
-
- XClearArea(display, window, 0, 0, win_width, win_height, False);
- draw_object(square, pgc);
- for (int i = 0; i < BLOCK_COUNT; i++){
- XSetForeground(display, bgc, 255 << 8 * i);
- draw_object(blocks[i], bgc);
- }
- //XDrawString(display, window, fgc, square->px, square->py, "player", 6);
- }
-}
-
-void
-draw_object(Obj *obj, GC gc)
-{
- XFillRectangle(display, window, gc, obj->px, obj->py, obj->width, obj->height);
-}
-
-void
-end_menu(void)
-{
- next_menu = Start_Menu;
-}
-
-void
-handle_inputs(void)
-{
- while (XPending(display) > 0) {
- XEvent event;
- XNextEvent(display, &event);
- switch (event.type) {
- case KeyPress: {
- switch (XLookupKeysym(&event.xkey, 0)) {
- case 'q':
- next_menu = End_Menu;
- break;
- case 'd':
- key_state[Key_D] = Key_Down;
- break;
- case 'a':
- key_state[Key_A] = Key_Down;
- break;
- case 'w':
- key_state[Key_W] = Key_Down;
- break;
- case 's':
- key_state[Key_S] = Key_Down;
- break;
- case ' ':
- key_state[Key_Space] = 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;
- case ' ':
- key_state[Key_Space] = Key_Up;
- break;
- default:
- break;
- }
- } break;
- case ClientMessage: {
- if ((Atom) event.xclient.data.l[0] == wm_delete_window) {
- next_menu = Quit;
- }
- } break;
- default:
- break;
- }
- }
-
- square->vx = 0;
- if (key_state[Key_D] == Key_Down)
- square->vx += 100;
- else
- square->vx -= 100;
- if (key_state[Key_A] == Key_Down)
- square->vx += -100;
- else
- square->vx -= -100;
-
- square->vy = 0;
- if (key_state[Key_S] == Key_Down)
- square->vy += 100;
- else
- square->vy -= 100;
- if (key_state[Key_W] == Key_Down)
- square->vy += -100;
- else
- square->vy -= -100;
-}
-
-void
-handle_collision(void)
-{
- for (int i = 0; i < BLOCK_COUNT; i++){
- if (blocks[i]->px <= 0){
- blocks[i]->px = 0;
- blocks[i]->vx *= -1;
- }
- if (win_width <= blocks[i]->px + blocks[i]->width){
- blocks[i]->px = win_width - blocks[i]->width;
- blocks[i]->vx *= -1;
- }
-
- if (blocks[i]->py <= 0){
- blocks[i]->py = 0;
- blocks[i]->vy *= -1;
- }
- if (win_height <= blocks[i]->py + blocks[i]->height){
- blocks[i]->py = win_height - blocks[i]->height;
- blocks[i]->vy *= -1;
- }
- }
-
- 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;
- }
-
- for (int i = 0; i < BLOCK_COUNT; i++){
- for (int j = i; j < BLOCK_COUNT; j++){
- obj_handle_collision(blocks[i], blocks[j]);
- }
- }
- for (int i = 0; i < BLOCK_COUNT; i++){
- obj_handle_collision(blocks[i], square);
- }
-}
-
-
-void
-cleanup(void)
-{
- XCloseDisplay(display);
-}
-
-int
-main(void)
-{
- setup();
-
- while (next_menu != Quit){
- switch (next_menu){
- case Start_Menu:
- start_menu();
- break;
- case Game_Play:
- game_play();
- break;
- case End_Menu:
- end_menu();
- break;
- default:
- break;
- }
- }
-
- cleanup();
- return 0;
-}
diff --git a/obj.h b/obj.h
@@ -1,101 +0,0 @@
-typedef struct Obj{
- float ppx, ppy; //previous position
- float px, py; //current position
- float vx, vy; //velocity
- float ax, ay; //acceleration
- float m; //mass
- float width, height;
-} Obj;
-
-Obj *obj_create(float px, float py,
- float vx, float vy,
- float ax, float ay,
- float m,
- float width, float height);
-void obj_move(Obj *obj, float px, float py); // move obj to the pos
-void obj_next_tick(Obj *obj, float dt); // move obj by velocity * dt
-void obj_accel(Obj *obj, float ax, float ay); // accelerate obj by accel
-int obj_test_collision(Obj *obj1, Obj *obj2);
-void obj_handle_collision(Obj *obj1, Obj *obj2);
-
-Obj
-*obj_create(float px, float py,
- float vx, float vy,
- float ax, float ay,
- float m,
- float width, float height)
-{
- Obj *obj;
- obj = (Obj *) malloc(sizeof(Obj));
- obj->ppx = obj->px = px;
- obj->ppy = obj->py = py;
- obj->vx = vx;
- obj->vy = vy;
- obj->ax = ax;
- obj->ay = ay;
- obj->m = m;
- obj->width = width;
- obj->height = height;
- return obj;
-}
-
-void
-obj_move(Obj *obj, float px, float py)
-{
- obj->ppx = obj->px = px;
- obj->ppy = obj->py = py;
-}
-
-void
-obj_next_tick(Obj *obj, float dt)
-{
- obj->ppx = obj->px;
- obj->ppy = obj->py;
- obj->vx += obj->ax * dt;
- obj->vy += obj->ay * dt;
- obj->px += obj->vx * dt;
- obj->py += obj->vy * dt;
-}
-
-void
-obj_accel(Obj *obj, float ax, float ay)
-{
- obj->vx += ax;
- obj->vy += ay;
-}
-
-
-int
-obj_test_collision(Obj *obj1, Obj *obj2)
-{
- return obj1->py < obj2->py + obj2->height &&
- obj2->py < obj1->py + obj1->height &&
- obj1->px < obj2->px + obj2->width &&
- obj2->px < obj1->px + obj1->width;
-}
-
-void
-obj_handle_collision(Obj *obj1, Obj *obj2)
-{
- if(!obj_test_collision(obj1, obj2))
- return;
-
- float v1, v2;
- float m1 = obj1->m;
- float m2 = obj2->m;
-
- if (obj2->ppy + obj2->height <= obj1->ppy ||
- obj1->ppy + obj1->height <= obj2->ppy){
- v1 = obj1->vy;
- v2 = obj2->vy;
- obj1->vy = 2*m2/(m1+m2)*v2 + (m1-m2)/(m1+m2)*v1;
- obj2->vy = 2*m1/(m1+m2)*v1 + (m2-m1)/(m1+m2)*v2;
- }else if (obj2->ppx + obj2->width <= obj1->ppx ||
- obj1->ppx + obj1->width <= obj2->ppx){
- v1 = obj1->vx;
- v2 = obj2->vx;
- obj1->vx = 2*m2/(m1+m2)*v2 + (m1-m2)/(m1+m2)*v1;
- obj2->vx = 2*m1/(m1+m2)*v1 + (m2-m1)/(m1+m2)*v2;
- }
-
-}