diff options
-rw-r--r-- | src/char.h | 3 | ||||
-rw-r--r-- | src/char/enemy.c | 132 | ||||
-rw-r--r-- | src/char/local.mk | 1 | ||||
-rw-r--r-- | src/defs.h | 24 | ||||
-rw-r--r-- | src/game.c | 10 |
5 files changed, 170 insertions, 0 deletions
@@ -28,6 +28,9 @@ struct mf_char; struct mf_char * mf_player_new(struct mf_maze *maze, int cell_width); +struct mf_char * +mf_enemy_new(struct mf_maze *maze, int cell_width, int maze_size); + void mf_char_get_vector(struct mf_char *c, int *x, int *y, int *travel, int *dx, int *dy); diff --git a/src/char/enemy.c b/src/char/enemy.c new file mode 100644 index 0000000..3907cf6 --- /dev/null +++ b/src/char/enemy.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2021 P. J. McDermott + * + * This file is part of Maze Fight + * + * Maze Fight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Maze Fight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Maze Fight. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <SDL.h> +#include <stdlib.h> +#include "../char.h" +#include "../defs.h" +#include "../maze.h" +#include "char.h" + +struct mf_enemy { + struct mf_char parent; +}; + +static int +_mf_enemy_update(struct mf_char *c, int stepped) +{ + enum _mf_char_dir dirs[4] = {MF_CHAR_DIR_U_, MF_CHAR_DIR_D_, + MF_CHAR_DIR_L_, MF_CHAR_DIR_R_}; + int i; + int j; + int t; + int dx; + int dy; + + if (stepped == SDL_FALSE) { + return 0; + } + + /* Shuffle directions */ + for (i = 0; i < 4; ++i) { + j = rand() / (RAND_MAX / (i+1)); + t = dirs[i]; + dirs[i] = dirs[j]; + dirs[j] = t; + } + for (i = 0; i < 3; ++i) { + if (dirs[i] == c->cur_dir) { + t = dirs[i]; + dirs[i] = dirs[3]; + dirs[3] = t; + } + } + + for (i = 0; i < 4; ++i) { + switch (dirs[i]) { + case MF_CHAR_DIR_U_: dx = 0; dy = -1; break; + case MF_CHAR_DIR_D_: dx = 0; dy = 1; break; + case MF_CHAR_DIR_L_: dx = -1; dy = 0; break; + case MF_CHAR_DIR_R_: dx = 1; dy = 0; break; + default: dx = 0; dy = 0; break; + } + if (!mf_maze_is_wall(c->maze, c->cur_x, c->cur_y, dx, dy)) { + /* Move */ + c->new_dir = dirs[i]; + } + } + + return 0; +} + +static int +_mf_enemy_render(struct mf_char *c __attribute__((__unused__)), + SDL_Renderer *renderer __attribute__((__unused__))) +{ + return 0; +} + +static void +_mf_enemy_destroy(struct mf_char *c __attribute__((__unused__))) +{ +} + +struct mf_char * +mf_enemy_new(struct mf_maze *maze, int cell_width, int maze_size) +{ + struct mf_char *c; + struct mf_enemy *p __attribute__((__unused__)); + + mf_char_init(c, p, enemy); + + c->maze = maze; + c->cell_width = cell_width; + c->speed = MF_ENEMY_SPEED; + c->new_dir = MF_CHAR_DIR_N_; + c->turning = 0; + c->turn_time = MF_ENEMY_TURN_TIME; + c->cur_x = 0; + c->cur_y = 0; + c->travel = 0; + c->padding = MF_ENEMY_P; + c->smile_y = MF_ENEMY_SMILE_Y; + c->smile_r = MF_ENEMY_SMILE_R; + c->eye_x = MF_ENEMY_EYE_X; + c->eye_y = MF_ENEMY_EYE_Y; + c->eye_r = MF_ENEMY_EYE_R; + + c->head_color.r = MF_COLOR_ELYR_R, c->head_color.g = MF_COLOR_ELYR_G; + c->head_color.b = MF_COLOR_ELYR_B, c->head_color.a = MF_COLOR_ELYR_A; + c->smil_color.r = MF_COLOR_ESML_R, c->smil_color.g = MF_COLOR_ESML_G; + c->smil_color.b = MF_COLOR_ESML_B, c->smil_color.a = MF_COLOR_ESML_A; + c->eyes_color.r = MF_COLOR_EEYE_R, c->eyes_color.g = MF_COLOR_EEYE_G; + c->eyes_color.b = MF_COLOR_EEYE_B, c->eyes_color.a = MF_COLOR_EEYE_A; + + while (c->cur_x < maze_size * MF_ENEMY_MIN_DIST || + c->cur_y < maze_size * MF_ENEMY_MIN_DIST) { + c->cur_x = rand() / (RAND_MAX / maze_size); + c->cur_y = rand() / (RAND_MAX / maze_size); + } + + c->cur_dir = MF_CHAR_DIR_N_; + _mf_enemy_update(c, SDL_TRUE); + c->cur_dir = c->new_dir; + + return c; +} diff --git a/src/char/local.mk b/src/char/local.mk index 92134a8..a93e5f1 100644 --- a/src/char/local.mk +++ b/src/char/local.mk @@ -1,4 +1,5 @@ mazefight_SOURCES += \ %reldir%/char.c \ %reldir%/char.h \ + %reldir%/enemy.c \ %reldir%/player.c @@ -42,6 +42,7 @@ #define MF_TITLE_FONT_S 48 /* Title font size */ #define MF_TEXT_FONT_S 16 /* Regular text font size */ +/* Player dimensions */ #define MF_PLAYER_SPEED 2 #define MF_PLAYER_TURN_TIME 15 #define MF_PLAYER_P 2 @@ -51,6 +52,17 @@ #define MF_PLAYER_EYE_Y 0.375 #define MF_PLAYER_EYE_R 0.125 +/* Enemy dimensions */ +#define MF_ENEMY_SPEED 2 +#define MF_ENEMY_TURN_TIME 15 +#define MF_ENEMY_P 2 +#define MF_ENEMY_SMILE_Y 0.25 +#define MF_ENEMY_SMILE_R 0.5 +#define MF_ENEMY_EYE_X 0.5 +#define MF_ENEMY_EYE_Y 0.375 +#define MF_ENEMY_EYE_R 0.125 +#define MF_ENEMY_MIN_DIST 0.5 + /* Colors */ #define MF_COLOR_BACK_R 0xAF /* Background color */ #define MF_COLOR_BACK_G 0xAF @@ -96,5 +108,17 @@ #define MF_COLOR_PEYE_G 0xDF #define MF_COLOR_PEYE_B 0xDF #define MF_COLOR_PEYE_A 0xFF +#define MF_COLOR_ELYR_R 0xAF /* Enemy color */ +#define MF_COLOR_ELYR_G 0x00 +#define MF_COLOR_ELYR_B 0x00 +#define MF_COLOR_ELYR_A 0xFF +#define MF_COLOR_ESML_R 0xDF /* Enemy smile color */ +#define MF_COLOR_ESML_G 0xDF +#define MF_COLOR_ESML_B 0xDF +#define MF_COLOR_ESML_A 0xFF +#define MF_COLOR_EEYE_R 0xDF /* Enemy eye color */ +#define MF_COLOR_EEYE_G 0xDF +#define MF_COLOR_EEYE_B 0xDF +#define MF_COLOR_EEYE_A 0xFF #endif /* MF_DEFS_H_ */ @@ -144,6 +144,7 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) { struct mf_maze *maze = NULL; struct mf_char *player = NULL; + struct mf_char *enemy = NULL; SDL_Color maze_color; char *font_path = NULL; TTF_Font *text_font = NULL; @@ -173,6 +174,10 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) if (player == NULL) { goto err; } + enemy = mf_enemy_new(maze, MF_WINDOW_H / size, size); + if (enemy == NULL) { + goto err; + } font_path = mf_strcat(mf_get_fonts_dir(), "/FifteenTwenty-Regular.ttf"); text_font = TTF_OpenFont(font_path, MF_TEXT_FONT_S); @@ -229,6 +234,7 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) } if (won == SDL_FALSE) { mf_char_update(player); + mf_char_update(enemy); mf_char_get_vector(player, &game.player_cx, &game.player_cy, &game.player_travel, &game.player_dx, &game.player_dy); @@ -246,6 +252,7 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) MF_COLOR_BACK_B, MF_COLOR_BACK_A); SDL_RenderClear(renderer); mf_char_render(player, renderer); + mf_char_render(enemy, renderer); if (fow == SDL_TRUE && _mf_game_fow(renderer, &game, maze, MF_WINDOW_H / size) < 0) { goto err; @@ -284,6 +291,7 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) text_font = NULL; mf_maze_destroy(&maze); mf_char_destroy(&player); + mf_char_destroy(&enemy); return 0; quit: @@ -292,6 +300,7 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) text_font = NULL; mf_maze_destroy(&maze); mf_char_destroy(&player); + mf_char_destroy(&enemy); return 1; err: @@ -304,5 +313,6 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) mftk_window_destroy(&win); mf_maze_destroy(&maze); mf_char_destroy(&player); + mf_char_destroy(&enemy); return -1; } |