diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/demo.c | 2 | ||||
-rw-r--r-- | src/engine/bullet.c | 88 | ||||
-rw-r--r-- | src/engine/bullet.h | 13 | ||||
-rw-r--r-- | src/engine/draw_screen.c | 4 | ||||
-rw-r--r-- | src/engine/draw_screen.h | 14 | ||||
-rw-r--r-- | src/engine/enemy.c | 31 | ||||
-rw-r--r-- | src/engine/enemy.h | 18 | ||||
-rw-r--r-- | src/engine/entity.c | 57 | ||||
-rw-r--r-- | src/engine/entity.h | 11 | ||||
-rw-r--r-- | src/engine/level_const.c | 2 | ||||
-rw-r--r-- | src/engine/level_const.h | 1 | ||||
-rw-r--r-- | src/engine/player_controller.c | 56 | ||||
-rw-r--r-- | src/engine/player_controller.h | 2 | ||||
-rw-r--r-- | src/game_loop/game_over.h | 2 | ||||
-rw-r--r-- | src/game_loop/gameplay.c | 50 | ||||
-rw-r--r-- | src/game_loop/gameplay.h | 12 | ||||
-rw-r--r-- | src/makefile | 1 |
17 files changed, 255 insertions, 109 deletions
@@ -62,7 +62,7 @@ void hh_demo_loop(unsigned long frame) { hh_shop(&hh_game_states); break; case hh_e_state_gameplay: - hh_gameplay(hh_game, &hh_game_states); + hh_gameplay(&hh_game, &hh_game_states); break; case hh_e_state_game_over: // todo: diff --git a/src/engine/bullet.c b/src/engine/bullet.c index e6ca6df..55b20cc 100644 --- a/src/engine/bullet.c +++ b/src/engine/bullet.c @@ -1,35 +1,81 @@ #include "bullet.h" +int bullets_size=0; +static int current_bullet=0; - - -// TODO: use hh_entity as bullet struct -void hh_shoot_bullet(vec2 player, vec_cor cam_pos, hh_entity* bullet){ +hh_entity* all_bullets=NULL; +hh_entity* hh_init_bullets(int size) { + if (all_bullets != NULL) { + free(all_bullets); + } + bullets_size = size; + all_bullets = malloc(size * sizeof(hh_entity)); + hh_entity bullet = { + .speed = 1, + .is_grounded = true, + .is_hit = false, + .radius = 4, + .pos = (vec2){-16,-16}, + .vel = (vec2){0,0}, + .size = (vec2) { 13,16}, + .render = { + .frame0 = 84, + .palette = 3, + .fam = (hh_s_ppu_loc_fam_entry){ + .horizontal_flip = false, + .vertical_flip = false, + .palette_index = 7, + .tilemap_index = 84, + } + } + }; + for (int i = 0; i < size; i++) { + all_bullets[i] = bullet; + } + return all_bullets; +} +bool rising_edge(bool signal, bool* prev) { + bool edge = false; + if (signal && !(*prev)) { + edge = true; + } + *prev = signal; + return edge; +} +bool prev_signal = false; +void hh_shoot_bullet(vec2 player, hh_entity* bullet){ vec2 temp; - if(g_hh_controller_p1.button_secondary){ - if(bullet->is_grounded){ + if(rising_edge(g_hh_controller_p1.button_secondary,&prev_signal) && bullet->is_grounded){ bullet->is_grounded=false; bullet->pos = player; - } + current_bullet = (current_bullet + 1) % bullets_size; + } + +} + +void hh_update_bullet(hh_entity* bullet){ + if(hh_background_collision_bulllet(*bullet)){ + hh_bullet_death(bullet); + + // printf("x %d y %d\n",(bullet->pos.x-cam_pos.x),(bullet->pos.y-cam_pos.y)); } else{ - if(!bullet->is_grounded){ - hh_update_bullet(bullet , cam_pos); - hh_draw_bullet(*bullet); - } + bullet->pos.x += bullet->speed; } - } -void hh_update_bullet(hh_entity* bullet, vec_cor cam_pos){ - bullet->pos.x += 1; - - // update bullet sprite on ppu - bullet->render.fam.position_x = (bullet->pos.x-cam_pos.x); - bullet->render.fam.position_y = (bullet->pos.y-cam_pos.y); +void hh_multiple_bullets(vec2 player, hh_entity* bullets){ + hh_shoot_bullet(player, &bullets[current_bullet]); + for(int i=0; i < bullets_size;i++){ + if(!bullets[i].is_grounded){ + hh_update_bullet(&bullets[i]); + } + } } -void hh_draw_bullet(hh_entity bullet){ - hh_s_ppu_loc_fam_entry temp = bullet.render.fam; - hh_ppu_update_foreground(10,temp); + +void hh_bullet_death(hh_entity* bullet){ + bullet->is_grounded=true; + bullet->pos.x= -16; + bullet->pos.y= -16; } diff --git a/src/engine/bullet.h b/src/engine/bullet.h index 5f07b2e..4133032 100644 --- a/src/engine/bullet.h +++ b/src/engine/bullet.h @@ -1,11 +1,18 @@ #pragma once #include "player_controller.h" #include "engine/sprite_controller.h" +#include "types.h" #include "input.h" +hh_entity* hh_init_bullets(int size); -void hh_shoot_bullet(vec2 playerPos, vec_cor cam_pos, hh_entity*); +/** @brief checks if player hit button and sets the activate bullet*/ +void hh_shoot_bullet(vec2 playerPos, hh_entity*); -void hh_update_bullet(hh_entity* , vec_cor ); +/** @brief updates single bullet position*/ +void hh_update_bullet(hh_entity* ); -void hh_draw_bullet(hh_entity); +/** @brief calculates all the bullets positions and which to shoot */ +void hh_multiple_bullets(vec2 player, hh_entity* bullets); + +void hh_bullet_death(hh_entity* bullet); diff --git a/src/engine/draw_screen.c b/src/engine/draw_screen.c index 823c284..74b4ff2 100644 --- a/src/engine/draw_screen.c +++ b/src/engine/draw_screen.c @@ -10,7 +10,7 @@ uint8_t hh_world_to_tile(vec2 pos){ return tile; } -void hh_update_screen(vec2 view, vec2 player){ +void hh_update_screen(vec2 view){ int current_tile_y = view.y / HH_PPU_SPRITE_HEIGHT; int current_tile_x = view.x / HH_PPU_SPRITE_WIDTH; int offset_py = view.y - (offsetY / 40 * HH_PPU_SPRITE_HEIGHT); @@ -86,7 +86,7 @@ vec_cor hh_draw_screen(vec2 player) { viewport.x = CLAMP(viewport.x, 0, level.size.x * HH_PPU_SPRITE_WIDTH - HH_PPU_SCREEN_WIDTH); viewport.y = CLAMP(viewport.y, 0, level.size.y * HH_PPU_SPRITE_HEIGHT - HH_PPU_SCREEN_HEIGHT); - hh_update_screen((vec2){.y=viewport.y,.x=viewport.x},player); + hh_update_screen((vec2){.y=viewport.y,.x=viewport.x}); if (viewport.x == previousViewport.x && viewport.y == previousViewport.y){} else{ hh_ppu_update_aux((hh_s_ppu_loc_aux){ diff --git a/src/engine/draw_screen.h b/src/engine/draw_screen.h index 9130842..4829bc6 100644 --- a/src/engine/draw_screen.h +++ b/src/engine/draw_screen.h @@ -11,24 +11,22 @@ #include <stdlib.h> #include "engine/camera.h" -#define hh_max_x_size 40 -#define hh_max_y_size 30 - -/** @brief return a single tile from world binary */ +/** @brief return a single tile from world */ uint8_t hh_world_to_tile(vec2 pos); -/** @brief shift to level if viewport changed position */ +/** @brief main function for the screen. shift through the map and update the camera based on the player */ vec_cor hh_draw_screen(vec2 player); -/** @brief send data to BAM memory from binary level */ +/** @brief sets the start of a level */ void hh_setup_screen(hh_level_entity currentlevel); -/** @brief updates screen based on view and maybe player position if it needs to turn back*/ -void hh_update_screen(vec2 view, vec2 ); +/** @brief updates screen if view is at the beginning or end */ +void hh_update_screen(vec2 view); /** @brief send black screen to background memory */ void hh_clear_screen(); /** @brief clears all sprite data */ void hh_clear_sprite(); + /** @brief send data to BAM memory from binary from shop */ void hh_setup_Shop(); diff --git a/src/engine/enemy.c b/src/engine/enemy.c new file mode 100644 index 0000000..186cfa0 --- /dev/null +++ b/src/engine/enemy.c @@ -0,0 +1,31 @@ +#include "engine/enemy.h" + +void hh_update_enemy(hh_entity* enemy, vec_cor cam_pos){ + //Bjorn functions + + +} + +void hh_multiple_enemies( vec_cor cam_pos, hh_entity* enemies, int total_enemies){ + for(int i=0; i < total_enemies;i++){ + hh_update_enemy(&enemies[i] , cam_pos); + } + +} + +void hh_enemy_death_check(hh_entity* enemy){ + if(enemy->hp == 0){ + enemy->is_hit=false; + enemy->pos = (vec2){-16, -16}; + } + else{ + enemy->hp--; + } +} +void hh_solve_hitted_enemies(hh_entity* enemies, int total_enemies){ + for(int i = 0; i < total_enemies; i++){ + if(enemies[i].is_hit){ + hh_enemy_death_check(&enemies[i]); + } + } +} diff --git a/src/engine/enemy.h b/src/engine/enemy.h new file mode 100644 index 0000000..80498f5 --- /dev/null +++ b/src/engine/enemy.h @@ -0,0 +1,18 @@ +#pragma once +#include "player_controller.h" +#include "engine/sprite_controller.h" +#include "types.h" +#include "input.h" + +/** @brief updates a single enemy locations TODO: Bjorn sets functions in here*/ +void hh_update_enemy(hh_entity* , vec_cor ); + +/** @brief calculates all the given enemies positions*/ +void hh_multiple_enemies( vec_cor cam_pos, hh_entity* enemies, int total_enemies); + +/** @brief checks if the enemy has zero hp else it takes hp from the enemy */ +void hh_enemy_death_check(hh_entity* enemy); + +/** @brieg all the given enemies get controlled if there hit and than calculates the dmg */ +void hh_solve_hitted_enemies(hh_entity* enemies, int total_enemies); + diff --git a/src/engine/entity.c b/src/engine/entity.c index 7b780cf..1cb88be 100644 --- a/src/engine/entity.c +++ b/src/engine/entity.c @@ -84,6 +84,41 @@ hh_entity hh_background_collision (hh_entity temp_old_entity,hh_entity temp_new_ return temp_old_entity; } +bool hh_background_collision_bulllet (hh_entity temp_old_entity){ + + // temp_new_entity.is_grounded = false; + +// solves x collision + if (temp_old_entity.vel.x <= 0) { + if (hh_colidable(hh_world_to_tile((vec2){.x=temp_old_entity.pos.x + 0, .y=temp_old_entity.pos.y + 0})) || + hh_colidable(hh_world_to_tile((vec2){.x=temp_old_entity.pos.x + 0, .y=temp_old_entity.pos.y + (temp_old_entity.size.y-1)}))) { + return true; + } + } else { + if (hh_colidable(hh_world_to_tile((vec2){.x=temp_old_entity.pos.x + temp_old_entity.size.x, .y=temp_old_entity.pos.y + 0})) || + hh_colidable(hh_world_to_tile((vec2){.x=temp_old_entity.pos.x + temp_old_entity.size.x, .y=temp_old_entity.pos.y + (temp_old_entity.size.y-1)}))) { + return true; + } + } + + //solves y collision + if (temp_old_entity.vel.y <= 0) { + if (hh_colidable(hh_world_to_tile((vec2){.x=temp_old_entity.pos.x + 0, .y=temp_old_entity.pos.y + 0})) || + hh_colidable(hh_world_to_tile((vec2){.x=temp_old_entity.pos.x + (temp_old_entity.size.x-1), .y=temp_old_entity.pos.y + 0}))) { + return true; + } + } else { + if (hh_colidable(hh_world_to_tile((vec2){.x=temp_old_entity.pos.x + 0, .y=temp_old_entity.pos.y + (temp_old_entity.size.y-1)})) || + hh_colidable(hh_world_to_tile((vec2){.x=temp_old_entity.pos.x + (temp_old_entity.size.x-1), .y=temp_old_entity.pos.y + (temp_old_entity.size.y-1)}))) { + return true; + } + } + // temp_old_entity = temp_new_entity; + // temp_old_entity.is_grounded = temp_new_entity.is_grounded; + // temp_old_entity.pos = temp_new_entity.pos; + // temp_old_entity.vel = temp_new_entity.vel; + return false; +} hh_entity hh_enemy_collision(hh_entity temp_player, hh_entity temp_enemy){ bool collide = hh_distance_circles( temp_player.pos, temp_enemy.pos, temp_player.radius, temp_enemy.radius); @@ -177,3 +212,25 @@ void hh_hit_entity(hh_entity* object_1, int8_t* hit_timer, int8_t* direction){ } } + +void hh_check_all_collisions(hh_entity* player, hh_entity* enemies, int total_enemies, hh_entity* bullets, int total_bullets, vec_cor cam_pos){ + for(int enemy = 0; enemy < total_enemies; enemy++){ + *player = hh_enemy_collision(*player, enemies[enemy]); + enemies[enemy].is_hit=false; + } + + for(int i = 0; i < total_bullets; i++){ + if(!bullets[i].is_grounded){ + for (int enemy = 0; enemy < total_enemies; enemy++){ + + if(hh_distance_circles(bullets[i].pos,enemies[enemy].pos,bullets[i].radius,enemies[enemy].radius)){ + enemies[enemy].is_hit=true; + hh_bullet_death(&bullets[i]); + } + } + } + } + +} + + diff --git a/src/engine/entity.h b/src/engine/entity.h index b681bd8..fde9341 100644 --- a/src/engine/entity.h +++ b/src/engine/entity.h @@ -7,6 +7,9 @@ #include "ppu/types.h" #include "engine/maths.h" #include "engine/types.h" +#include "engine/animator.h" +#include "engine/sprite_controller.h" + // #include "engine/animator.h" // TODO: make a sprite update function (and required data structs?) @@ -43,8 +46,14 @@ hh_entity hh_enemy_collision(hh_entity temp_player, hh_entity temp_enemy); /// @return true if objects collids bool hh_distance_circles(vec2 object_1, vec2 object_2, int radius_1, int radius_2); -// TODO: comments on functions below +/** @brief jumps a entity. TODO: input jumping how high and no magic number*/ void hh_jump_entity(hh_entity* ); +/** @brief looks if the player is grounded and if not it sets the position down */ void hh_gravity_entity(hh_entity* ); +/** @brief if object is hit bounches in specific direction and moves the object */ void hh_hit_entity(hh_entity* object_1, int8_t* hit_timer, int8_t* direction); +/** @brief specific bullet background collisions detection */ +bool hh_background_collision_bulllet (hh_entity temp_old_entity); +/** @brief checks any entity has a hit on each othe*/ +void hh_check_all_collisions(hh_entity* player, hh_entity* enemies, int total_enemies, hh_entity* bullets, int total_bullets, vec_cor cam_pos); diff --git a/src/engine/level_const.c b/src/engine/level_const.c index 3847ad8..896d0e0 100644 --- a/src/engine/level_const.c +++ b/src/engine/level_const.c @@ -41,6 +41,8 @@ hh_g_all_levels hh_init_game_levels(){ levels.level[0].place = hh_game_level1; levels.level[1].place = hh_game_level2; + // free(hh_game_level1); + // free(hh_game_level2); return levels; } diff --git a/src/engine/level_const.h b/src/engine/level_const.h index b86ae7b..6275b72 100644 --- a/src/engine/level_const.h +++ b/src/engine/level_const.h @@ -28,4 +28,5 @@ typedef struct { }hh_g_all_levels; +/** @brief init all the levels*/ hh_g_all_levels hh_init_game_levels(); diff --git a/src/engine/player_controller.c b/src/engine/player_controller.c index 096243b..83c5966 100644 --- a/src/engine/player_controller.c +++ b/src/engine/player_controller.c @@ -7,26 +7,8 @@ #include "engine/animator.h" #include "engine/bullet.h" -void hh_player_actions(hh_entity* player, vec_cor cam_pos){ - static hh_entity bullet={ -// .hp = 4, - .speed = 6, - .is_grounded = true, - .is_hit = false, - .radius = 8, - .pos = (vec2){-16,-16}, - .vel = (vec2){0,0}, - .render = { - .frame0 = 84, - .palette = 3, - .fam = (hh_s_ppu_loc_fam_entry){ - .horizontal_flip = false, - .vertical_flip = false, - .palette_index = 7, - .tilemap_index = 84, - } - } - }; +void hh_player_actions(hh_entity* player){ + static hh_entity player_new = {0}; player_new = *player; @@ -53,40 +35,6 @@ void hh_player_actions(hh_entity* player, vec_cor cam_pos){ *player = hh_background_collision ( *player, player_new); - - hh_shoot_bullet(player->pos, cam_pos ,&bullet); - uint16_t idx = 16; - idx = hh_update_sprite(idx, player, cam_pos); - // idx = hh_update_sprite(idx, &enemy, cam_pos); - - idx =16; - - // TODO: make this a function call - // update player sprite on ppu - // player.render.fam.position_x = (player.pos.x-cam_pos.x); - // player.render.fam.position_y = (player.pos.y-cam_pos.y); - - // enemy.render.fam.position_x = (enemy.pos.x-cam_pos.x); - // enemy.render.fam.position_y = (enemy.pos.y-cam_pos.y); - - - // TODO: make this loop a function call - // for (int i = 0; i < 4; i++) - // { - // hh_s_ppu_loc_fam_entry temp = player.render.fam; - // temp.position_x = player.render.fam.position_x+(!(player.vel.x>0)?-1:1)*(i%2?8:-8); - // temp.position_y = player.render.fam.position_y+(i>1?0:-16); - // temp.tilemap_index = player.render.fam.tilemap_index + i; - // temp.horizontal_flip = !(player.vel.x>0); - // hh_ppu_update_foreground(i,temp); - - // // hh_s_ppu_loc_fam_entry temp = { - // // .position_x = player.render.fam.position_x+(!(player.vel.x>0)?-1:1)*(i%2?8:-8) - // // }; - - // } - - // hh_ppu_update_foreground(4, enemy.render.fam); } diff --git a/src/engine/player_controller.h b/src/engine/player_controller.h index 4a325e8..23749e5 100644 --- a/src/engine/player_controller.h +++ b/src/engine/player_controller.h @@ -4,4 +4,4 @@ #include "engine/entity.h" // inputs -void hh_player_actions(hh_entity* player, vec_cor cam_pos); +void hh_player_actions(hh_entity* player); diff --git a/src/game_loop/game_over.h b/src/game_loop/game_over.h index 80db667..47318df 100644 --- a/src/game_loop/game_over.h +++ b/src/game_loop/game_over.h @@ -14,5 +14,5 @@ typedef enum { hh_e_game_over_end, } hh_e_game_over; - +/** @brief game loop function game over*/ void hh_game_over(hh_e_game_state*); diff --git a/src/game_loop/gameplay.c b/src/game_loop/gameplay.c index bc6c98d..da029f3 100644 --- a/src/game_loop/gameplay.c +++ b/src/game_loop/gameplay.c @@ -1,10 +1,11 @@ #include "gameplay.h" - +#include "engine/entity.h" // player struct -void hh_gameplay(hh_g_all_levels game, hh_e_game_state* hh_game_state){ +void hh_gameplay(hh_g_all_levels* game, hh_e_game_state* hh_game_state){ static hh_e_gameplay gameplay = hh_e_setup_screen; + static hh_entity* bullets; static hh_entity player1={ .hp = 4, .speed = 6, @@ -15,7 +16,7 @@ void hh_gameplay(hh_g_all_levels game, hh_e_game_state* hh_game_state){ .size = (vec2){32,32}, .vel = (vec2){0,0}, .render = { - .frame0 = 80, + .frame0 = 3, .palette = 3, .fam = (hh_s_ppu_loc_fam_entry){ .horizontal_flip = false, @@ -32,11 +33,12 @@ void hh_gameplay(hh_g_all_levels game, hh_e_game_state* hh_game_state){ .is_grounded = false, .is_hit = false, .radius = 8, - .pos = (vec2){128,48}, + .pos = (vec2){128,24}, + .size = (vec2){16,16}, .vel = (vec2){0,0}, // .vec = (vec2){0,0}, .render = { - .frame0 = 20, + .frame0 = 1, .palette = 7, .fam = (hh_s_ppu_loc_fam_entry){ .horizontal_flip = false, @@ -46,30 +48,36 @@ void hh_gameplay(hh_g_all_levels game, hh_e_game_state* hh_game_state){ } } }; - + static int total_bullets = 5; switch (gameplay) { case hh_e_setup_screen: - hh_setup_screen(game.level[game.current_level]); + printf("%d\n",game->current_level); + bullets = hh_init_bullets(total_bullets); + hh_setup_screen(game->level[game->current_level]); gameplay = hh_e_play_level; + enemy.hp=4; break; case hh_e_play_level: // TODO: here come all the different functions for the gameplay vec_cor cam_pos;//value in tiles cam_pos = hh_draw_screen(player1.pos); - hh_player_actions(&player1,cam_pos); - - // enemy's + hh_player_actions(&player1); + hh_multiple_bullets(player1.pos,bullets); + hh_multiple_enemies(cam_pos, &enemy,1); + hh_check_all_collisions(&player1,&enemy,1,bullets,total_bullets,cam_pos); + hh_solve_hitted_enemies(&enemy,1); + hh_render_all_entities(&player1,bullets,&enemy,total_bullets,1, cam_pos); - - if(game.level[game.current_level].hh_level_completed){ + + if(game->level[game->current_level].hh_level_completed){ gameplay = hh_e_level_complete; } break; case hh_e_level_complete: - if(game.current_level < 3){ - game.current_level++; + if(game->current_level < 3){ + game->current_level+=1; gameplay = hh_e_setup_screen; } else { @@ -88,3 +96,17 @@ void hh_gameplay(hh_g_all_levels game, hh_e_game_state* hh_game_state){ } void hh_reset_levels(){} + + +void hh_render_all_entities(hh_entity* player, hh_entity* bullets, hh_entity* enemies, int bullet_size, int enemy_size, vec_cor cam_pos){ + + int index = 0; + hh_update_sprite(0 , player, cam_pos); + + for (int i = 0; i < bullet_size; i++) { + hh_update_sprite(i+5,&bullets[i],cam_pos); + } + for (int i = 0; i < enemy_size; i++) { + hh_update_sprite(i+5+bullet_size,&enemies[i],cam_pos); + } +} diff --git a/src/game_loop/gameplay.h b/src/game_loop/gameplay.h index d309e78..9d66c37 100644 --- a/src/game_loop/gameplay.h +++ b/src/game_loop/gameplay.h @@ -1,9 +1,13 @@ #pragma once #include "engine/draw_screen.h" +#include "engine/bullet.h" #include "engine/player_controller.h" #include "engine/sprite_controller.h" #include "game_loop/starting_screen.h" #include "engine/level_const.h" +#include "engine/animator.h" +#include "engine/enemy.h" + typedef enum { hh_e_setup_screen, @@ -11,7 +15,9 @@ typedef enum { hh_e_level_complete, hh_e_game_over, }hh_e_gameplay; - +/** @brief resets all the levels the first condition */ void hh_reset_levels(); -void hh_gameplay(hh_g_all_levels, hh_e_game_state*); - +/** @brief game loop function to handle the gameplay*/ +void hh_gameplay(hh_g_all_levels* game, hh_e_game_state* hh_game_state); +/** @brief renders all the entities*/ +void hh_render_all_entities(hh_entity* player, hh_entity* bullets, hh_entity* enemies, int bullet_size, int enemy_size, vec_cor cam_pos); diff --git a/src/makefile b/src/makefile index c30840d..fdd8ab5 100644 --- a/src/makefile +++ b/src/makefile @@ -41,6 +41,7 @@ LOCAL_SRCS += main.c \ engine/bullet.c \ engine/title_screen.c \ engine/level_const.c \ + engine/enemy.c \ engine/animator.c \ game_loop/shop.c \ game_loop/gameplay.c \ |