summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2021-08-08 00:37:01 (EDT)
committer P. J. McDermott <pj@pehjota.net>2021-08-08 00:37:01 (EDT)
commitaf5967c92418dbaf3a4ca440e10c6567cfe78d2f (patch)
treeef213115df62a7b43d493b94db183f174bb3bfd2
parent73d85fa7352179ac26ee4346d5d7148329325777 (diff)
downloadmazefight-af5967c92418dbaf3a4ca440e10c6567cfe78d2f.zip
mazefight-af5967c92418dbaf3a4ca440e10c6567cfe78d2f.tar.gz
mazefight-af5967c92418dbaf3a4ca440e10c6567cfe78d2f.tar.bz2
player: Implement (renders just a dot so far)
-rw-r--r--src/defs.h7
-rw-r--r--src/game.c13
-rw-r--r--src/local.mk2
-rw-r--r--src/player.c212
-rw-r--r--src/player.h40
5 files changed, 274 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <SDL.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+#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_ */