diff options
| author | Aldrik Ramaekers <aldrik@amftech.nl> | 2022-12-08 13:05:51 +0100 |
|---|---|---|
| committer | Aldrik Ramaekers <aldrik@amftech.nl> | 2022-12-08 13:05:51 +0100 |
| commit | f8b97f2450bb789ae54a1d8d3845110342ff6134 (patch) | |
| tree | 92d25a57f60ead33c7209879e181bc01206fed69 | |
| parent | 0c44af8f6c45e5bb957f38cc3e9784ca69524261 (diff) | |
work
| -rw-r--r-- | build/zombies.exe | bin | 1650189 -> 1655018 bytes | |||
| -rw-r--r-- | include/map.h | 40 | ||||
| -rw-r--r-- | include/players.h | 10 | ||||
| -rw-r--r-- | include/zombies.h | 14 | ||||
| -rw-r--r-- | map.c | 11 | ||||
| -rw-r--r-- | objects.c | 32 | ||||
| -rw-r--r-- | players.c | 140 | ||||
| -rw-r--r-- | zombies.c | 35 |
8 files changed, 201 insertions, 81 deletions
diff --git a/build/zombies.exe b/build/zombies.exe Binary files differindex 86c8faa..30bfe17 100644 --- a/build/zombies.exe +++ b/build/zombies.exe diff --git a/include/map.h b/include/map.h index 0bf1028..735c106 100644 --- a/include/map.h +++ b/include/map.h @@ -22,13 +22,10 @@ typedef struct t_tile { vec2f br; } tile; -tile map_loaded[10][10]; +#define MAP_SIZE_X 20 +#define MAP_SIZE_Y 20 -// data data that is stored on disk -vec2 spawner_tiles[2] = { - {9, 0}, - {1, 8}, -}; +tile map_loaded[MAP_SIZE_Y][MAP_SIZE_X]; typedef struct t_map_info { int tile_width; @@ -38,17 +35,26 @@ typedef struct t_map_info { } map_info; // data data that is stored on disk -int map[10][10] = { - {0,0,0,0,0,0,0,0,0,1}, - {0,0,0,0,0,0,0,0,0,0}, - {0,0,0,1,1,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0}, - {0,0,0,1,1,2,1,0,0,0}, - {0,0,0,0,0,0,1,0,0,0}, - {0,0,0,0,0,0,0,0,0,0}, +int map[MAP_SIZE_Y][MAP_SIZE_X] = { + {0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, }; void load_map_from_data(); diff --git a/include/players.h b/include/players.h index b74ce7e..844cb17 100644 --- a/include/players.h +++ b/include/players.h @@ -8,16 +8,16 @@ typedef struct t_bullet { bool active; - float x; - float y; - float h; - float xacceleration; - float yacceleration; + vec3f position; + float endx; + float endy; + float alive_time; } bullet; bullet bullets[500] = {0}; int max_bullets = 500; +float sec_since_last_shot = 10.0f; float playerx = 3; float playery = 3; diff --git a/include/zombies.h b/include/zombies.h index c9e22f1..44b2956 100644 --- a/include/zombies.h +++ b/include/zombies.h @@ -9,9 +9,21 @@ typedef struct t_zombie { bool alive; float health; - vec2f position; + vec3f position; + vec3f size; } zombie; +typedef struct t_spawner { + vec2 position; + float sec_since_last_spawn; +} spawner; + +// data data that is stored on disk +spawner spawner_tiles[2] = { + {9, 0, 0}, + {1, 8, 0}, +}; + zombie zombies[50] = {0}; int max_zombies = 50; @@ -95,8 +95,8 @@ static int get_height_of_tile_tr(int current_height, int x, int y) { // load hardcoded map. void load_map_from_data() { - for (int y = 0; y < 10; y++) { - for (int x = 9; x >= 0; x--) { + for (int y = 0; y < MAP_SIZE_Y; y++) { + for (int x = MAP_SIZE_X-1; x >= 0; x--) { int h = map[y][x]; int highest_point_topleft = get_height_of_tile_tl(h, x, y); int highest_point_topright = get_height_of_tile_tr(h, x, y); @@ -156,15 +156,14 @@ bool is_in_bounds(platform_window* window, float x, float y) { int tile_width = get_tile_width(window); int tile_height = get_tile_height(window); int xdiff_between_bottom_and_top = tile_width/3; - return (x >= 0 && x <= 10 && y >= 0 && y < 10); + return (x >= 0 && x <= MAP_SIZE_X && y >= 0 && y < MAP_SIZE_Y); } - void draw_grid(platform_window* window) { map_info info = get_map_info(window); - for (int y = 0; y < 10; y++) { - for (int x = 9; x >= 0; x--) { + for (int y = 0; y < MAP_SIZE_Y; y++) { + for (int x = MAP_SIZE_X-1; x >= 0; x--) { tile tile = map_loaded[y][x]; int xdiff_between_bottom_and_top = info.tile_width/3; @@ -1,22 +1,26 @@ #include "include/objects.h" -box get_box_of_object(platform_window* window, object o) { +box get_box_of_square(platform_window* window, vec3f position, vec3f size) { map_info info = get_map_info(window); - float render_x = (info.tile_width * o.position.x) + (info.px_incline * o.position.y); - vec2f rendertl = (vec2f){render_x, info.tile_width * o.position.y - o.h*info.px_raised_per_h}; - vec2f rendertr = (vec2f){render_x + info.tile_width, info.tile_height * o.position.y - o.h*info.px_raised_per_h}; - vec2f renderbr = (vec2f){render_x + info.px_incline+info.tile_width, info.tile_height * o.position.y + info.tile_height - o.h*info.px_raised_per_h}; - vec2f renderbl = (vec2f){render_x + info.px_incline, info.tile_height * o.position.y + info.tile_height - o.h*info.px_raised_per_h}; - - o.h += o.size.z; - vec2f rendertl2 = (vec2f){render_x, info.tile_width * o.position.y - o.h*info.px_raised_per_h}; - vec2f rendertr2 = (vec2f){render_x + info.tile_width, info.tile_height * o.position.y - o.h*info.px_raised_per_h}; - vec2f renderbr2 = (vec2f){render_x + info.px_incline+info.tile_width, info.tile_height * o.position.y + info.tile_height - o.h*info.px_raised_per_h}; - vec2f renderbl2 = (vec2f){render_x + info.px_incline, info.tile_height * o.position.y + info.tile_height - o.h*info.px_raised_per_h}; + float render_x = (info.tile_width * position.x) + (info.px_incline * position.y); + vec2f rendertl = (vec2f){render_x, info.tile_width * position.y - position.z*info.px_raised_per_h}; + vec2f rendertr = (vec2f){render_x + info.tile_width*size.x, info.tile_height * position.y - position.z*info.px_raised_per_h}; + vec2f renderbr = (vec2f){render_x + (info.px_incline+info.tile_width)*size.x, info.tile_height * position.y + info.tile_height*size.y - position.z*info.px_raised_per_h}; + vec2f renderbl = (vec2f){render_x + info.px_incline*size.x, info.tile_height * position.y + info.tile_height*size.y - position.z*info.px_raised_per_h}; + + position.z += size.z; + vec2f rendertl2 = (vec2f){render_x, info.tile_width * position.y - position.z*info.px_raised_per_h}; + vec2f rendertr2 = (vec2f){render_x + info.tile_width*size.x, info.tile_height * position.y - position.z*info.px_raised_per_h}; + vec2f renderbr2 = (vec2f){render_x + (info.px_incline+info.tile_width)*size.x, info.tile_height * position.y + info.tile_height*size.y - position.z*info.px_raised_per_h}; + vec2f renderbl2 = (vec2f){render_x + info.px_incline*size.x, info.tile_height * position.y + info.tile_height*size.y - position.z*info.px_raised_per_h}; return (box){rendertl, rendertr, renderbl, renderbr, rendertl2, rendertr2, renderbl2, renderbr2}; } +box get_box_of_object(platform_window* window, object o) { + return get_box_of_square(window, (vec3f){o.position.x, o.position.y, o.h}, o.size); +} + void render_quad_with_outline(vec2f tl, vec2f tr, vec2f bl, vec2f br) { renderer->render_quad( tl.x, tl.y, @@ -45,9 +49,9 @@ void draw_objects_at_row(platform_window* window, int row) { bool did_player_draw = false; int x_of_player = playerx; - int y_of_player = playery; + int y_of_player = ceil(playery); - for (int i = 10; i >= 0; i--) { + for (int i = MAP_SIZE_X-1; i >= 0; i--) { object o = get_object_at_tile(i, row); if (row == y_of_player && x_of_player == i) { @@ -8,12 +8,12 @@ float get_bullet_size(platform_window* window) { return get_tile_width(window) * get_bullet_size_in_tile(window); } -float get_player_size_in_tile(platform_window* window) { +float get_player_size_in_tile() { return 0.5; } float get_player_size(platform_window* window) { - int player_size = get_tile_width(window) * get_player_size_in_tile(window); + int player_size = get_tile_width(window) * get_player_size_in_tile(); } object check_if_player_collided_with_object(platform_window* window) { @@ -26,8 +26,8 @@ object check_if_player_collided_with_object(platform_window* window) { box box = get_box_of_object(window, o); float x_to_check = playerx; - float y_to_check = playery; float player_size_in_tile_px = player_size / (float)info.tile_width; + float y_to_check = playery + player_size_in_tile_px; if (x_to_check+player_size_in_tile_px >= o.position.x && x_to_check <= o.position.x+o.size.x && y_to_check >= o.position.y && y_to_check <= o.position.y+o.size.y) { @@ -50,7 +50,7 @@ void take_player_input(platform_window* window) { if (is_in_bounds(window, playerx, newy)) { playery = newy; object o = check_if_player_collided_with_object(window); - if (o.active) playery = o.position.y+o.size.y + pad_between_player_and_obj; + if (o.active) playery = o.position.y+o.size.y - get_player_size_in_tile() + pad_between_player_and_obj; } } @@ -59,7 +59,7 @@ void take_player_input(platform_window* window) { if (is_in_bounds(window, playerx, newy)) { playery = newy; object o = check_if_player_collided_with_object(window); - if (o.active) playery = o.position.y - pad_between_player_and_obj; + if (o.active) playery = o.position.y - get_player_size_in_tile() - pad_between_player_and_obj; } } @@ -77,7 +77,7 @@ void take_player_input(platform_window* window) { if (is_in_bounds(window, newx, playery)) { playerx = newx; object o = check_if_player_collided_with_object(window); - if (o.active) playerx = o.position.x-get_player_size_in_tile(window) - pad_between_player_and_obj; + if (o.active) playerx = o.position.x-get_player_size_in_tile() - pad_between_player_and_obj; } } } @@ -89,13 +89,17 @@ void draw_player(platform_window* window) { take_player_input(window); + sec_since_last_shot += update_delta; if (is_left_down()) { - shoot(window); + if (sec_since_last_shot > 0.3f) { + shoot(window); + sec_since_last_shot = 0.0f; + } } float player_render_x = playerx*info.tile_width + (playery*info.px_incline); float player_render_y = playery*info.tile_height - (height*info.px_raised_per_h); - renderer->render_rectangle(player_render_x, player_render_y - size, size, size, rgb(200,150,120)); + renderer->render_rectangle(player_render_x, player_render_y, size, size, rgb(200,150,120)); _global_camera.x = -(window->width / 2) + player_render_x; _global_camera.y = -(window->height / 2) + player_render_y; @@ -103,6 +107,7 @@ void draw_player(platform_window* window) { void shoot(platform_window* window) { map_info info = get_map_info(window); + float bullet_range = 100.0f; float hh = get_height_of_tile_under_coords(window, playerx, playery); @@ -112,15 +117,66 @@ void shoot(platform_window* window) { dirx /= length; diry /= length; + float bulletx = playerx + (get_player_size_in_tile()/2); + float bullety = playery + (get_player_size_in_tile()/2); + float bullet_end_point_x = bulletx+dirx*bullet_range; + float bullet_end_point_y = bullety+diry*bullet_range; + for (int i = 0; i < max_bullets; i++) { bullet b = bullets[i]; if (b.active) continue; - bullets[i] = (bullet){true, playerx, playery, hh + 0.5f, dirx, diry}; + bullets[i] = (bullet){true, bulletx, bullety, hh, bullet_end_point_x, bullet_end_point_y}; break; } } +bool onSegment(vec2f p, vec2f q, vec2f r) +{ + if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) && + q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y)) + return true; + + return false; +} + +int orientation(vec2f p, vec2f q, vec2f r) +{ + int val = (q.y - p.y) * (r.x - q.x) - + (q.x - p.x) * (r.y - q.y); + + if (val == 0) return 0; // collinear + + return (val > 0)? 1: 2; // clock or counterclock wise +} + +bool lines_intersect(vec2f p1, vec2f q1, vec2f p2, vec2f q2) +{ + int o1 = orientation(p1, q1, p2); + int o2 = orientation(p1, q1, q2); + int o3 = orientation(p2, q2, p1); + int o4 = orientation(p2, q2, q1); + + // General case + if (o1 != o2 && o3 != o4) + return true; + + // Special Cases + // p1, q1 and p2 are collinear and p2 lies on segment p1q1 + if (o1 == 0 && onSegment(p1, p2, q1)) return true; + + // p1, q1 and q2 are collinear and q2 lies on segment p1q1 + if (o2 == 0 && onSegment(p1, q2, q1)) return true; + + // p2, q2 and p1 are collinear and p1 lies on segment p2q2 + if (o3 == 0 && onSegment(p2, p1, q2)) return true; + + // p2, q2 and q1 are collinear and q1 lies on segment p2q2 + if (o4 == 0 && onSegment(p2, q1, q2)) return true; + + return false; // Doesn't fall in any of the above cases +} + bool check_if_bullet_collided_with_object(bullet b, platform_window* window) { map_info info = get_map_info(window); float size = get_bullet_size_in_tile(window); @@ -128,8 +184,9 @@ bool check_if_bullet_collided_with_object(bullet b, platform_window* window) { for (int i = 0; i < max_objects; i++) { object o = objects[i]; if (!o.active) continue; - - if (b.x <= o.position.x + o.size.x && b.x + size >= o.position.x && b.y <= o.position.y + o.size.y && b.y >= o.position.y) { + if (b.position.x <= o.position.x + o.size.x && b.position.x + size >= o.position.x && + b.position.y <= o.position.y + o.size.y && b.position.y >= o.position.y && + b.position.z <= o.h + o.size.z && b.position.z >= o.h) { return true; } } @@ -137,8 +194,35 @@ bool check_if_bullet_collided_with_object(bullet b, platform_window* window) { return false; } +bool check_if_bullet_collided_with_zombie(bullet b, platform_window* window, bool kill_if_collided) { + map_info info = get_map_info(window); + float size = get_bullet_size_in_tile(window); + + for (int i = 0; i < max_zombies; i++) { + zombie o = zombies[i]; + if (!o.alive) continue; + + vec2f bstart = (vec2f){b.position.x, b.position.y}; + vec2f bend = (vec2f){b.endx, b.endy}; + + if (b.position.z <= o.position.z + o.size.z && b.position.z >= o.position.z) { + if (lines_intersect(bstart, bend, (vec2f){o.position.x, o.position.y+o.size.y}, (vec2f){o.position.x+o.size.x, o.position.y+o.size.y}) || // bottom + lines_intersect(bstart, bend, (vec2f){o.position.x, o.position.y}, (vec2f){o.position.x+o.size.x, o.position.y}) || // top + lines_intersect(bstart, bend, (vec2f){o.position.x, o.position.y}, (vec2f){o.position.x, o.position.y+o.size.y}) || // left + lines_intersect(bstart, bend, (vec2f){o.position.x+o.size.x, o.position.y}, (vec2f){o.position.x+o.size.x, o.position.y+o.size.y})) // right + { + if (kill_if_collided) { + zombies[i].alive = false; + } + return true; + } + } + } + + return false; +} + void draw_bullets(platform_window* window) { - float bulletspeed = 0.1f; float size = get_bullet_size(window); map_info info = get_map_info(window); @@ -146,14 +230,14 @@ void draw_bullets(platform_window* window) { bullet b = bullets[i]; if (!b.active) continue; - bullets[i].x += bullets[i].xacceleration*bulletspeed; - bullets[i].y += bullets[i].yacceleration*bulletspeed; - - if (is_in_bounds(window, b.x, b.y)) { - tile t = get_tile_under_coords(window, b.x, b.y); + bullets[i].alive_time += update_delta; + if (bullets[i].alive_time > 0.03f) bullets[i].active = false; + + if (is_in_bounds(window, b.position.x, b.position.y)) { + tile t = get_tile_under_coords(window, b.position.x, b.position.y); - float h = get_height_of_tile_under_coords(window, bullets[i].x, bullets[i].y); - if (h >= b.h) { + float h = get_height_of_tile_under_coords(window, bullets[i].position.x, bullets[i].position.y); + if (h >= b.position.z) { bullets[i].active = false; // hit the ground. } } @@ -161,13 +245,21 @@ void draw_bullets(platform_window* window) { bullets[i].active = false; } - if (check_if_bullet_collided_with_object(b, window)) { + //if (check_if_bullet_collided_with_object(b, window)) { + // bullets[i].active = false; + //} + if (check_if_bullet_collided_with_zombie(b, window, true)) { bullets[i].active = false; - } + } if (!b.active) continue; - float bullet_render_x = b.x*info.tile_width + (b.y*info.px_incline); - float bullet_render_y = b.y*info.tile_height - (b.h*info.px_raised_per_h); - renderer->render_rectangle(bullet_render_x - (size/2), bullet_render_y - (size/2), size, size, rgb(0,50,220)); + float bullet_render_x = b.position.x*info.tile_width + (b.position.y*info.px_incline); + float bullet_render_y = b.position.y*info.tile_height - (b.position.z*info.px_raised_per_h); + + float bullet_render_x_end = b.endx*info.tile_width + (b.endy*info.px_incline); + float bullet_render_y_end = b.endy*info.tile_height - (b.position.z*info.px_raised_per_h); + + renderer->render_line(bullet_render_x, bullet_render_y, bullet_render_x_end, bullet_render_y_end, 2, rgb(0,255,100)); + //renderer->render_rectangle(bullet_render_x - (size/2), bullet_render_y - (size/2), size, size, rgb(0,50,220)); } }
\ No newline at end of file @@ -7,7 +7,8 @@ void spawn_zombie(int x, int y) { zombies[i].alive = true; zombies[i].health = 100.0f; - zombies[i].position = (vec2f){x,y}; + zombies[i].position = (vec3f){x,y, 0}; + zombies[i].size = (vec3f){0.4, 0.4, 1}; break; } } @@ -16,35 +17,39 @@ void draw_spawners(platform_window* window) { map_info info = get_map_info(window); for (int x = 0; x < 2; x++) { - vec2 spawner_location = spawner_tiles[x]; - int render_x = (info.tile_width * spawner_location.x) + (info.px_incline * spawner_location.y); - int render_y = info.tile_height * spawner_location.y; + spawner spawner = spawner_tiles[x]; + int render_x = (info.tile_width * spawner.position.x) + (info.px_incline * spawner.position.y); + int render_y = info.tile_height * spawner.position.y; - tile tile = map_loaded[spawner_location.y][spawner_location.x]; + tile tile = map_loaded[spawner.position.y][spawner.position.x]; renderer->render_quad( tile.tl.x, tile.tl.y, tile.bl.x, tile.bl.y, tile.br.x, tile.br.y, tile.tr.x, tile.tr.y, - rgb(100, 150, 50)); + rgb(100, 150, 50)); + + spawner_tiles[x].sec_since_last_spawn += update_delta; + if (spawner_tiles[x].sec_since_last_spawn >= 1.0f) { + spawn_zombie(spawner.position.x, spawner.position.y); + spawner_tiles[x].sec_since_last_spawn = 0; + } renderer->render_line(tile.tl.x, tile.tl.y, tile.tr.x, tile.tr.y, 1, rgb(0,255,255)); // top renderer->render_line(tile.tl.x, tile.tl.y, tile.bl.x, tile.bl.y, 1, rgb(0,255,255)); // left renderer->render_line(tile.tr.x, tile.tr.y, tile.br.x, tile.br.y, 1, rgb(0,255,255)); // right renderer->render_line(tile.bl.x, tile.bl.y, tile.br.x, tile.br.y, 1, rgb(0,255,255)); // bottom } - } void draw_zombies_at_tile(platform_window* window, int x, int y) { map_info info = get_map_info(window); - float zombie_size = get_player_size(window); float speed = 0.05f; for (int i = 0; i < max_zombies; i++) { zombie o = zombies[i]; if (!o.alive) continue; - if ((int)o.position.x != x || (int)o.position.y != y) continue; + if ((int)o.position.x != x || (int)ceil(o.position.y) != y) continue; float dirx = (playerx - o.position.x); float diry = (playery - o.position.y); @@ -52,14 +57,16 @@ void draw_zombies_at_tile(platform_window* window, int x, int y) { dirx /= length; diry /= length; + float height = get_height_of_tile_under_coords(window, zombies[i].position.x, zombies[i].position.y); zombies[i].position.x += dirx*speed; zombies[i].position.y += diry*speed; + zombies[i].position.z = height; - float height = get_height_of_tile_under_coords(window, zombies[i].position.x, zombies[i].position.y); - int render_x = (info.tile_width * o.position.x) + (info.px_incline * o.position.y); - int render_y = info.tile_height * o.position.y - (height*info.px_raised_per_h); - - renderer->render_rectangle(render_x, render_y - zombie_size, zombie_size, zombie_size, rgb(40,0,255)); + box box = get_box_of_square(window, (vec3f){o.position.x, o.position.y, height}, o.size); + render_quad_with_outline(box.tl_b, box.tr_b, box.bl_b, box.br_b); + render_quad_with_outline(box.tl_u, box.tr_u, box.bl_u, box.br_u); + render_quad_with_outline(box.tl_u, box.tl_b, box.bl_u, box.bl_b); + render_quad_with_outline(box.bl_u, box.br_u, box.bl_b, box.br_b); } } |
