⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sprite.cpp

📁 qt版的超级玛利
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 + -