📄 sprite.cpp
字号:
bullet->Create( BULLET, x, y, 16, 16, 4, &g_bmBullet );
bullet->BitBlt( NONE, RIGHT );
bullet->BitBlt( NONE, RIGHT );
bullet->BitBlt( NONE, RIGHT );
bullet->BitBlt( NONE, RIGHT );
bullet->SetAction( NONE, RIGHT );
bullet->m_xv = xv;
bullet->m_yv = yv;
bullet->m_ya = GRAVITY;
g_sprites.Add( bullet );
}
void CPlayer::Draw( int planex )
{
int x = (int)m_x - planex;
int y = (int)m_y;
RECT rc;
rc.left = (m_curBitmap % 8) * m_width;
rc.top = (m_curBitmap / 8) * m_height;
if( m_type == 1 )
rc.top += 64;
rc.right = rc.left + m_width;
rc.bottom = rc.top + m_height;
if( x < 0 )
{
rc.left += -x;
x = 0;
}
else if( x + m_width > 640 )
rc.right -= x + m_width - 640;
if( y < 0 )
{
rc.top += -y;
y = 0;
}
else if( y + m_height > 480 )
rc.bottom -= y + m_height - 480;
if( !m_shield || m_show )
m_pbmSprite->Draw( x, y, rc );
if( m_shield )
{
m_show = !m_show;
CTime time;
time.GetTime();
if( time - m_shieldTime > 3 )
m_shield = FALSE;
}
}
void CPlayer::Move( float time, BYTE input )
{
static BYTE lastinput;
if( m_action == DEAD )
{
CSprite::Move( time );
return;
}
// update position
float startx = m_x;
float starty = m_y;
float xv = m_xv;
float maxspeed;
if( (input & KEY_ACC) && m_onground )
maxspeed = 400;
else
maxspeed = 250;
m_xv += m_xa * time;
m_yv += m_ya * time;
if( m_xv > maxspeed )
m_xv = maxspeed;
else if( m_xv < -maxspeed )
m_xv = -maxspeed;
m_x += m_xv * time;
m_y += m_yv * time;
if( m_x < g_plane.m_x )
m_x = (float)g_plane.m_x;
if( xv > 0 && m_xv < 0 ||
xv < 0 && m_xv > 0 )
{
if( m_onground )
{
m_xv = 0;
m_xa = 0;
SetAction( STILL );
}
}
// animate
if( m_xv )
m_relSwitch += fabs(m_xv) * time;
else
m_relSwitch += fabs(m_yv) * time;
if( m_relSwitch >= m_absSwitch )
{
m_relSwitch = 0;
AdvanceBitmap();
}
// process user input
if( input & KEY_RIGHT )
{
if( m_dir == LEFT )
{
if( m_onground )
{
ChangeDirection();
if( m_action != STILL && m_xv < 0 )
{
m_xa = 1000;
SetAction( STOP );
}
}
else
m_xa = 500;
}
else if( !m_onground || m_action == STILL )
{
m_xa = 500;
if( m_action == STILL )
SetAction( WALK );
}
}
else if( input & KEY_LEFT )
{
if( m_dir == RIGHT )
{
if( m_onground )
{
ChangeDirection();
if( m_action != STILL && m_xv > 0 )
{
m_xa = -1000;
SetAction( STOP );
}
}
else
m_xa = -500;
}
else if( !m_onground || m_action == STILL )
{
m_xa = -500;
if( m_action == STILL )
SetAction( WALK );
}
}
if( m_onground && // jump
(input & KEY_JUMP) && !(lastinput & KEY_JUMP) )
{
m_onground = FALSE;
SetAction( JUMP );
if( input & KEY_ACC )
m_yv = -650;
else
m_yv = -600;
m_ya = GRAVITY;
m_xa = 0;
}
if( m_hasbullet && (input & KEY_ACC) && !(lastinput & KEY_ACC) )
Fire();
if( m_onground && // friction
!(input & KEY_RIGHT) && !(input & KEY_LEFT) )
{
if( m_xv > 0 )
m_xa = -500;
else if( m_xv < 0 )
m_xa = 500;
}
if( m_action == JUMP && m_yv < 0 &&
!(input & KEY_JUMP) && (lastinput & KEY_JUMP) )
{
m_ya += 1250;
}
// collision detection
COLLISION col;
g_plane.Collide(m_width, m_height, startx, starty, m_x, m_y, &col);
col.sprite = NULL;
for( CSprite *sprite=g_sprites.m_head; sprite;
sprite = sprite->m_next )
{
if( sprite->m_action == UPSIDEDOWN )
continue;
BOOL b = FALSE;
if( sprite->m_type == GHOST && sprite->m_action != DEAD ||
sprite->m_type == WALKTURTLE ||
sprite->m_type == FLYTURTLE ||
sprite->m_type == MUSHROOM ||
sprite->m_type == FLOWER )
b = TRUE;
if( b && Collide(startx, starty, sprite, &col) )
col.sprite = sprite;
}
if( col.frac <= 1 )
{
m_x = col.sectx;
m_y = col.secty;
if( !col.sprite ) // player hit something(eg. bricks)
{
if( col.type == COL_VERT )
{
m_xv = 0;
m_xa = 0;
if( m_action != JUMP )
SetAction( STILL );
}
else
{
if( m_yv > 0 )
{
m_onground = TRUE;
m_yv = 0;
m_ya = 0;
if( m_xv == 0 )
SetAction( STILL );
else
SetAction( WALK );
}
else
{
m_yv = -m_yv/3;
m_xv /= 2;
if( col.contents == SURF_BRICK )
{
if( m_type == 1 )
{
AddDebris( col.tilex, col.tiley );
g_plane.SetSurface( col.tilex, col.tiley, SURF_NONE );
}
}
else if( col.contents == SURF_COIN ||
col.contents == SURF_MUSHROOM )
{
g_plane.SetSurface( col.tilex, col.tiley, SURF_SOLID );
switch( col.contents )
{
case SURF_COIN:
AddCoin( col.tilex, col.tiley );
break;
case SURF_MUSHROOM:
if( m_type == 0 )
AddMushroom( col.tilex, col.tiley );
else
AddFlower( col.tilex, col.tiley );
break;
}
}
}
}
}
else
{
if( col.sprite->m_type == MUSHROOM )
{
g_sprites.Delete( col.sprite );
GrowUp();
}
else if( col.sprite->m_type == FLOWER )
{
g_sprites.Delete( col.sprite );
if( m_type == 1 )
m_hasbullet = TRUE; // we've got bullet!
else
GrowUp(); // just take it as a mushroom
}
else if( col.sprite->m_action != DEAD )
{
if( m_yv > 0 )
{
if( !col.sprite->m_onground )
{
col.sprite->m_yv = 150;
col.sprite->m_ya = GRAVITY;
}
m_yv = -150;
if( col.sprite->m_type == FLYTURTLE )
col.sprite->m_type = WALKTURTLE;
else
{
col.sprite->SetAction( DEAD, RIGHT );
col.sprite->m_xv = 0;
}
}
else if( !m_shield )
BeenHit();
}
else // the dead turtle
{
if( col.sprite->m_xv ) // moving
{
if( col.type == COL_VERT )
BeenHit();
else // stop it
{
col.sprite->m_xv = 0;
m_yv = -150; // bounce us up
}
}
else // kick it off
{
if( col.type == COL_HORZ )
m_y += 3; // to avoid some odd things happening
float playerx = m_x + m_width/2;
float ghostx = col.sprite->m_x + col.sprite->m_width/2;
if( playerx <= ghostx )
col.sprite->m_xv = 500;
else
col.sprite->m_xv = -500;
}
}
}
}
CheckBottom();
// scroll screen
int screenx = (int)m_x - g_plane.m_x;
if( screenx > 288 )
g_plane.IncrementX( screenx - 288 );
// see if we fall into channel
if( g_player.m_y > 480 )
{
m_type = 0;
g_player.BeenHit();
}
lastinput = input;
}
void CGhost::GetBox( BOX &box )
{
CSprite::GetBox( box );
if( m_type == WALKTURTLE || m_type == FLYTURTLE )
box.miny += 16;
}
void CGhost::Move( float time )
{
if( !m_active )
return;
float startx = m_x;
float starty = m_y;
CSprite::Move( time );
if( m_action == UPSIDEDOWN )
return;
COLLISION col;
g_plane.Collide(m_width, m_height, startx, starty, m_x, m_y, &col);
col.sprite = NULL;
for( CSprite *sprite=g_sprites.m_head; sprite;
sprite = sprite->m_next )
{
if( sprite->m_action == UPSIDEDOWN )
continue;
if( sprite->m_type == GHOST && sprite->m_action != DEAD ||
sprite->m_type == WALKTURTLE ||
sprite->m_type == FLYTURTLE )
{
if( Collide(startx, starty, sprite, &col) )
col.sprite = sprite;
}
}
if( (g_player.m_action != DEAD) && (!g_player.m_shield) )
{
if( Collide(startx, starty, &g_player, &col) )
col.sprite = &g_player;
}
if( col.frac <= 1 )
{
m_x = col.sectx;
m_y = col.secty;
if( col.sprite == &g_player )
{
if( col.type == COL_VERT || m_y >= 0 )
g_player.BeenHit();
}
else if( !col.sprite && col.type == COL_HORZ )
{
if( m_yv >= 0 )
m_onground = TRUE;
m_ya = 0;
m_yv = 0;
}
else
{
ChangeDirection();
m_xv = -m_xv;
}
}
CheckBottom();
}
void CWalkTurtle::Move( float time )
{
if( !m_active )
return;
if( m_action != DEAD )
{
CGhost::Move( time );
return;
}
float startx = m_x;
float starty = m_y;
CSprite::Move( time );
if( m_action == UPSIDEDOWN )
return;
COLLISION col;
g_plane.Collide(m_width, 32, startx, starty+16, m_x, m_y+16, &col);
col.sprite = NULL;
for( CSprite *sprite=g_sprites.m_head; sprite;
sprite = sprite->m_next )
{
if( sprite->m_action == UPSIDEDOWN )
continue;
if( sprite->m_type == GHOST && sprite->m_type != DEAD ||
sprite->m_type == WALKTURTLE ||
sprite->m_type == FLYTURTLE )
{
if( Collide(startx, starty, sprite, &col) )
col.sprite = sprite;
}
}
if( (g_player.m_action != DEAD) && (!g_player.m_shield) )
{
if( Collide(startx, starty, &g_player, &col) )
col.sprite = &g_player;
}
if( col.frac <= 1 )
{
m_x = col.sectx;
m_y = col.secty - 16;
if( col.sprite )
{
if( col.sprite == &g_player )
g_player.BeenHit();
else // hit other ghost
{
col.sprite->SetAction( DEAD, RIGHT );
col.sprite->SetAction( UPSIDEDOWN, RIGHT );
col.sprite->m_ya = GRAVITY;
col.sprite->m_yv = -200;
col.sprite->m_xv = -col.sprite->m_xv;
}
}
else
{
if( col.type == COL_HORZ )
{
m_onground = TRUE;
m_ya = 0;
m_yv = 0;
}
else
m_xv = -m_xv;
}
}
CheckBottom();
}
void CFlyTurtle::Move( float time )
{
if( !m_active )
return;
if( m_type == WALKTURTLE )
{
CWalkTurtle::Move( time );
return;
}
if( m_type == FLYTURTLE ) // I believe I can fly
{
if( m_onground )
{
m_yv = -350;
m_ya = GRAVITY/2;
m_onground = FALSE;
}
}
CGhost::Move( time );
}
void CFlyTurtle::Draw( int planex )
{
int x = (int)m_x - planex;
int y = (int)m_y;
if( x + m_width < 0 || x > 640 ||
y + m_height < 0 || y > 480 )
return;
RECT rc;
rc.left = m_curBitmap * m_width;
if( m_type == WALKTURTLE )
rc.top = 0;
else
rc.top = 48;
rc.right = rc.left + m_width;
rc.bottom = rc.top + m_height;
if( x < 0 )
{
rc.left += -x;
x = 0;
}
else if( x + m_width > 640 )
rc.right -= x + m_width - 640;
if( y < 0 )
{
rc.top += -y;
y = 0;
}
else if( y + m_height > 480 )
rc.bottom -= y + m_height - 480;
m_pbmSprite->Draw( x, y, rc );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -