From af5967c92418dbaf3a4ca440e10c6567cfe78d2f Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Sun, 08 Aug 2021 00:37:01 -0400 Subject: player: Implement (renders just a dot so far) --- diff --git a/src/defs.h b/src/defs.h index 8a4ea63..501bbb2 100644 --- a/src/defs.h +++ b/src/defs.h @@ -42,6 +42,9 @@ #define MF_TITLE_FONT_S 48 /* Title font size */ #define MF_TEXT_FONT_S 16 /* Regular text font size */ +#define MF_PLAYER_SPEED 2 +#define MF_PLAYER_TURN_TIME 15 + /* Colors */ #define MF_COLOR_BACK_R 0xAF /* Background color */ #define MF_COLOR_BACK_G 0xAF @@ -71,5 +74,9 @@ #define MF_COLOR_CHKM_G 0x00 #define MF_COLOR_CHKM_B 0x00 #define MF_COLOR_CHKM_A 0xFF +#define MF_COLOR_PLYR_R 0x00 /* Player color */ +#define MF_COLOR_PLYR_G 0x00 +#define MF_COLOR_PLYR_B 0x00 +#define MF_COLOR_PLYR_A 0xFF #endif /* MF_DEFS_H_ */ diff --git a/src/game.c b/src/game.c index 6a8be75..e336c03 100644 --- a/src/game.c +++ b/src/game.c @@ -25,6 +25,7 @@ #include "dirs.h" #include "game.h" #include "maze.h" +#include "player.h" #include "tk.h" #include "util.h" @@ -65,6 +66,7 @@ int mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) { struct mf_maze *maze = NULL; + struct mf_player *player = NULL; SDL_Color maze_color; char *font_path = NULL; TTF_Font *text_font = NULL; @@ -89,6 +91,11 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) maze_color.b = MF_COLOR_MAZE_B; maze_color.a = MF_COLOR_MAZE_A; + player = mf_player_new(maze, MF_WINDOW_H / size); + if (player == NULL) { + goto err; + } + font_path = mf_strcat(mf_get_fonts_dir(), "/FifteenTwenty-Regular.ttf"); text_font = TTF_OpenFont(font_path, MF_TEXT_FONT_S); if (text_font == NULL) { @@ -131,6 +138,7 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) default: break; } + mf_player_key_event(player, &event); switch (mftk_window_event(win, &event)) { case 0: break; @@ -140,11 +148,13 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) goto err; } } + mf_player_update(player); SDL_SetRenderDrawColor(renderer, MF_COLOR_BACK_R, MF_COLOR_BACK_G, MF_COLOR_BACK_B, MF_COLOR_BACK_A); SDL_RenderClear(renderer); mf_maze_render(maze, renderer, &maze_color, MF_WINDOW_H / size); + mf_player_render(player, renderer); secs = (beg - game.beg) / 1000; if (sprintf(game.time_buf, "%02d:%02d", secs / 60, secs % 60) < 0) { @@ -175,6 +185,7 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) TTF_CloseFont(text_font); text_font = NULL; mf_maze_destroy(&maze); + mf_player_destroy(&player); return 0; quit: @@ -182,6 +193,7 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) TTF_CloseFont(text_font); text_font = NULL; mf_maze_destroy(&maze); + mf_player_destroy(&player); return 1; err: @@ -193,5 +205,6 @@ mf_game(long seed, int size, int fow, int reveal, SDL_Renderer *renderer) } mftk_window_destroy(&win); mf_maze_destroy(&maze); + mf_player_destroy(&player); return -1; } diff --git a/src/local.mk b/src/local.mk index dc06380..8a20a79 100644 --- a/src/local.mk +++ b/src/local.mk @@ -9,6 +9,8 @@ mazefight_SOURCES += \ %reldir%/maze.h \ %reldir%/menu.c \ %reldir%/menu.h \ + %reldir%/player.c \ + %reldir%/player.h \ %reldir%/tk.h \ %reldir%/util.c \ %reldir%/util.h diff --git a/src/player.c b/src/player.c new file mode 100644 index 0000000..99fe45f --- /dev/null +++ b/src/player.c @@ -0,0 +1,212 @@ +/* + * 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 . + */ + +#include +#include +#include +#include +#include "defs.h" +#include "maze.h" +#include "player.h" + +enum _mf_player_dir { + MF_PLAYER_DIR_N_, + MF_PLAYER_DIR_U_, + MF_PLAYER_DIR_D_, + MF_PLAYER_DIR_L_, + MF_PLAYER_DIR_R_ +}; + +struct mf_player { + struct mf_maze *maze; + int cell_width; + int speed; + enum _mf_player_dir cur_dir; + enum _mf_player_dir new_dir; + int turning; + int cur_x; + int cur_y; + int new_x; + int new_y; + int travel; +}; + +struct mf_player * +mf_player_new(struct mf_maze *maze, int cell_width) +{ + struct mf_player *p; + + p = calloc(1, sizeof(*p)); + if (p == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Couldn't create player: %s", + strerror(errno)); + return NULL; + } + + p->maze = maze; + p->cell_width = cell_width; + p->speed = MF_PLAYER_SPEED; + p->new_dir = MF_PLAYER_DIR_N_; + p->turning = 0; + p->cur_x = 0; + p->cur_y = 0; + p->travel = 0; + + if (mf_maze_is_wall(maze, 0, 0, 1, 0)) { + p->cur_dir = MF_PLAYER_DIR_D_; + } else { + p->cur_dir = MF_PLAYER_DIR_R_; + } + + return p; +} + +static void +_mf_player_move(struct mf_player *p, enum _mf_player_dir dir) +{ + p->new_dir = dir; +} + +void +mf_player_key_event(struct mf_player *p, SDL_Event *e) +{ + switch (e->type) { + case SDL_KEYDOWN: + switch (e->key.keysym.sym) { + case SDLK_UP: + _mf_player_move(p, MF_PLAYER_DIR_U_); + break; + case SDLK_DOWN: + _mf_player_move(p, MF_PLAYER_DIR_D_); + break; + case SDLK_LEFT: + _mf_player_move(p, MF_PLAYER_DIR_L_); + break; + case SDLK_RIGHT: + _mf_player_move(p, MF_PLAYER_DIR_R_); + break; + default: + break; + } + default: + break; + } +} + +int +mf_player_update(struct mf_player *p) +{ + int dx; + int dy; + + if (p->travel > 0) { + /* Currently moving */ + p->travel += p->speed; + if (p->travel >= p->cell_width) { + /* Reached next cell */ + p->cur_x = p->new_x; + p->cur_y = p->new_y; + if (p->cur_dir == p->new_dir) { + /* Want to continue straight */ + p->travel -= p->cell_width; + } else { + /* Want to stop or turn */ + p->travel = 0; + } + } else { + /* Farther to go */ + return 0; + } + } + if (p->new_dir != MF_PLAYER_DIR_N_ && p->cur_dir != p->new_dir) { + /* Want to turn */ + p->cur_dir = p->new_dir; + p->new_dir = MF_PLAYER_DIR_N_; + p->turning = MF_PLAYER_TURN_TIME + 1; + } + if (p->turning > 0) { + /* Turning */ + --p->turning; + } + if (p->turning == 0) { + /* Done turning */ + if (p->new_dir != MF_PLAYER_DIR_N_) { + /* Want to move */ + switch (p->new_dir) { + case MF_PLAYER_DIR_U_: dx = 0; dy = -1; break; + case MF_PLAYER_DIR_D_: dx = 0; dy = 1; break; + case MF_PLAYER_DIR_L_: dx = -1; dy = 0; break; + case MF_PLAYER_DIR_R_: dx = 1; dy = 0; break; + default: dx = 0; dy = 0; break; + } + p->new_dir = MF_PLAYER_DIR_N_; + if (mf_maze_is_wall(p->maze, p->cur_x, p->cur_y, + dx, dy)) { + return 0; + } + p->new_x = p->cur_x + dx; + p->new_y = p->cur_y + dy; + p->travel += p->speed; + } + } + + return 0; +} + +int +mf_player_render(struct mf_player *p, SDL_Renderer *renderer) +{ + int x; + int y; + + if (SDL_SetRenderDrawColor(renderer, + MF_COLOR_PLYR_R, MF_COLOR_PLYR_G, + MF_COLOR_PLYR_B, MF_COLOR_PLYR_A) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Couldn't render player: %s", + SDL_GetError()); + return -1; + } + + x = p->cur_x * p->cell_width + p->cell_width / 2; + y = p->cur_y * p->cell_width + p->cell_width / 2; + switch (p->cur_dir) { + case MF_PLAYER_DIR_U_: y -= p->travel; break; + case MF_PLAYER_DIR_D_: y += p->travel; break; + case MF_PLAYER_DIR_L_: x -= p->travel; break; + case MF_PLAYER_DIR_R_: x += p->travel; break; + default: break; + } + return SDL_RenderDrawPoint(renderer, x, y); +} + +void +mf_player_destroy(struct mf_player **p_p) +{ + struct mf_player *p; + + if (p_p == NULL || *p_p == NULL) { + return; + } + p = *p_p; + + free(p); + p = NULL; +} diff --git a/src/player.h b/src/player.h new file mode 100644 index 0000000..d27500c --- /dev/null +++ b/src/player.h @@ -0,0 +1,40 @@ +/* + * 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 . + */ + +#ifndef MF_PLAYER_H_ +#define MF_PLAYER_H_ + +struct mf_player; + +struct mf_player * +mf_player_new(struct mf_maze *maze, int cell_width); + +void +mf_player_key_event(struct mf_player *p, SDL_Event *e); + +int +mf_player_update(struct mf_player *p); + +int +mf_player_render(struct mf_player *p, SDL_Renderer *renderer); + +void +mf_player_destroy(struct mf_player **p_p); + +#endif /* MF_PLAYER_H_ */ -- cgit v0.9.1