Remade player input and movement, more or less replay-ready now. Also made the direction vector normalized.

This commit is contained in:
Andrew "Akari" Alexeyew 2012-07-14 17:37:52 +03:00
parent c443aaf446
commit 8e0f390386
9 changed files with 198 additions and 61 deletions

View file

@ -19,6 +19,7 @@ ADD_FLEX_BISON_DEPENDENCY(cfgscanner cfgparser)
set(SRCs
main.c
stage.c
replay.c
global.c
player.c
projectile.c

View file

@ -41,4 +41,8 @@ enum {
void parse_config(char *filename);
void config_preset();
#define CONFIG_KEY_FIRST KEY_UP
#define CONFIG_KEY_LAST KEY_SCREENSHOT
int config_sym2key(int sym);
#endif

View file

@ -141,3 +141,10 @@ void config_preset() {
tconfig.intval[NO_STAGEBG] = 0;
tconfig.intval[NO_STAGEBG_FPSLIMIT] = 40;
}
int config_sym2key(int sym) {
int i;
for(i = CONFIG_KEY_FIRST; i <= CONFIG_KEY_LAST; ++i)
if(sym == tconfig.intval[i])
return i;
}

View file

@ -92,6 +92,7 @@ typedef struct {
int frames;
int lasttime; // frame limiter
int timer;
int replaytimer; // lol
Boss *boss;
MenuData *menu;
@ -123,4 +124,10 @@ void take_screenshot();
double frand();
// this is used by both player and replay code
enum {
EV_PRESS,
EV_RELEASE
};
#endif

View file

@ -197,8 +197,8 @@ void plr_realdeath(Player *plr) {
plr->pos = VIEWPORT_W/2 + VIEWPORT_H*I+30I;
plr->recovery = -(global.frames + DEATH_DELAY + 150);
if(global.plr.bombs < PLR_START_BOMBS)
global.plr.bombs = PLR_START_BOMBS;
if(plr->bombs < PLR_START_BOMBS)
plr->bombs = PLR_START_BOMBS;
if(plr->lifes-- == 0) {
if(plr->continues < MAX_CONTINUES)
@ -217,3 +217,108 @@ void plr_death(Player *plr) {
plr->deathtime = global.frames + DEATHBOMB_TIME;
}
}
// XXX: how about we convert all the plr_ prefixes to player_?
void player_setmoveflag(Player* plr, int key, int mode) {
int flag = 0;
switch(key) {
case KEY_UP: flag = MOVEFLAG_UP; break;
case KEY_DOWN: flag = MOVEFLAG_DOWN; break;
case KEY_LEFT: flag = MOVEFLAG_LEFT; break;
case KEY_RIGHT: flag = MOVEFLAG_RIGHT; break;
}
if(!flag)
return;
if(mode)
plr->moveflags |= flag;
else
plr->moveflags &= ~flag;
}
void player_event(Player* plr, int type, int key) {
switch(type) {
case EV_PRESS:
switch(key) {
case KEY_FOCUS:
plr->focus = 1;
break;
case KEY_SHOT:
plr->fire = True;
break;
case KEY_BOMB:
plr_bomb(plr);
break;
default:
player_setmoveflag(plr, key, True);
break;
}
break;
case EV_RELEASE:
switch(key) {
case KEY_FOCUS:
plr->focus = -30; // that's for the transparency timer
break;
case KEY_SHOT:
plr->fire = False;
break;
default:
player_setmoveflag(plr, key, False);
break;
}
break;
}
}
void player_applymovement(Player* plr) {
if(plr->deathtime < -1)
return;
plr->moving = False;
int up = player_hasmoveflag(*plr, MOVEFLAG_UP),
down = player_hasmoveflag(*plr, MOVEFLAG_DOWN),
left = player_hasmoveflag(*plr, MOVEFLAG_LEFT),
right = player_hasmoveflag(*plr, MOVEFLAG_RIGHT);
if(left && !right) {
plr->moving = True;
plr->dir = 1;
} else if(right && !left) {
plr->moving = True;
plr->dir = 0;
}
complex direction = 0;
if(up) direction -= 1I;
if(down) direction += 1I;
if(left) direction -= 1;
if(right) direction += 1;
double real = creal(direction);
double imag = cimag(direction);
if(real && imag)
direction = (real + imag*I) / sqrt(real*real + imag*imag);
if(direction)
plr_move(&global.plr, direction);
/*
if(!keys[tconfig.intval[KEY_SHOT]] && plr->fire)
plr->fire = False;
if(!keys[tconfig.intval[KEY_FOCUS]] && plr->focus > 0)
plr->focus = -30;
*/
}

View file

@ -52,6 +52,8 @@ typedef struct {
Character cha;
ShotMode shot;
Enemy *slaves;
int moveflags;
} Player;
void init_player(Player*);
@ -66,4 +68,15 @@ void plr_move(Player*, complex delta);
void plr_bomb(Player*);
void plr_realdeath(Player*);
void plr_death(Player*);
#define MOVEFLAG_UP 1
#define MOVEFLAG_DOWN 2
#define MOVEFLAG_LEFT 4
#define MOVEFLAG_RIGHT 8
#define player_hasmoveflag(p,f) (((p).moveflags & (f)) == (f))
void player_setmoveflag(Player* plr, int key, int mode);
void player_event(Player* plr,int type, int key);
void player_applymovement(Player* plr);
#endif

11
src/replay.c Executable file
View file

@ -0,0 +1,11 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
* Copyright (C) 2012, Alexeyew Andrew <http://akari.thebadasschoobs.org/>
*/
void replay_event(int type, int key) {
}

9
src/replay.h Executable file
View file

@ -0,0 +1,9 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
* Copyright (C) 2012, Alexeyew Andrew <http://akari.thebadasschoobs.org/>
*/
void replay_event(int, int);

View file

@ -9,6 +9,9 @@
#include <SDL/SDL.h>
#include "global.h"
#include "replay.h"
#include "config.h"
#include "player.h"
#include "menu/ingamemenu.h"
StageInfo stages[] = {
@ -38,6 +41,13 @@ void stage_start() {
global.nostagebg = False;
}
void stage_ingamemenu() {
if(!global.menu)
global.menu = create_ingame_menu();
else
global.menu->quit = 1;
}
void stage_input() {
if(global.menu) {
menu_input(global.menu);
@ -47,68 +57,35 @@ void stage_input() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
int sym = event.key.keysym.sym;
int key = config_sym2key(sym);
global_processevent(&event);
if(event.type == SDL_KEYDOWN) {
if(sym == tconfig.intval[KEY_FOCUS])
global.plr.focus = 1;
else if(sym == tconfig.intval[KEY_SHOT]) {
if(!global.dialog)
global.plr.fire = True;
else
switch(event.type) {
case SDL_KEYDOWN:
printf("%d / %d\n", sym, SDLK_ESCAPE);
if(global.dialog && (key == KEY_SHOT || key == KEY_BOMB)) {
page_dialog(&global.dialog);
} else if(sym == tconfig.intval[KEY_BOMB]) {
if(!global.dialog)
plr_bomb(&global.plr);
} else if(sym == SDLK_ESCAPE) {
if(!global.menu)
global.menu = create_ingame_menu();
else
global.menu->quit = 1;
}
} else if(event.type == SDL_KEYUP) {
if(sym == tconfig.intval[KEY_FOCUS])
global.plr.focus = -30; // that's for the transparency timer
else if(sym == tconfig.intval[KEY_SHOT])
global.plr.fire = False;
} else if(event.type == SDL_QUIT) {
exit(1);
} else if(sym == SDLK_ESCAPE) {
stage_ingamemenu();
} else {
player_event(&global.plr, EV_PRESS, key);
replay_event(EV_PRESS, key);
}
break;
case SDL_KEYUP:
player_event(&global.plr,EV_RELEASE, key);
replay_event(EV_RELEASE, key);
break;
case SDL_QUIT:
exit(1);
break;
}
}
if(global.plr.deathtime < -1)
return;
Uint8 *keys = SDL_GetKeyState(NULL);
global.plr.moving = False;
if(keys[tconfig.intval[KEY_LEFT]] && !keys[tconfig.intval[KEY_RIGHT]]) {
global.plr.moving = True;
global.plr.dir = 1;
} else if(keys[tconfig.intval[KEY_RIGHT]] && !keys[tconfig.intval[KEY_LEFT]]) {
global.plr.moving = True;
global.plr.dir = 0;
}
complex direction = 0;
if(keys[tconfig.intval[KEY_LEFT]])
direction -= 1;
if(keys[tconfig.intval[KEY_RIGHT]])
direction += 1;
if(keys[tconfig.intval[KEY_UP]])
direction -= 1I;
if(keys[tconfig.intval[KEY_DOWN]])
direction += 1I;
if(direction)
plr_move(&global.plr, direction);
if(!keys[tconfig.intval[KEY_SHOT]] && global.plr.fire)
global.plr.fire = False;
if(!keys[tconfig.intval[KEY_FOCUS]] && global.plr.focus > 0)
global.plr.focus = -30;
player_applymovement(&global.plr);
}
void draw_hud() {
@ -332,8 +309,11 @@ void stage_logic(int time) {
global.frames++;
if(!global.dialog && !global.boss)
global.timer++;
if(!global.dialog) {
if(!global.boss)
global.timer++;
global.replaytimer++;
}
if(global.timer >= time)
global.game_over = GAMEOVER_WIN;