aboutsummaryrefslogtreecommitdiff
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/bullet.c44
-rw-r--r--src/engine/bullet.h16
-rw-r--r--src/engine/draw_screen.c8
-rw-r--r--src/engine/entity.c81
-rw-r--r--src/engine/entity.h25
-rw-r--r--src/engine/player_controller.c182
-rw-r--r--src/engine/sprite_controller.h7
7 files changed, 317 insertions, 46 deletions
diff --git a/src/engine/bullet.c b/src/engine/bullet.c
new file mode 100644
index 0000000..5aa9e51
--- /dev/null
+++ b/src/engine/bullet.c
@@ -0,0 +1,44 @@
+#include "bullet.h"
+#include "engine/sprite_controller.h"
+
+
+void shootBullet(vec2 playerPos, Bullet* bullet){
+ // Set bullet's x and y coordinates to player's coordinates
+ bullet->x = playerPos.x;
+ bullet->y = playerPos.y;
+ // Set bullet's velocity to a fixed value
+ bullet->velocity = 1;
+ // Set bullet's status to active
+ bullet->isActive = true;
+}
+void updateBullet(Bullet* bullet, int deltaTime){
+ // Only update bullet if it is active
+ static int latestLocationBullet = 0;
+ if (bullet->isActive) {
+ // Move bullet based on velocity and deltaTime
+ bullet->x += bullet->velocity * deltaTime;
+ drawBullet(bullet);
+ // Check if bullet has moved 16 pixels
+ if (bullet->x - latestLocationBullet > 32) {
+ // Set bullet's status to inactive
+ bullet->isActive = false;
+ drawBullet(&(Bullet){.x = -16,.y = -16. });
+ }
+ }
+ else{
+ latestLocationBullet = bullet->x;
+ }
+}
+void drawBullet(Bullet* bullet){
+
+
+ hh_ppu_update_foreground(10, (hh_s_ppu_loc_fam_entry)
+ {
+ .position_x = bullet->x,
+ .position_y = bullet->y,
+ .horizontal_flip = false,
+ .vertical_flip = false,
+ .palette_index = 7,
+ .tilemap_index = 84, // change tilemap to the correct foreground index;
+ });
+}
diff --git a/src/engine/bullet.h b/src/engine/bullet.h
new file mode 100644
index 0000000..ad67d84
--- /dev/null
+++ b/src/engine/bullet.h
@@ -0,0 +1,16 @@
+#pragma once
+#include "player_controller.h"
+
+typedef struct {
+ int x;
+ int y;
+ int velocity;
+ int isActive;
+ int hit;
+} Bullet;
+
+
+//Bullet* createBullet(float x, float y, float velocity, float direction);
+void shootBullet(vec2 playerPos, Bullet* bullet);
+void updateBullet(Bullet* bullet, int deltaTime);
+void drawBullet(Bullet* bullet);
diff --git a/src/engine/draw_screen.c b/src/engine/draw_screen.c
index 58553bd..0c31bf6 100644
--- a/src/engine/draw_screen.c
+++ b/src/engine/draw_screen.c
@@ -3,7 +3,7 @@
uint8_t hh_world_to_tile(vec2 pos){
//TODO: remove magic file name here
- FILE* level = fopen("static/tiles.bin", "rb"); /* open binary file */
+ FILE* level = fopen("static/level1_test.bin", "rb"); /* open binary file */
if (!level) { /* check if file opened successfully */
fprintf(stderr, "Error: Failed to open file.\n");
return 0;
@@ -61,7 +61,6 @@ void hh_setup_screen(){
}
free(tile);
}
-
void hh_clear_screen(){
// (HH_PPU_SCREEN_HEIGHT*HH_PPU_SCREEN_WIDTH)/(HH_PPU_SPRITE_HEIGHT*HH_PPU_SPRITE_WIDTH)
for (int i = 0; i < HH_PPU_BG_CANVAS_TILES_H*HH_PPU_BG_CANVAS_TILES_V; i++) {
@@ -82,6 +81,9 @@ void hh_clear_screen(){
void hh_clear_sprite(){
for (int i = 0; i < HH_PPU_FG_SPRITE_COUNT; i++) {
- hh_ppu_update_sprite(i,(hh_s_ppu_loc_sprite){0});
+ hh_ppu_update_foreground(i,(hh_s_ppu_loc_fam_entry){
+ .position_x = -16,
+ .position_y = -16,
+ });
}
}
diff --git a/src/engine/entity.c b/src/engine/entity.c
index 153e7e1..535759d 100644
--- a/src/engine/entity.c
+++ b/src/engine/entity.c
@@ -43,4 +43,85 @@ void hh_solve_collision(vec2 pos_environment, hh_entity* entity){
// entity->vel.x = 0;
// }
}
+hh_entity hh_background_collision (hh_entity temp_old_entity,hh_entity temp_new_entity){
+ temp_old_entity.is_grounded = false;
+
+// solves x collision
+ if (temp_old_entity.vel.x <= 0) {
+ if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_old_entity.pos.y + 0})) ||
+ hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_old_entity.pos.y + 15}))) {
+ temp_new_entity.pos.x = (temp_new_entity.pos.x & ~15) + 16,
+ temp_new_entity.vel.x = 0;
+ }
+ } else {
+ if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 16, .y=temp_old_entity.pos.y + 0})) ||
+ hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 16, .y=temp_old_entity.pos.y + 15}))) {
+ temp_new_entity.pos.x = temp_new_entity.pos.x & ~15, // <-- magic comma, NOT TOUCHY
+ temp_new_entity.vel.x = 0;
+ }
+ }
+
+ //solves y collision
+ if (temp_old_entity.vel.y <= 0) {
+ if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_new_entity.pos.y + 0})) ||
+ hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 15, .y=temp_new_entity.pos.y + 0}))) {
+ temp_new_entity.pos.y = (temp_new_entity.pos.y & ~15) + 16,
+ temp_new_entity.vel.y = 0;
+ }
+ } else {
+ if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_new_entity.pos.y + 15})) ||
+ hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 15, .y=temp_new_entity.pos.y + 15}))) {
+ temp_new_entity.pos.y = temp_new_entity.pos.y & ~15,
+ temp_new_entity.vel.y = 0;
+ temp_old_entity.is_grounded = true;
+ }
+ }
+ temp_old_entity.pos = temp_new_entity.pos;
+ temp_old_entity.vel = temp_new_entity.vel;
+ return temp_old_entity;
+}
+
+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);
+
+ if (collide == true && temp_player.is_hit == false)
+ {
+ temp_player.is_hit = true;
+ //angle = atan2( tempEntity.pos_y - tempPlayer.pos_y, tempEntity.pos_x - tempPlayer.pos_x);
+ if(temp_player.pos.x <= temp_enemy.pos.x) //player left of enemy -- creates flinch movement L or R
+ {
+ // printf("BONK-left!/n");
+ temp_player.vel.y = -5;
+ temp_player.vel.x = -8;
+ } else {
+ // printf("BONK-right!/n");
+ temp_player.vel.y = -5;
+ temp_player.vel.x = 8;
+ }
+ // ghost mode / invulnerable or other things on hit
+ // temp_player.hp--;
+
+ } else {
+ temp_player.is_hit = false;
+
+ }
+
+
+return temp_player;
+}
+
+
+bool hh_distance_circles (vec2 object_1, vec2 object_2, int radius_1, int radius_2){
+ int a_squared = (object_1.x - object_2.x) * (object_1.x - object_2.x);
+ int b_squared = (object_1.y - object_2.y) * (object_1.y - object_2.y);
+ int c_squared = a_squared + b_squared;
+ int radius = ( radius_1 + radius_2) * ( radius_1 + radius_2 );
+
+ if( c_squared <= radius ){
+ return true;
+ } else {
+ return false;
+ }
+}
diff --git a/src/engine/entity.h b/src/engine/entity.h
index f45dae2..cad6ba4 100644
--- a/src/engine/entity.h
+++ b/src/engine/entity.h
@@ -2,6 +2,7 @@
#include <stdint.h>
#include <stdbool.h>
+#include <stdio.h>
#include "ppu/types.h"
@@ -32,6 +33,8 @@ typedef struct {
typedef struct {
vec2 pos, vel, vec;
bool is_grounded;
+ bool is_hit;
+ uint8_t radius;
int8_t hp;
int8_t speed;
hh_s_rendering render;
@@ -55,3 +58,25 @@ bool hh_collision(vec2 pos1, vec2 pos2);
/// @param entity position
/// @return solved new entity position
void hh_solve_collision(vec2 pos_environment, hh_entity* entity);
+
+/// @brief solve collision of entity with background tiles
+/// @param temp_old_entity old data of entity
+/// @param temp_new_entity new data of entity where it wants to go to
+/// @return updated new entity where it actually can go to
+hh_entity hh_background_collision (hh_entity temp_old_entity, hh_entity temp_new_entity);
+
+/// @brief solve collision of player with enemy
+/// @param temp_player data of player
+/// @param temp_enemy data of enemy
+/// @return updated player with new stats if hitted with enemy
+hh_entity hh_enemy_collision(hh_entity temp_player, hh_entity temp_enemy);
+
+/// @brief calculate if circles (entity) hit each other
+/// @param object_1 position of first object (entity)
+/// @param object_2 position of second object (entity)
+/// @param radius_1 radius of first object (entity)
+/// @param radius_2 radius of second object (entity)
+/// @return true if objects collids
+bool hh_distance_circles (vec2 object_1, vec2 object_2, int radius_1, int radius_2);
+
+
diff --git a/src/engine/player_controller.c b/src/engine/player_controller.c
index 22f6eb6..647b00c 100644
--- a/src/engine/player_controller.c
+++ b/src/engine/player_controller.c
@@ -6,29 +6,143 @@
#include "input.h"
+#include "engine/bullet.h"
void hh_player_actions() {
+ static Bullet bullet ={
+ .isActive=false,
+ };
static hh_entity player={
.hp = 4,
.speed = 6,
.is_grounded = false,
+ .is_hit = false,
+ .radius = 8,
.pos = (vec2){32,32},
.vel = (vec2){0,0},
.vec = (vec2){0,0},
.render = {
+ .frame0 = 80,
+ .palette = 3,
+ .fam = (hh_s_ppu_loc_fam_entry){
+ .horizontal_flip = false,
+ .vertical_flip = false,
+ .palette_index = 2,
+ .tilemap_index = 60,
+ }
+ }
+ }, player_new = {0};
+
+
+ static hh_entity enemy={
+ .hp = 4,
+ .speed = 6,
+ .is_grounded = false,
+ .is_hit = false,
+ .radius = 8,
+ .pos = (vec2){128,48},
+ .vel = (vec2){0,0},
+ .vec = (vec2){0,0},
+ .render = {
.frame0 = 20,
.palette = 7,
.fam = (hh_s_ppu_loc_fam_entry){
.horizontal_flip = false,
.vertical_flip = false,
.palette_index = 7,
- .tilemap_index = 2,
+ .tilemap_index = 1,
}
}
- }, player_new = {0};
-
+ };
+ player_new = player;
// hh_input_read();
+ static uint8_t hit = 0;
+ int8_t hit_timer = 0;
+ int8_t direction_x = (-1 * g_hh_controller_p1.dpad_left) + (1 * g_hh_controller_p1.dpad_right);
+ int8_t direction_y = (-1 * g_hh_controller_p1.dpad_up) + (1 * g_hh_controller_p1.dpad_down);
+
+ if(player.is_hit == true){
+ hit_timer = 9;
+ player.is_hit = false;
+ }
+ if(hit_timer > -10){
+ hit_timer--;
+ }
+
+ if(hit_timer <= 0){
+ if(direction_x != 0){
+ if(player.vel.x > -1 * player.speed && player.vel.x < player.speed) {
+ player.vel.x = player.vel.x + direction_x;
+ } else {
+ if (player.vel.x > 0) {
+ player.vel.x--;
+ } else if(player.vel.x < 0) {
+ player.vel.x++;
+ }
+ }
+ } else {
+ if (player.vel.x > 0) {
+ player.vel.x--;
+ } else if(player.vel.x < 0) {
+ player.vel.x++;
+ }
+ }
+
+ /* // movement Y (w-s) disable gravity to use this
+ if(direction_y != 0){
+ if(player.vel.y > -4 && player.vel.y < 4 ) {
+ player.vel.y = player.vel.y + direction_y;
+ }
+ } else {
+ if (player.vel.y > 0) {
+ player.vel.y--;
+ } else if(player.vel.y < 0) {
+ player.vel.y++;
+ }
+ }
+
+ */
+ } else {
+ if (player.vel.x > 0) {
+ player.vel.x--;
+ } else if(player.vel.x < 0) {
+ player.vel.x++;
+ }
+ player.vel.y++;
+ }
+
+
+ if (g_hh_controller_p1.button_primary && player.is_grounded == true) {//JUMP
+ player.vel.y = -10;
+ player.is_grounded = false;
+ } else if (player.vel.y < 6){
+ player.vel.y += 1; //gravity
+ }
+
+ if(g_hh_controller_p1.button_secondary==true){
+ shootBullet(player.pos,&bullet);
+ }
+ updateBullet(&bullet,5);
+
+
+
+/*
player.vel = (vec2){.x = (-1 * g_hh_controller_p1.dpad_left) + (1 * g_hh_controller_p1.dpad_right),
.y = (-1 * g_hh_controller_p1.dpad_up) + (1 * g_hh_controller_p1.dpad_down) };
+
+ player_new.vel = (vec2){
+ .x = player.vel.x,
+ .y = player.vel.y,
+ };
+*/
+
+ player_new.vel = (vec2){
+ .x = player.vel.x,
+ .y = player.vel.y,
+ };
+
+ player_new = hh_enemy_collision(player, enemy);
+
+
// const int8_t maa = 3;
// const int8_t mbb = -3;
// if (g_hh_controller_p1.dpad_up)
@@ -55,8 +169,8 @@ void hh_player_actions() {
// player.vel.x = CLAMP(player.vel.x,-32,32);
player_new.pos = (vec2){
- .x = player.pos.x + player.vel.x,
- .y = player.pos.y + player.vel.y,
+ .x = player.pos.x + player_new.vel.x,
+ .y = player.pos.y + player_new.vel.y,
};
@@ -97,40 +211,9 @@ void hh_player_actions() {
// }
// }
- player_new.is_grounded = false;
-
- // solves x collision
- if (player.vel.x <= 0) {
- if (hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player.pos.y + 0})) ||
- hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player.pos.y + 15}))) {
- player_new.pos.x = (player_new.pos.x & ~15) + 16,
- player_new.vel.x = 0;
- }
- } else {
- if (hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 16, .y=player.pos.y + 0})) ||
- hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 16, .y=player.pos.y + 15}))) {
- player_new.pos.x = player_new.pos.x & ~15, // <-- magic comma, NOT TOUCHY
- player_new.vel.x = 0;
- }
- }
-
- //solves y collision
- if (player.vel.y <= 0) {
- if (hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player_new.pos.y + 0})) ||
- hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player_new.pos.y + 15}))) {
- player_new.pos.y = (player_new.pos.y & ~15) + 16,
- player_new.vel.y = 0;
- }
- } else {
- if (hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player_new.pos.y + 16})) ||
- hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 16, .y=player_new.pos.y + 15}))) {
- player_new.pos.y = player_new.pos.y & ~15,
- player_new.vel.y = 0;
- player_new.is_grounded = true;
- }
- }
-
- player = player_new;
+ player = hh_background_collision ( player, player_new);
+
+ //player = player_new;
vec_cor cam_pos;//value in tiles
// cam_pos = (vec2){0,0};
@@ -141,10 +224,29 @@ void hh_player_actions() {
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);
player.render.fam.tilemap_index = 2;//TODO: these two lines should be redundant
player.render.fam.palette_index = 7;
- hh_ppu_update_foreground(0, player.render.fam);
+ // hh_ppu_update_foreground(0, player.render.fam);
+
+ 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.frame0 + i;
+ temp.palette_index = player.render.palette;
+ temp.horizontal_flip = !(player.vel.x>0);
+ hh_ppu_update_foreground(i,temp);
+ }
+
+
+
+ hh_ppu_update_foreground(4, enemy.render.fam);
}
+
+
diff --git a/src/engine/sprite_controller.h b/src/engine/sprite_controller.h
index c6ebc93..fc6d3d3 100644
--- a/src/engine/sprite_controller.h
+++ b/src/engine/sprite_controller.h
@@ -12,7 +12,7 @@
//TODO: pack data inside of sprite_palette LUT
//HH_PPU_PALETTE_COUNT
#define HH_SPRITE_COUNT 80
-#define HH_PAL_IDX_SKY 0
+#define HH_PAL_IDX_SKY 512
#define HH_PAL_IDX_BRICK 1
const static uint8_t hh_g_sprite_palette[HH_SPRITE_COUNT] = {
//TODO: make a buffer of 16 no-collider sprites (instead of the current 1)
@@ -31,6 +31,7 @@ const static uint8_t hh_g_sprite_palette[HH_SPRITE_COUNT] = {
6,6,6,6,/*6,6,6,6,6,6, //title_screen large letters
6,6,6,6,*/
//other palettes here:
+ // [HH_PAL_IDX_SKY] = 0,
};
@@ -67,9 +68,9 @@ const static hh_ppu_loc_palette_table_t hh_g_palette = {
{0x1,0x1,0x1},
{0x4,0x2,0x5},
{0x7,0x3,0x7},
- {0x1,0x1,0x3},
{0xe,0xe,0xe},
- {0x0,0x0,0x0},
+ {0xe,0xe,0xe}, //elemental
+ {0x0,0x0,0x0},
{0x0,0x0,0x0}},
{
{0x0,0x0,0x0},