diff --git a/assets/img/enemyrun.png b/assets/img/enemyrun.png new file mode 100644 index 0000000..ff5767e Binary files /dev/null and b/assets/img/enemyrun.png differ diff --git a/build/makefile b/build/makefile index 72de081..d8fed24 100644 --- a/build/makefile +++ b/build/makefile @@ -1,12 +1,14 @@ CC = gcc CFLAGS = -Wall -I../include LDFLAGS = -lSDL -lSDL_image -lSDL_mixer -lSDL_ttf -OBJS = main.o menu.o music.o text.o stars.o settings.o start.o +OBJS = main.o menu.o music.o text.o stars.o settings.o start.o enemy.o + game: $(OBJS) $(CC) $(OBJS) $(LDFLAGS) -o game + %.o: ../src/%.c $(CC) $(CFLAGS) -c $< .PHONY: clean clean: - rm -f $(OBJS) game \ No newline at end of file + rm -f $(OBJS) game diff --git a/doc/enemxy.png b/doc/enemxy.png new file mode 100644 index 0000000..1984f0f Binary files /dev/null and b/doc/enemxy.png differ diff --git a/include/constants.h b/include/constants.h new file mode 100644 index 0000000..26dbc4c --- /dev/null +++ b/include/constants.h @@ -0,0 +1,17 @@ +#ifndef CONSTANTS_H +#define CONSTANTS_H + +//*screen size +#define SCREEN_W 1280 +#define SCREEN_H 720 + +//*stars stuff +#define STARS_COUNT 100 // number of stars //? need locking +#define STARS_LAYERS 4 // number of stars variations +#define DELTA_TIME 16 // 1000ms / 60fps = 16.6666 + +//*main menu buttons stuff +#define BUTTON_SPACING 14 // spacing between the buttons (px) //! LOCKED +#define INTIAL_BUTTON_Y 325 // initial button y position (px) //!LOCKED + +#endif \ No newline at end of file diff --git a/include/enemy.h b/include/enemy.h new file mode 100644 index 0000000..4928bc4 --- /dev/null +++ b/include/enemy.h @@ -0,0 +1,30 @@ +#ifndef ENEMY_H +#define ENEMY_H + +typedef struct +{ + SDL_Rect img_pos; // position of the sprite on the screen + SDL_Rect img_size; // size of the sprite + SDL_Surface *img; // pointer to the sprite image + int direction; // 0 for idle, 1 for right , 2 for left + float speed; // steps per frame + int max_steps; // maximum number of steps before changing direction + int idle_time; // time when the enemy started idling + int x; // position of the enemy in the grid (screen coordinates) + int y; // position of the enemy in the grid (screen coordinates) +} enemy; + +void initEnemy(enemy *e); +void drawEnemy(SDL_Surface *screen, enemy e); +void animateEnemy(enemy *e, int direction); +void moveEnemy(enemy *e); //! added new parameter dont forget +int collisionBB(SDL_Rect player, SDL_Rect enemy); + +//**************************************************** + +void initEnemytest(enemy *e); +void drawEnemytest(SDL_Surface *screen, enemy e); +void animateEnemytest(enemy *e, int direction); +void moveEnemytest(enemy *e); + +#endif \ No newline at end of file diff --git a/include/menu.h b/include/menu.h index e33e43a..bd2bab7 100644 --- a/include/menu.h +++ b/include/menu.h @@ -1,9 +1,6 @@ #ifndef MENU_H #define MENU_H - -#define SCREEN_W 1280 -#define SCREEN_H 720 // screen height and width typedef struct { @@ -46,7 +43,6 @@ void imageDrawClicked_playbutton(SDL_Surface *screen, image img); void imageDrawClicked_settingsbutton(SDL_Surface *screen, image img); void imageDrawClicked_quitbutton(SDL_Surface *screen, image img); - void imageDrawHovered_playbutton(SDL_Surface *screen, image img); void imageDrawHovered_settingsbutton(SDL_Surface *screen, image img); void imageDrawHovered_quitbutton(SDL_Surface *screen, image img); @@ -55,5 +51,4 @@ void imageDrawHovered_quitbutton(SDL_Surface *screen, image img); //**UNIVERSAL FUNCTION**// // free buttons - #endif diff --git a/src/enemy.c b/src/enemy.c new file mode 100644 index 0000000..e13013e --- /dev/null +++ b/src/enemy.c @@ -0,0 +1,224 @@ +#include +#include +#include "constants.h" +#include "enemy.h" + +void initEnemy(enemy *e) +{ + e->img = IMG_Load("../assets/img/enemyrun.png"); + if (e->img == NULL) + { + printf("Error loading enemy image: %s\n", SDL_GetError()); + } + e->direction = 1; + e->speed = 1; + e->max_steps = 100; + e->idle_time = 2000; + e->x = (SCREEN_W / 2 - (e->img->w / 6) - 96 / 2) + 100; // screen width - (width of img / sprite size) - (width of sprite / 2) + e->y = (SCREEN_H / 2 - (e->img->h / 3) - 96 / 2) + 100; // screen height - (height of img / sprite size) - (height of sprite / 2) + + e->img_size.x = 0; + e->img_size.y = 0; + e->img_size.w = (e->img->w) / 6; // (width of img / sprite frames) :576/6 =96px + e->img_size.h = (e->img->h) / 3; // (height of img / sprite frames) := 288/3= 96px + e->img_pos.x = e->x; + e->img_pos.y = e->y; +} + +void drawEnemy(SDL_Surface *screen, enemy e) +{ + SDL_BlitSurface(e.img, &(e.img_size), screen, &(e.img_pos)); +} + +void animateEnemy(enemy *e, int direction) //! added new parameter dont forget +{ + static int frame = 0; // static variable to track current frame + int row = 0; + if (direction == 1) + { + row = 0; + } + else if (direction == 2) + { + row = 1; + } + else if (direction == 0) + { + row = 2; + } + e->img_size.x = frame * e->img_size.w; // set x position based on frame + e->img_size.y = row * e->img_size.h; // set y position based on direction + + Uint32 current_time = SDL_GetTicks(); + static Uint32 last_time = 0; + Uint32 delta_time = current_time - last_time; + if (delta_time >= 100) + { // add a delay of 100 milliseconds between frames + frame++; // increment frame counter + if (frame >= 6) + { // if we've reached the end of the sprite sheet, wrap around + frame = 0; + } + last_time = current_time; + } +} + +void moveEnemy(enemy *e) +{ + if (e->direction == 1) + { // move right + animateEnemy(e, 1); + e->img_pos.x += e->speed; + if (e->img_pos.x >= e->x + e->max_steps) + { + e->img_pos.x = e->x + e->max_steps; + e->direction = 0; // change direction to idle + e->idle_time = SDL_GetTicks(); // start idle time + } + } + else if (e->direction == 2) + { // move left + animateEnemy(e, 2); + e->img_pos.x -= e->speed; + if (e->img_pos.x <= e->x) + { + e->img_pos.x = e->x; + e->direction = 0; // change direction to idle + e->idle_time = SDL_GetTicks(); // start idle time + } + } + else if (e->direction == 0) + { // idle + animateEnemy(e, 0); + Uint32 current_time = SDL_GetTicks(); + if (current_time - e->idle_time >= 2000) + { // check if idle time is over + if (e->img_pos.x == e->x) + { + e->direction = 1; // change direction to right + } + else if (e->img_pos.x == e->x + e->max_steps) + { + e->direction = 2; // change direction to left + } + } + } +} + +int collisionBB(SDL_Rect player, SDL_Rect enemy) +{ + int collision = 0; + if ((player.x + player.w < enemy.x) || (player.x > enemy.x + enemy.w) || (player.y + player.h < enemy.y) || (player.y > enemy.y + enemy.h)) + { + collision = 0; // no collision + } + else + { + collision = 1; // collision + } + return collision; +} + +//******************************* + +void initEnemytest(enemy *e) +{ + e->img = IMG_Load("../assets/img/enemyrun.png"); + if (e->img == NULL) + { + printf("Error loading enemy image: %s\n", SDL_GetError()); + } + e->direction = 1; + e->speed = 1; + e->max_steps = 100; + e->idle_time = 2000; + e->x = (SCREEN_W / 2 - (e->img->w / 6) - 96 / 2) + 200; // screen width - (width of img / sprite size) - (width of sprite / 2) + e->y = (SCREEN_H / 2 - (e->img->h / 3) - 96 / 2) + 100; // screen height - (height of img / sprite size) - (height of sprite / 2) + + e->img_size.x = 0; + e->img_size.y = 0; + e->img_size.w = (e->img->w) / 6; // (width of img / sprite frames) :576/6 =96px + e->img_size.h = (e->img->h) / 3; // (height of img / sprite frames) := 288/3= 96px + e->img_pos.x = e->x; + e->img_pos.y = e->y; +} + +void drawEnemytest(SDL_Surface *screen, enemy e) +{ + SDL_BlitSurface(e.img, &(e.img_size), screen, &(e.img_pos)); +} + +void animateEnemytest(enemy *e, int direction) //! added new parameter dont forget +{ + static int frame = 0; // static variable to track current frame + int row = 0; + if (direction == 1) + { + row = 0; + } + else if (direction == 2) + { + row = 1; + } + else if (direction == 0) + { + row = 2; + } + e->img_size.x = frame * e->img_size.w; // set x position based on frame + e->img_size.y = row * e->img_size.h; // set y position based on direction + + Uint32 current_time = SDL_GetTicks(); + static Uint32 last_time = 0; + Uint32 delta_time = current_time - last_time; + if (delta_time >= 100) + { // add a delay of 100 milliseconds between frames + frame++; // increment frame counter + if (frame >= 6) + { // if we've reached the end of the sprite sheet, wrap around + frame = 0; + } + last_time = current_time; + } +} + +void moveEnemytest(enemy *e) +{ + if (e->direction == 2) + { // move right + animateEnemy(e, 1); + e->img_pos.x += e->speed; + if (e->img_pos.x >= e->x + e->max_steps) + { + e->img_pos.x = e->x + e->max_steps; + e->direction = 0; // change direction to idle + e->idle_time = SDL_GetTicks(); // start idle time + } + } + else if (e->direction == 1) + { // move left + animateEnemy(e, 2); + e->img_pos.x -= e->speed; + if (e->img_pos.x <= e->x) + { + e->img_pos.x = e->x; + e->direction = 0; // change direction to idle + e->idle_time = SDL_GetTicks(); // start idle time + } + } + else if (e->direction == 0) + { // idle + animateEnemy(e, 0); + Uint32 current_time = SDL_GetTicks(); + if (current_time - e->idle_time >= 2000) + { // check if idle time is over + if (e->img_pos.x == e->x) + { + e->direction = 1; // change direction to right + } + else if (e->img_pos.x == e->x + e->max_steps) + { + e->direction = 2; // change direction to left + } + } + } +} diff --git a/src/main.c b/src/main.c index 7921c55..9cddc51 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include #include #include +#include "constants.h" // for constants #include #include //for loading images @@ -10,21 +11,15 @@ #include //for loading sounds // including the headers - #include "../include/menu.h" //menu header #include "../include/music.h" //music header #include "../include/text.h" //text header #include "../include/stars.h" //stars header #include "../include/settings.h" //settings header +#include "../include/enemy.h" // screen SDL_Surface *screen; -#define SCREEN_W 1280 -#define SCREEN_H 720 // screen height and width - -#define STARS_COUNT 100 // number of stars //! need locking -#define STARS_LAYERS 4 // number of stars variations -#define DELTA_TIME 16 // 1000ms / 60fps = 16.6666 //* regular -> hovered -> clicked // images (_C for clicked) (_H for hovered) @@ -65,6 +60,10 @@ Mix_Chunk *clickFX; // text text author; +// characters +enemy enemy1; +enemy enemy2; + // logic SDL_Event event; int loop = 1; // game loop @@ -141,6 +140,10 @@ int main() // loading text textLoad(&author); + // loading enemy + initEnemy(&enemy1); + initEnemytest(&enemy2); + //* loading settings menu images //? maybe add background instead of solid color for settings menu @@ -440,6 +443,17 @@ int main() imageDraw_lvl1(screen, lvl1); imageDraw_backbutton(screen, backButton); //! used twice, but it's ok for now (universal fucntion) + drawEnemy(screen, enemy1); + moveEnemy(&enemy1); //* moveEnemy will call animateEnemy + //************ + drawEnemytest(screen, enemy2); + moveEnemytest(&enemy2); //* moveEnemy will call animateEnemy + //************ + if (collisionBB(enemy1.img_pos, enemy2.img_pos) == 1) + { + printf(" collision detected \t"); + } + while (SDL_PollEvent(&event)) { switch (event.type) diff --git a/src/menu.c b/src/menu.c index 1e034d1..e15ec57 100644 --- a/src/menu.c +++ b/src/menu.c @@ -1,9 +1,7 @@ #include #include #include "../include/menu.h" - -spacing = 14; // spacing between the buttons (px) -initial_y = 325; // intitial y pos //!LOCKED +#include "constants.h" // load the images void imageLoad_background(image *img) @@ -54,7 +52,7 @@ void imageLoad_playbutton(image *img) img->img_size.w = img->img->w; img->img_size.h = img->img->h; img->img_pos.x = ((SCREEN_W / 2) - (img->img_size.w / 2)); - img->img_pos.y = initial_y; + img->img_pos.y = INTIAL_BUTTON_Y; } void imageLoad_settingsbutton(image *img) @@ -72,7 +70,7 @@ void imageLoad_settingsbutton(image *img) img->img_size.w = img->img->w; img->img_size.h = img->img->h; img->img_pos.x = ((SCREEN_W / 2) - (img->img_size.w / 2)); - img->img_pos.y = initial_y + img->img_size.h + spacing; + img->img_pos.y = INTIAL_BUTTON_Y + img->img_size.h + BUTTON_SPACING; } void imageLoad_quitbutton(image *img) @@ -89,7 +87,7 @@ void imageLoad_quitbutton(image *img) img->img_size.w = img->img->w; img->img_size.h = img->img->h; img->img_pos.x = ((SCREEN_W / 2) - (img->img_size.w / 2)); - img->img_pos.y = initial_y + img->img_size.h * 2 + spacing * 2; + img->img_pos.y = INTIAL_BUTTON_Y + img->img_size.h * 2 + BUTTON_SPACING * 2; } // load the Clicked images @@ -107,7 +105,7 @@ void imageLoadClicked_playbutton(image *img) img->img_size.w = img->img->w; img->img_size.h = img->img->h; img->img_pos.x = ((SCREEN_W / 2) - (img->img_size.w / 2)); - img->img_pos.y = initial_y; + img->img_pos.y = INTIAL_BUTTON_Y; } void imageLoadClicked_settingsbutton(image *img) @@ -124,7 +122,7 @@ void imageLoadClicked_settingsbutton(image *img) img->img_size.w = img->img->w; img->img_size.h = img->img->h; img->img_pos.x = ((SCREEN_W / 2) - (img->img_size.w / 2)); - img->img_pos.y = initial_y + img->img_size.h + spacing; + img->img_pos.y = INTIAL_BUTTON_Y + img->img_size.h + BUTTON_SPACING; } void imageLoadClicked_quitbutton(image *img) @@ -141,7 +139,7 @@ void imageLoadClicked_quitbutton(image *img) img->img_size.w = img->img->w; img->img_size.h = img->img->h; img->img_pos.x = ((SCREEN_W / 2) - (img->img_size.w / 2)); - img->img_pos.y = initial_y + img->img_size.h * 2 + spacing * 2; + img->img_pos.y = INTIAL_BUTTON_Y + img->img_size.h * 2 + BUTTON_SPACING * 2; } // load the hovered images @@ -159,7 +157,7 @@ void imageLoadHovered_playbutton(image *img) img->img_size.w = img->img->w; img->img_size.h = img->img->h; img->img_pos.x = ((SCREEN_W / 2) - (img->img_size.w / 2)); - img->img_pos.y = initial_y; + img->img_pos.y = INTIAL_BUTTON_Y; } void imageLoadHovered_settingsbutton(image *img) @@ -176,7 +174,7 @@ void imageLoadHovered_settingsbutton(image *img) img->img_size.w = img->img->w; img->img_size.h = img->img->h; img->img_pos.x = ((SCREEN_W / 2) - (img->img_size.w / 2)); - img->img_pos.y = initial_y + img->img_size.h + spacing; + img->img_pos.y = INTIAL_BUTTON_Y + img->img_size.h + BUTTON_SPACING; } void imageLoadHovered_quitbutton(image *img) @@ -193,7 +191,7 @@ void imageLoadHovered_quitbutton(image *img) img->img_size.w = img->img->w; img->img_size.h = img->img->h; img->img_pos.x = ((SCREEN_W / 2) - (img->img_size.w / 2)); - img->img_pos.y = initial_y + img->img_size.h * 2 + spacing * 2; + img->img_pos.y = INTIAL_BUTTON_Y + img->img_size.h * 2 + BUTTON_SPACING * 2; } // draw the images