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) --- (limited to 'src/player.c') 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; +} -- cgit v0.9.1