xlib_playground

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

commit aca29690679b950892d98fa7b2c345acba386b21
parent 6efcb129b7d389c59b2e98485eecfbc4ac1a7523
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue, 20 Dec 2022 15:46:43 +0900

add mass

Diffstat:
Mmain.c | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Mobj.h | 43++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 108 insertions(+), 30 deletions(-)

diff --git a/main.c b/main.c @@ -11,6 +11,7 @@ #define INIT_WIDTH 800 #define INIT_HEIGHT 600 #define FPS 60 +#define BLOCK_COUNT 100 /* variables */ @@ -20,7 +21,7 @@ unsigned int win_width = INIT_WIDTH, win_height = INIT_HEIGHT; GC pgc, fgc, bgc; Atom wm_delete_window; Obj *square; -Obj *block; +Obj *blocks[BLOCK_COUNT]; int quit = 0; enum Keys { Key_D, @@ -55,8 +56,7 @@ void handle_inputs(void); void end_menu(void); void next_tick(float); void cleanup(void); -//int check_collision(Obj *, Obj *); -//int handle_collision(Obj *, Obj *); + void setup(void) @@ -145,15 +145,24 @@ void game_init(void) { if(!square) // not allocated - if(!(square = obj_create(100, 100, 0, 0, 0, 0, 20, 20))){ + if(!(square = obj_create(100, 100, 0, 0, 0, 0, 400, 20, 20))){ fprintf(stderr, "couldn't create object: square"); exit(1); } - if(!block) // not allocated - if(!(block = obj_create(200, 200, 0, 0, 0, 0, 20, 20))){ - fprintf(stderr, "couldn't create object: block"); - 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((float)rand()*win_width/(float)RAND_MAX, + (float)rand()*win_height/(float)RAND_MAX, + rand()*300.0/RAND_MAX - 150, + rand()*300.0/RAND_MAX - 150, + 0, 0, 100, 10, 10))){ + fprintf(stderr, "couldn't create object: block"); + exit(1); + } + } square->px = 100; square->py = 100; @@ -190,6 +199,8 @@ game_play(void) //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); @@ -197,7 +208,9 @@ game_play(void) XClearArea(display, window, 0, 0, win_width, win_height, False); draw_object(square, pgc); - draw_object(block, bgc); + for (int i = 0; i < BLOCK_COUNT; i++){ + draw_object(blocks[i], bgc); + } //XDrawString(display, window, fgc, square->px, square->py, "player", 6); } } @@ -276,54 +289,78 @@ handle_inputs(void) } } - square->vx = 0; if (key_state[Key_D] == Key_Down) square->vx += 300; + else + square->vx -= 300; if (key_state[Key_A] == Key_Down) square->vx += -300; + else + square->vx -= -300; - square->vy = 0; if (key_state[Key_S] == Key_Down) square->vy += 300; + else + square->vy -= 300; if (key_state[Key_W] == Key_Down) square->vy += -300; + else + square->vy -= -300; + + if (square->vx > 300) square->vx = 300; + if (square->vx < -300) square->vx = -300; + if (square->vy > 300) square->vy = 300; + if (square->vy < -300) square->vy = -300; } 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 = 0; + square->vx *= -1; } if (win_width <= square->px + square->width){ square->px = win_width - square->width; - square->vx = 0; + square->vx *= -1; } - if (square->py <= 0){ square->py = 0; - square->vy = 0; + square->vy *= -1; } if (win_height <= square->py + square->height){ square->py = win_height - square->height; - square->vy = 0; + square->vy *= -1; } - if (block->py < square->py + square->height && - square->py < block->py + block->height && - block->px < square->px + square->width && - square->px < block->px + block->width){ - if (square->ppy + square->height <= block->ppy){ - obj_move(block, block->px, square->py + square->height); - }else if (block->ppy + block->height <= square->ppy){ - obj_move(block, block->px, square->py - block->height); - }else if (square->ppx + square->width <= block->ppx){ - obj_move(block, square->px + square->width, block->py); - }else if (block->ppx + block->width <= square->ppx){ - obj_move(block, square->px - block->width, block->py); + 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); + } } diff --git a/obj.h b/obj.h @@ -3,22 +3,26 @@ typedef struct Obj{ 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; @@ -29,6 +33,7 @@ Obj obj->vy = vy; obj->ax = ax; obj->ay = ay; + obj->m = m; obj->width = width; obj->height = height; return obj; @@ -58,3 +63,39 @@ 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; + } + +}