funcode实验--拍飞虫(c++实现)

C++语言课程设计一拍飞虫

一、实验内容

玩家通过控制拍子拍打飞虫获取分数。

要求如下:

1、 单击空格键即可进入游戏。进入游戏后左上角有两个记录游戏数据标示。上面一个是记录游戏剩余时间,下面一个是记录本局的游戏分数。下面也有五个记录游戏数据的标示,从左到右分别是记录各局游戏分数分数最高的前五个。

2、 移动鼠标可以控制拍子的移动,单击鼠标左键可以控制拍子拍打动作。

3、 游戏开始的时候,系统随机生成12个虫子,其中大虫子5个,小虫子7个,每打死一个大虫子获得1分,打死一个小虫子获得2分。游戏的分数会实时的显示在左上角。

4、  附加:姓名随拍子一块运动。

二、实验代码

LessonX.h

/
//
//
//
//
/
#ifndef _LESSON_X_H_
#define _LESSON_X_H_
//
#include <Windows.h>

/
//
// 游戏总管类。负责处理游戏主循环、游戏初始化、结束等工作
class	CGameMain
{
private:
	int				m_iGameState;				// 游戏状态,0:结束或者等待开始;1:初始化;2:游戏进行中
    CSprite*		m_pPaizi;	//拍子精灵
	CSprite*		m_pKaishi;	//空格开始精灵
	float			m_fGameTime	;	// 本局游戏剩余时间
	CTextSprite*	m_pTime;  //显示时间文字编辑精灵
	CTextSprite*	m_pScore;	//显示分数文件编辑精灵
	float			m_fPosX;	//拍子精灵的x坐标
	float			m_fPosY;	//拍子精灵的y坐标
	int			m_iGameScore;	// 本局游戏当前积分值
    float		m_fRotateTime;		// 拍子拍下后距离复位还差多少时间
	float		m_fOldRotation;		// 拍子的初始角度
    float		m_fScreenLeft;// 屏幕的4个边界值:上下左右
	float		m_fScreenRight;
	float		m_fScreenTop;
	float		m_fScreenBottom;
  //  CSprite*	m_pFeichong;		//飞虫精灵
  	CSprite*	m_pFeichong[15];		//飞虫精灵
	int			m_iScore[15];			//拍中对应飞虫精灵的得分
	int			m_iCount;		// 记录游戏中一共创建多少只飞虫
	int			m_iHighScore[5] ;// 最高的5局分数
    CTextSprite*	m_pScoreNum[5];//地图下方的5个文字显示精灵数组
    CSprite*    m_pMyName;
public:
	CGameMain();            //构造函数
	~CGameMain();           //析构函数

	// Get方法
	int				GetGameState()											{ return m_iGameState; }

	// Set方法
	void			SetGameState( const int iState )				{ m_iGameState	=	iState; }

	// 游戏主循环等
	void			GameMainLoop( float	fDeltaTime );
	void			GameInit();
	void			GameRun( float fDeltaTime );
	void			GameEnd();
	void	OnKeyDown( const int iKey, const int bAltPress, const int bShiftPress, const int bCtrlPress );
    void			OnMouseMove( const float fMouseX, const float fMouseY );
    void	OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY );
    void			Flying(const char* szName); //参数为设置飞虫飞行的名字
    void			OnSpriteColWorldLimit( const char *szName, const int iColSide );
    void			AddFlyBugs();	// 添加飞虫
    CSprite*		FindSpriteByName(const char* szName);//找到飞虫的名字
    CTextSprite*	FindTextSpriteByName(const char* szName);
};

/
//
extern CGameMain	g_GameMain;

#endif // _LESSON_X_H_

LessonX.cpp

/
//
//
//
//
/
#include <Stdio.h>
#include "CommonClass.h"
#include "LessonX.h"

//
//
CGameMain		g_GameMain;

//==============================================================================
//
// 大体的程序流程为:GameMainLoop函数为主循环函数,在引擎每帧刷新屏幕图像之后,都会被调用一次。

//==============================================================================
//
// 构造函数
CGameMain::CGameMain()
{
	m_iGameState		=0;
	m_fGameTime			=0.f;
    m_iGameScore		=0;
    m_fPosX				=0.f;
    m_fPosY				=0.f;
    m_pKaishi			=new CSprite("kaishi");
    m_pPaizi			=new CSprite("paizi");
    m_pTime				=new CTextSprite("Time");
    m_pScore			=new CTextSprite("Score");
    m_fRotateTime			=0.f;
    m_fOldRotation			=0.f;
    //屏幕的4个边界值:上下左右
    m_fScreenBottom			=0.f;
	m_fScreenLeft			=0.f;
	m_fScreenRight			=0.f;
    m_fScreenTop			=0.f;
    //m_pFeichong				=new CSprite("feichong_0");
    m_iCount				=0;
    for(int i=0;i<5;i++)
	{
		m_iHighScore[i]=0;
		m_pScoreNum[i]=new CTextSprite(CSystem::MakeSpriteName("Score",i));
    }
    m_pMyName=new CSprite("MyName");
}
//==============================================================================
//
// 析构函数
CGameMain::~CGameMain()
{
}
//==============================================================================
//
// 游戏主循环,此函数将被不停的调用,引擎每刷新一次屏幕,此函数即被调用一次
// 用以处理游戏的开始、进行中、结束等各种状态.
// 函数参数fDeltaTime : 上次调用本函数到此次调用本函数的时间间隔,单位:秒
void CGameMain::GameMainLoop( float	fDeltaTime )
{
	switch( GetGameState())
	{
		// 初始化游戏,清空上一局相关数据
	case 1:
		{
			GameInit();
			SetGameState(2); // 初始化之后,将游戏状态设置为进行中
		}
		break;
		// 游戏进行中,处理各种游戏逻辑
	case 2:
		{
			// TODO 修改此处游戏循环条件,完成正确游戏逻辑
			if(m_fGameTime>0)
			{
				GameRun( fDeltaTime );
			}
			else // 游戏结束。调用游戏结算函数,并把游戏状态修改为结束状态
			{
				SetGameState(0);
				GameEnd();
			}
		}
		break;

		// 游戏结束/等待按空格键开始
	case 0:
	default:
		break;
	};
}
//=============================================================================
//
// 每局开始前进行初始化,清空上一局相关数据
void CGameMain::GameInit()
{
    m_fPosX=m_pPaizi->GetSpritePositionX();
    m_fPosY=m_pPaizi->GetSpritePositionY();
    m_fOldRotation=m_pPaizi->GetSpriteRotation();
   /*
    //获取世界边界的值
    m_fScreenLeft   = CSystem::GetScreenLeft();
	m_fScreenRight  = CSystem::GetScreenRight();
	m_fScreenTop    = CSystem::GetScreenTop();
    m_fScreenBottom = CSystem::GetScreenBottom();
    // 设置该精灵的世界边界
    m_pFeichong->SetSpriteWorldLimit(WORLD_LIMIT_NULL, m_fScreenLeft-10.f, m_fScreenTop-10.f, m_fScreenRight+10.f, m_fScreenBottom+10.f);
    */

}
//=============================================================================
//
// 每局游戏进行中
void CGameMain::GameRun( float fDeltaTime )
{
      m_fGameTime -= fDeltaTime;
      m_pTime->SetTextValue((int)m_fGameTime);
      //在游戏中判断拍子拍下后,动作时间是否达到了0,是的话恢复拍子的角度
      if(m_fRotateTime > 0)
      {
            m_fRotateTime -= fDeltaTime;
			if(m_fRotateTime <= 0)
			{
				m_pPaizi->SetSpriteRotation(m_fOldRotation);
			}
      }
}
//=============================================================================
//
// 本局游戏结束
void CGameMain::GameEnd()
{
    m_iGameState = 0;
    m_pKaishi->SetSpriteVisible(true);
    m_fGameTime = 0.f;
    //m_pScore->SetTextValue((int)m_fGameTime);
    m_pTime->SetTextValue((int)m_fGameTime);
    CSystem::ShowCursor(true);
    m_pPaizi->SetSpritePosition(m_fPosX,m_fPosY);
    //m_pFeichong->DeleteSprite();
    for(int i=0; i<m_iCount; i++)
    {
        m_pFeichong[i]->DeleteSprite();
    }
    m_iCount = 0;
    // 把本局分数与历史最高的5次分数比较
    if(m_iGameScore> m_iHighScore[4])
    {
        m_iHighScore[4] = m_iGameScore;
        int temp = 0;
        for(int i=4; i>0; i--)
        {
            if(m_iHighScore[i] > m_iHighScore[i-1])
            {
                temp = m_iHighScore[i];
                m_iHighScore[i] = m_iHighScore[i-1];
                m_iHighScore[i-1] = temp;
            }
            else
            {
                break;
            }
        }
    }
    char szName[256];
    for(int i=0; i<5; i++)
    {
        sprintf(szName, "Score%d", i);
        CTextSprite* tmpSprite=FindTextSpriteByName(szName);
        tmpSprite->SetTextValue(m_iHighScore[i]);
    }
}
//按键监听
void    CGameMain::OnKeyDown( const int iKey, const int bAltPress, const int bShiftPress, const int bCtrlPress )
{
        if( KEY_SPACE == iKey && 0 == m_iGameState )
        {
            m_iGameState =	1;
            m_iGameScore	=	0;
            m_fGameTime		=	30.f; //游戏总共的时间
            // 更新当前游戏积分显示(清零上一局积分显示值)
            m_pScore->SetTextValue(m_iGameScore);
            // 更新当前游戏剩余时间显示, 由于游戏刚开始,所以直接设置为g_fMaxGameTime
            m_pTime->SetTextValue(m_fGameTime);
            // 隐藏 "按空格开始游戏" 这个提示图片
            m_pKaishi->SetSpriteVisible(false);
            // 隐藏鼠标
            CSystem::ShowCursor(false);

            // 从精灵模板中复制出一只精灵
            //m_pFeichong->CloneSprite("feichong_muban1");

            //创建飞虫精灵
            AddFlyBugs();
            // 调用函数,设置飞虫飞行轨迹
			//Flying("feichong_0");

        }
}
//监听拍子的移动
void CGameMain::OnMouseMove( const float fMouseX, const float fMouseY )
{
    if(m_iGameState==1||m_iGameState==2)
    {
        m_pPaizi->SetSpritePosition(fMouseX, fMouseY);
        m_pMyName->SetSpritePosition(fMouseX, fMouseY+10.0f);
    }
}
void CGameMain::OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY )
{
    if(m_iGameState==1||m_iGameState==2)
	{
		m_pPaizi->SetSpriteRotation(m_fOldRotation - 10);
		m_fRotateTime	=	0.2f;
    }
    float fPosX, fPosY;
    /*
    fPosX = m_pFeichong->GetSpritePositionX();
    fPosY = m_pFeichong->GetSpritePositionY();
    // 飞虫中心点在拍子范围内,说明拍子打中飞虫
    if(m_pPaizi->IsPointInSprite(fPosX, fPosY))
    {
        Flying("feichong_0");
    }
    */
    for(int i=0; i<m_iCount; i++)
    {
        fPosX = m_pFeichong[i]->GetSpritePositionX();
        fPosY = m_pFeichong[i]->GetSpritePositionY();
        // 飞虫中心点在拍子范围内,说明拍子打中飞虫
        if(m_pPaizi->IsPointInSprite(fPosX, fPosY))
        {
            Flying(m_pFeichong[i]->GetName());
            m_iGameScore += m_iScore[i];
        }
    }
    m_pScore->SetTextValue(m_iGameScore);//更改游戏分数显示

}
//创建所有的飞虫
void CGameMain::AddFlyBugs()
{
    for(int i=0; i<5; i++)
	{
        m_pFeichong[m_iCount]=new
        CSprite(CSystem::MakeSpriteName("feichong_",m_iCount));
        m_iScore[m_iCount]=1;
        m_iCount++;
	}
	for(int i=0; i<7; i++)
	{
        m_pFeichong[m_iCount]=new
        CSprite(CSystem::MakeSpriteName("feichong_",m_iCount));
        m_iScore[m_iCount]=2;
        m_iCount++;
	}
    for(int i=0; i<m_iCount; i++)//创建精灵实体
    {
        // 从精灵模板中复制出一只精灵
        if(m_iScore[i] == 1)
        {
            m_pFeichong[i]->CloneSprite("feichong_muban1");
        }
        else
        {
            m_pFeichong[i]->CloneSprite("feichong_muban2");
        }
        // 获取屏幕边界值
        m_fScreenLeft   = CSystem::GetScreenLeft();
        m_fScreenRight  = CSystem::GetScreenRight();
        m_fScreenTop    = CSystem::GetScreenTop();
        m_fScreenBottom = CSystem::GetScreenBottom();
        // 设置该精灵的世界边界
        m_pFeichong[i]->SetSpriteWorldLimit(WORLD_LIMIT_NULL, m_fScreenLeft-10.f, m_fScreenTop-10.f, m_fScreenRight+10.f, m_fScreenBottom+10.f);
        Flying(m_pFeichong[i]->GetName());
    }
}

//随机生成飞虫的飞行轨迹
void CGameMain::Flying(const char* szName)
{
    int iDir = 0;
	float fPosX, fPosY, fPosX1, fPosY1;
	float fSpeed;
	iDir = CSystem::RandomRange(0,3);//随机生成飞虫出现的方向
    switch(iDir)
	{
	case 0: // 左方
		fPosX = CSystem::RandomRange(m_fScreenLeft-5.f, m_fScreenLeft);
        fPosY=CSystem::RandomRange(m_fScreenTop-5.f,m_fScreenBottom+5.f);
		break;
	case 1: // 下方
		fPosX= CSystem::RandomRange(m_fScreenLeft-5.f, m_fScreenRight+5.f);
		fPosY=CSystem::RandomRange(m_fScreenBottom,m_fScreenBottom+5.f);
		break;
	case 2: // 右方
		fPosX = CSystem::RandomRange(m_fScreenRight, m_fScreenRight+5.f);
        fPosY=CSystem::RandomRange(m_fScreenTop-5.f,m_fScreenBottom+5.f);
		break;
	case 3: // 上方m
		fPosX= CSystem::RandomRange(m_fScreenLeft-5.f, m_fScreenRight+5.f);
		fPosY = CSystem::RandomRange(m_fScreenTop-5.f, m_fScreenTop-5.f);
	}

    fSpeed = CSystem::RandomRange(10, 40);//随机生成飞虫飞行速度
	//飞虫飞行的终点位置
	fPosX1 = CSystem::RandomRange(m_fScreenLeft+15.f, m_fScreenRight-15.f);
	fPosY1=CSystem::RandomRange(m_fScreenTop+15.f, m_fScreenBottom-15.f);

	CSprite* tmpSprite=FindSpriteByName(szName);
	tmpSprite->SetSpritePosition(fPosX, fPosY);
    tmpSprite->SpriteMoveTo(fPosX1, fPosY1, fSpeed, false);

}
//飞虫与世界边界的碰撞
void CGameMain::OnSpriteColWorldLimit( const char *szName, const int iColSide )
{
    /*
    if(strcmp(szName, m_pFeichong->GetName())==0)
	{
		Flying("feichong_0");
    }
    */
    if(strstr(szName, "feichong")!=NULL)//判断是否是飞虫精灵
	{
		//遍历飞虫精灵判断是哪个飞虫
		for(int i=0; i<m_iCount; i++)
		{
			if(strcmp(szName, m_pFeichong[i]->GetName())==0)
			{
			Flying( m_pFeichong[i]->GetName());//重新设置飞虫的飞行动作
			}
		}
	}
}
CSprite* CGameMain::FindSpriteByName(const char* szName)
{
	for(int i=0;i<m_iCount;i++)
		if(strcmp(szName,m_pFeichong[i]->GetName())==0)
			return m_pFeichong[i];
    return NULL;
}
CTextSprite* CGameMain::FindTextSpriteByName(const char* szName)
{
    for(int i=0;i<5;i++)
        if(strcmp(szName,m_pScoreNum[i]->GetName())==0)
            return m_pScoreNum[i];
    return NULL;
}





Main.cpp

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
#include "CommonClass.h"
#include "LessonX.h"

///
//
// 主函数入口
//
//
int PASCAL WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR     lpCmdLine,
                   int       nCmdShow)
{
	// 初始化游戏引擎
	if( !CSystem::InitGameEngine( hInstance, lpCmdLine ) )
		return 0;

	// To do : 在此使用API更改窗口标题
	CSystem::SetWindowTitle("LessonX");

	// 引擎主循环,处理屏幕图像刷新等工作
	while( CSystem::EngineMainLoop() )
	{
		// 获取两次调用之间的时间差,传递给游戏逻辑处理
		float	fTimeDelta	=	CSystem::GetTimeDelta();

		// 执行游戏主循环
		g_GameMain.GameMainLoop( fTimeDelta );
	};

	// 关闭游戏引擎
	CSystem::ShutdownGameEngine();
	return 0;
}

//==========================================================================
//
// 引擎捕捉鼠标移动消息后,将调用到本函数
void CSystem::OnMouseMove( const float fMouseX, const float fMouseY )
{
	// 可以在此添加游戏需要的响应函数
    g_GameMain.OnMouseMove(fMouseX,fMouseY);
}
//==========================================================================
//
// 引擎捕捉鼠标点击消息后,将调用到本函数
void CSystem::OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY )
{
	// 可以在此添加游戏需要的响应函数
    g_GameMain.OnMouseClick(iMouseType,fMouseX,fMouseY);
}
//==========================================================================
//
// 引擎捕捉鼠标弹起消息后,将调用到本函数
void CSystem::OnMouseUp( const int iMouseType, const float fMouseX, const float fMouseY )
{
	// 可以在此添加游戏需要的响应函数

}
//==========================================================================
//
// 引擎捕捉键盘按下消息后,将调用到本函数
// bAltPress bShiftPress bCtrlPress 分别为判断Shift,Alt,Ctrl当前是否也处于按下状态。比如可以判断Ctrl+E组合键
void CSystem::OnKeyDown( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress )
{
	// 可以在此添加游戏需要的响应函数
    g_GameMain.OnKeyDown(iKey,bAltPress,bShiftPress,bCtrlPress);
}
//==========================================================================
//
// 引擎捕捉键盘弹起消息后,将调用到本函数
void CSystem::OnKeyUp( const int iKey )
{
	// 可以在此添加游戏需要的响应函数
}

//===========================================================================
//
// 引擎捕捉到精灵与精灵碰撞之后,调用此函数
void CSystem::OnSpriteColSprite( const char *szSrcName, const char *szTarName )
{

}

//===========================================================================
//
// 引擎捕捉到精灵与世界边界碰撞之后,调用此函数.
// iColSide : 0 左边,1 右边,2 上边,3 下边
void CSystem::OnSpriteColWorldLimit( const char *szName, const int iColSide )
{
     g_GameMain.OnSpriteColWorldLimit(szName,iColSide);
}



三、运行截图




评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值