📄 player.cpp
字号:
}
}
else
turn_key_down[0] = false;
if(key[config.key_right[who2]]) {
if(config.moving_style[who2] == MOV_RELATIVE) {
// Relative moving
if(!turn_key_down[1] && !turning) {
// Turn right
nextdir = dir + 1;
if(nextdir > DIR_W)
nextdir = DIR_N;
if(!walking)
dir = nextdir;
turn_key_down[1] = true;
}
}
else if(config.moving_style[who2] == MOV_ABSOLUTE && !walking) {
// Absolute moving
dir = DIR_E;
walking = true;
offset = 0.0f;
tx = x + 1;
ty = y;
// Check if the target is passable?
if(map_solid(tx, ty)) {
tx = x;
ty = y;
walking = false;
}
if(on_block) {
// We're on a block, jump down from it
jump(tx, ty, 2.0f, 0.05f);
tx = x;
ty = y;
anim = 0;
on_block = true;
// Play the jumping sound
if(jumping)
play_sound(SND_JUMP, false);
}
}
}
else
turn_key_down[1] = false;
// Check for 180 degree turning
if(key[config.key_down[who2]]) {
if(config.moving_style[who2] == MOV_RELATIVE) {
// Relative moving
if(!turn_key_down[2] && !turning && !walking && !key[config.key_up[who2]]) {
nextdir = dir + 1;
if(nextdir > DIR_W)
nextdir = DIR_N;
turning = true;
turning_counter = 0;
turn_key_down[2] = true;
}
}
else if(config.moving_style[who2] == MOV_ABSOLUTE && !walking) {
// Absolute moving
dir = DIR_S;
walking = true;
offset = 0.0f;
tx = x;
ty = y + 1;
// Check if the target is passable?
if(map_solid(tx, ty)) {
tx = x;
ty = y;
walking = false;
}
if(on_block) {
// We're on a block, jump down from it
jump(tx, ty, 2.0f, 0.05f);
tx = x;
ty = y;
anim = 0;
on_block = true;
// Play the jumping sound
if(jumping)
play_sound(SND_JUMP, false);
}
}
}
else
turn_key_down[2] = false;
// Don't move if we're using the flower power (relative)
if(on_block && config.moving_style[who2] == MOV_RELATIVE && (p1.num_flower_bombs > 0 || p2.num_flower_bombs > 0))
return;
// Check for walking input
if(key[config.key_up[who2]] && !walking && !turning) {
if(config.moving_style[who2] == MOV_RELATIVE) {
// Relative moving
walking = true;
offset = 0.0f;
dir = nextdir;
switch(dir) {
default:
case DIR_N: tx = x; ty = y - 1; break;
case DIR_E: tx = x + 1; ty = y; break;
case DIR_S: tx = x; ty = y + 1; break;
case DIR_W: tx = x - 1; ty = y; break;
}
// Check if the target is passable?
if(map_solid(tx, ty)) {
tx = x;
ty = y;
walking = false;
}
if(on_block) {
// We're on a block, jump down from it
jump(tx, ty, 2.0f, 0.05f);
tx = x;
ty = y;
anim = 0;
on_block = true;
// Play the jumping sound
if(jumping)
play_sound(SND_JUMP, false);
}
}
else {
// Absolute moving
dir = DIR_N;
walking = true;
offset = 0.0f;
tx = x;
ty = y - 1;
// Check if the target is passable?
if(map_solid(tx, ty)) {
tx = x;
ty = y;
walking = false;
}
if(on_block) {
// We're on a block, jump down from it
jump(tx, ty, 2.0f, 0.05f);
tx = x;
ty = y;
anim = 0;
on_block = true;
// Play the jumping sound
if(jumping)
play_sound(SND_JUMP, false);
}
}
}
// Move towards the target tile
if(offset < 1.0f && (tx != x || ty != y)) {
offset += 0.1f;
// If we're reached the target tile, move again
if(offset >= 1.0f) {
x = tx;
y = ty;
offset = 0.0f;
walking = false;
in_teleport = 0;
}
}
// Reload the weapons
if(reload > 0)
reload--;
// Dropping bombs
if(key[config.key_shoot[who2]] && reload == 0 && num_bombs < 3 && !on_block && !icon_menu.wait) {
reload = 30;
// Plant the bomb
add_bomb(x, y, BTYP_NORMAL, who);
num_bombs++;
// Play the sound
play_sound(SND_BOMB, false);
}
// Invoke the special powers
if(key[config.key_special[who2]]) {
open_icon_menu(who, on_block);
show_icon(0);
show_icon(1);
}
#endif
}
// The player dies
void PLAYER::die() {
if(jumping)
return;
if(dying)
return; // Hey, don't you die twice, man! ;)
dying = true;
die_anim = 1.0f;
death_counter = 80; // Just over one second
// Play the sound
static int last_sound = -1;
int sound = last_sound;
while(sound == last_sound)
sound = RAND(SND_DIE1, SND_DIE6);
play_sound(sound, false);
last_sound = sound;
// Reduce the special powers
for(int f=0; f<NUM_ICONS; f++) {
//icon_menu.count[f] = 0;
if(icon_menu.count[f])
icon_menu.count[f]--;
}
// Add a comment
add_comment(COL_DEFAULT, "Respawning soon...");
}
// From bonus.cpp
extern int powers_from_bonuses;
// Pick a bonus up
void PLAYER::pick_bonus(BONUS *b) {
#ifndef EDITOR
b->alive = false;
b->effect();
if(wisp.bonus == b)
wisp.bonus = NULL;
// Handle the bonuses
bonus_counter[b->type]++;
if(bonus_counter[b->type] >= powers_from_bonuses) {
// Add a comment
switch(next_bonus[b->type]) {
default:
case RED_POWER_TRAP:
add_comment(COL_RED, "You have received a Trap."); break;
case RED_POWER_WILDFIRE:
add_comment(COL_RED, "You have received a Wild Fire."); break;
case RED_POWER_NAPALM:
add_comment(COL_RED, "You have received a Napalm Strike."); break;
case GREEN_POWER_WISP:
add_comment(COL_GREEN, "You have received a Will O' The Wisp."); break;
case GREEN_POWER_POTATOMAN:
add_comment(COL_GREEN, "You have received a Potato Man."); break;
case GREEN_POWER_FLOWERPOWER:
add_comment(COL_GREEN, "You have received a Flower Power."); break;
case BLUE_POWER_TELEPORT:
add_comment(COL_BLUE, "You have received a Teleport."); break;
case BLUE_POWER_TURN:
add_comment(COL_BLUE, "You have received a Turn."); break;
case BLUE_POWER_LIGHTNING:
add_comment(COL_BLUE, "You have received a Lightning Bolt."); break;
}
// Handle the special power
icon_menu.count[next_bonus[b->type]]++;
next_bonus[b->type]++;
switch(b->type) {
default:
case BONUS_RED:
if(next_bonus[BONUS_RED] > RED_POWER_NAPALM)
next_bonus[BONUS_RED] = RED_POWER_TRAP;
break;
case BONUS_GREEN:
if(next_bonus[BONUS_GREEN] > GREEN_POWER_FLOWERPOWER)
next_bonus[BONUS_GREEN] = GREEN_POWER_WISP;
break;
case BONUS_BLUE:
if(next_bonus[BONUS_BLUE] > BLUE_POWER_LIGHTNING)
next_bonus[BONUS_BLUE] = BLUE_POWER_TELEPORT;
break;
}
bonus_counter[b->type] = 0;
}
#endif
}
// Get current x with offset
float PLAYER::get_real_x() {
// Calculate the offset
float offx = 0;
if(dir == DIR_E)
offx = offset;
else if(dir == DIR_W)
offx = -offset;
return (float)x + offx + 0.5f;
}
// Get current y with offset
float PLAYER::get_real_y() {
// Calculate the offset
float offy = 0;
if(dir == DIR_N)
offy = -offset;
else if(dir == DIR_S)
offy = offset;
return (float)y + offy + 0.5f;
}
// Teleport power instance from special_power.cpp
#ifndef EDITOR
extern SP_TELEPORT sp_teleport;
#endif
// Draw the player
void PLAYER::draw() {
if(!alive)
return;
// Calculate the offset
float offx = 0, offz = 0;
switch(dir) {
default:
case DIR_N: offz = -offset; break;
case DIR_E: offx = offset; break;
case DIR_S: offz = offset; break;
case DIR_W: offx = -offset; break;
}
// Translate to the position
glPushMatrix();
glTranslatef(x + offx + 0.5f, size - 0.20f, y + offz + 0.5f);
// Take the jumping position in to account
int jpox = -1;
int jpoy = -1;
float shadow_offset = 0.0f;
#ifndef EDITOR
if(jumping) {
VECT jpos = 0.0f;
jpos = jump_dir * jump_pos * jump_dist;
glTranslatef(jpos.x, jpos.y, jpos.z);
// If we're over a block, raise the shadow a bit higher
jpox = (int)(x + offx + 0.5f + jpos.x);
jpoy = (int)(y + offz + 0.5f + jpos.z);
if(map[jpox][jpoy][1])
shadow_offset = TILE_H + 0.01f;
else if(!map[jpox][jpoy][0])
// Translate a waaaay down, so that the shadow can't be seen
shadow_offset = -100.0f;
}
#endif
// If we're jumped over a block, raise the player up
if(map[x][y][1]) {
glTranslatef(0, TILE_H, 0);
shadow_offset = 0.01f;
}
// Draw the shadow
glDepthMask(GL_FALSE);
glColor3f(1,1,1);
BIND_TEXTURE(sprite_shadow);
float sh = -(size - 0.21f);
glTranslatef(0, shadow_offset, 0);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(1,1); glVertex3f( 0.6f, sh, -0.6f);
glTexCoord2f(0,1); glVertex3f(-0.6f, sh, -0.6f);
glTexCoord2f(1,0); glVertex3f( 0.6f, sh, 0.6f);
glTexCoord2f(0,0); glVertex3f(-0.6f, sh, 0.6f);
glEnd();
glTranslatef(0, -shadow_offset, 0);
glDepthMask(GL_TRUE);
// If we're jumping, translate up to the position
#ifndef EDITOR
if(jumping) {
float jy = jump_height * SIN(180.0f * jump_pos);
// If we're jumping to a block, make sure we don't "sink" in it
if(map[jump_tx][jump_ty][1] && jy < TILE_H && jump_pos > 0.5f)
jy = TILE_H;
glTranslatef(0, jy, 0);
}
// If we're teleporting using the teleport special, raise ourselves up!
int who = (this == &p1) ? 1 : 2;
if(using_special_power == who && which_special_power == BLUE_POWER_TELEPORT)
glTranslatef(0, TELEPORT_POWER_HEIGHT * sp_teleport.teleport_pos, 0);
#endif
// Negate the camera rotation
glMultMatrixf(cam_neg_matrix);
// glRotatef(45.0f, 0,1,0);
// glRotatef(-30.0f, 1,0,0);
// Compute the texture coords according the animation frame and direction
BIND_TEXTURE(player1_anim);
int f = anim_frames[(int)anim];
float textx = 0.25f * f;
float texty = 0.25f * (3-dir);
// Draw the sprite
if(!dying) {
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(textx + 0.25f, texty + 0.25f); glVertex3f( size, size, size);
glTexCoord2f(textx, texty + 0.25f); glVertex3f(-size, size, size);
glTexCoord2f(textx + 0.25f, texty); glVertex3f( size, -size, -size);
glTexCoord2f(textx, texty); glVertex3f(-size, -size, -size);
glEnd();
}
else {
// Draw the dying animation
float z = size - (2*size*(1-die_anim));
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(textx + 0.25f, texty + (die_anim*0.25f)); glVertex3f( size, z, z);
glTexCoord2f(textx, texty + (die_anim*0.25f)); glVertex3f(-size, z, z);
glTexCoord2f(textx + 0.25f, texty); glVertex3f( size, -size, -size);
glTexCoord2f(textx, texty); glVertex3f(-size, -size, -size);
glEnd();
}
glPopMatrix();
}
// Clear the player
void PLAYER::clear() {
x = y = 0;
tx = ty = 0;
offset = 0.0f;
dir = DIR_E;
nextdir = dir;
size = 0.75f;
anim = 0.0f;
walking = false;
turning = false;
turning_counter = 0;
reload = 0;
num_bombs = 0;
num_flower_bombs = 0;
alive = true;
death_counter = 0;
turn_key_down[0] = turn_key_down[1] = turn_key_down[2] = false;
in_teleport = 0;
jumping = false;
jump_pos = jump_dist = jump_height = jump_speed = 0.0f;
jump_tx = jump_ty = 0;
jump_dir = 0.0f;
dying = false;
die_anim = 0.0f;
}
// Jump
void PLAYER::jump(int tx, int ty, float height, float speed) {
if(jumping)
return;
if(tx == (int)get_real_x() && ty == (int)get_real_y())
return;
jumping = true;
// Direction vector
float dx = ((float)tx + 0.5f) - get_real_x();
float dy = ((float)ty + 0.5f) - get_real_y();
jump_dir.x = dx;
jump_dir.z = dy;
jump_dir.y = 0;
normalize(jump_dir);
// Compute the distance
jump_dist = sqrtf(dx*dx + dy*dy);
jump_pos = 0.0f;
jump_height = height;
jump_speed = speed;
// Save the target tile
jump_tx = tx;
jump_ty = ty;
walking = false;
anim = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -