Funcode实现打飞虫1

前言:

        1、相较于文档给出的,优化了单身二十年手速所造成的问题(包括中心点问题)

        2、优化了连续点击拍子的效果不佳的问题

效果图:

精灵总览

背景图层数设置为0

空格开始

倒计时

拍子

 分数

 时间

 蚊子

 名字

 代码:

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;
}

//==========================================================================
//
// 引擎捕捉鼠标移动消息后,将调用到本函数
// 参数 fMouseX, fMouseY:为鼠标当前坐标
//
void CSystem::OnMouseMove( const float fMouseX, const float fMouseY )
{
	// 可以在此添加游戏需要的响应函数
	g_GameMain.OnMouseMove(fMouseX, fMouseY);
}
//==========================================================================
//
// 引擎捕捉鼠标点击消息后,将调用到本函数
// 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
// 参数 fMouseX, fMouseY:为鼠标当前坐标
//
void CSystem::OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY )
{
	// 可以在此添加游戏需要的响应函数
	g_GameMain.OnMouseClick(iMouseType, fMouseX, fMouseY);
}
//==========================================================================
//
// 引擎捕捉鼠标弹起消息后,将调用到本函数
// 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
// 参数 fMouseX, fMouseY:为鼠标当前坐标
//
void CSystem::OnMouseUp( const int iMouseType, const float fMouseX, const float fMouseY )
{
	// 可以在此添加游戏需要的响应函数
	g_GameMain.OnMouseUp(iMouseType, fMouseX, fMouseY);
}
//==========================================================================
//
// 引擎捕捉键盘按下消息后,将调用到本函数
// 参数 iKey:被按下的键,值见 enum KeyCodes 宏定义
// 参数 iAltPress, iShiftPress,iCtrlPress:键盘上的功能键Alt,Ctrl,Shift当前是否也处于按下状态(0未按下,1按下)
//
void CSystem::OnKeyDown( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress )
{
	// 可以在此添加游戏需要的响应函数
	g_GameMain.OnKeyDown(iKey, bAltPress, bShiftPress, bCtrlPress);
}
//==========================================================================
//
// 引擎捕捉键盘弹起消息后,将调用到本函数
// 参数 iKey:弹起的键,值见 enum KeyCodes 宏定义
//
void CSystem::OnKeyUp( const int iKey )
{
	// 可以在此添加游戏需要的响应函数
	g_GameMain.OnKeyUp(iKey);
}

//===========================================================================
//
// 引擎捕捉到精灵与精灵碰撞之后,调用此函数
// 精灵之间要产生碰撞,必须在编辑器或者代码里设置精灵发送及接受碰撞
// 参数 szSrcName:发起碰撞的精灵名字
// 参数 szTarName:被碰撞的精灵名字
//
void CSystem::OnSpriteColSprite( const char *szSrcName, const char *szTarName )
{
	// 可以在此添加游戏需要的响应函数
	g_GameMain.OnSpriteColSprite(szSrcName, szTarName);
}

//===========================================================================
//
// 引擎捕捉到精灵与世界边界碰撞之后,调用此函数.
// 精灵之间要产生碰撞,必须在编辑器或者代码里设置精灵的世界边界限制
// 参数 szName:碰撞到边界的精灵名字
// 参数 iColSide:碰撞到的边界 0 左边,1 右边,2 上边,3 下边
//
void CSystem::OnSpriteColWorldLimit( const char *szName, const int iColSide )
{
	// 可以在此添加游戏需要的响应函数
	g_GameMain.OnSpriteColWorldLimit(szName, iColSide);
}

LessonX.h


#ifndef _LESSON_X_H_
#define _LESSON_X_H_
//
#include <Windows.h>
#include <vector>
using namespace std;
/
//
// 游戏总管类。负责处理游戏主循环、游戏初始化、结束等工作
class	CGameMain
{
private:
	int				m_iGameState;				// 游戏状态,0:结束或者等待开始;1:初始化;2表示未开始(此时拍子不随鼠标移动),3 表示倒计时阶段, 4表示开始拍子可以随鼠标移动并拍打

public:
	CGameMain();            //构造函数
	~CGameMain();           //析构函数
    float	m_fRotateTime;		// 拍子拍下后距离复位还差多少时间
    float	m_fOldRotation;		// 拍子的初始角度
    CSprite	 *paizi;
//    int m_iGameState;

    int				countdownTime ;	//倒计时时间
	float			countPassedTime;	//倒计时经过的时间
	CTextSprite		*countdown;		//倒计时的文字精灵
    CSprite			*kaishi;			//“空格开始”精灵
    vector< CSprite *>  m_mosquitos;
    vector< CSprite *>  m_names;
    int		m_iMosquitoCount;
    int					m_iGameScore;		//当前得分
	CTextSprite			*score;			//score精灵
	float			m_fGameTime;		//游戏时间
	CTextSprite		*gameTime;		//游戏时间精灵

    int index = 1;
	// 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 			OnMouseMove( const float fMouseX, const float fMouseY );
	void 			OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY );
	void 			OnMouseUp( const int iMouseType, const float fMouseX, const float fMouseY );
	void 			OnKeyDown( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress );
	void 			OnKeyUp( const int iKey );
	void 			OnSpriteColSprite( const char *szSrcName, const char *szTarName );
	void 			OnSpriteColWorldLimit( const char *szName, const int iColSide );
};

/
//
extern CGameMain	g_GameMain;

#endif // _LESSON_X_H_

LessonX.Cpp

#include <Stdio.h>
#include "CommonClass.h"
#include "LessonX.h"
#include <iostream>
using namespace std;


//
//
CGameMain		g_GameMain;

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

//==============================================================================
//
// 构造函数
CGameMain::CGameMain()
{
	m_iGameState =	1;
	paizi = new CSprite("paizi");
	countdown = new CTextSprite("countdown");
    kaishi = new CSprite("kaishi");
    score = new CTextSprite("score");//实例化得分
    gameTime = new CTextSprite("gameTime");
}
//==============================================================================
//
// 析构函数
CGameMain::~CGameMain()
{
}

//==============================================================================
//
// 游戏主循环,此函数将被不停的调用,引擎每刷新一次屏幕,此函数即被调用一次
// 用以处理游戏的开始、进行中、结束等各种状态.
// 函数参数fDeltaTime : 上次调用本函数到此次调用本函数的时间间隔,单位:秒
void CGameMain::GameMainLoop( float	fDeltaTime )
{
	switch( GetGameState() )
	{
		// 初始化游戏,清空上一局相关数据
	case 1:
		{
			GameInit();
			SetGameState(2); // 初始化之后,将游戏状态设置为进行中
		}
		break;

		// 游戏进行中,处理各种游戏逻辑
	case 2:
		{
			// TODO 修改此处游戏循环条件,完成正确游戏逻辑
			if( true )
			{
				GameRun( fDeltaTime );
			}
			else // 游戏结束。调用游戏结算函数,并把游戏状态修改为结束状态
			{
				SetGameState(0);
				GameEnd();
			}
		}
		break;

        case 3:
    case 4:
    {// TODO 修改此处游戏循环条件,完成正确游戏逻辑
        if( true ){
            GameRun( fDeltaTime );
        }
        else // 游戏结束。调用游戏结算函数,并把游戏状态修改为结束状态
        {
            SetGameState(0);
            GameEnd();
        }
    }

		// 游戏结束/等待按空格键开始
	case 0:
	default:
		break;
	};
}
//=============================================================================
//
// 每局开始前进行初始化,清空上一局相关数据
void CGameMain::GameInit()
{
    CSystem::ShowCursor(false);	//隐藏鼠标
    m_fRotateTime = 0.f;//旋转时间
    m_fOldRotation = paizi->GetSpriteRotation();		//获取拍子的初始角度
    countdownTime = 5;		//倒计时时间为5s
    countPassedTime = 0.f;
    countdown->SetSpriteVisible(false);		//设置倒计时不可见
    m_iMosquitoCount = 15;//蚊子的数量
    m_iGameScore = 0;//将得分设置为0
}
//=============================================================================
//
// 每局游戏进行中
void CGameMain::GameRun( float fDeltaTime )
{
    /*if(m_fRotateTime > 0)	{
		m_fRotateTime -= fDeltaTime;	//每经过fDeltaTime,拍子旋转的时间也少了fDeltaTime
		if(m_fRotateTime <= 0){	//经过了0.2s以后
			paizi->SetSpriteRotation(m_fOldRotation);	//恢复拍子的初始旋转角
		}
	}*/
	if(m_iGameState==3){	//m_iGameState 为3时才执行
		countPassedTime += fDeltaTime;	//统计经过的时间,并存储到countPassedTime
            //思考:countPassedTime 是浮点数,那么为什么countdown -countPassedTime可以显示整数的时间?
		countdown->SetTextValue(countdownTime -countPassedTime);
		if(countPassedTime >= countdownTime){	//经过的时间超过countdownTime
			countdown->SetSpriteVisible(false);	//隐藏countdown
			countPassedTime = 0;		//重置经过的时间,为下一轮游戏做准备
			m_iGameState = 4;		//切换g_iGameState 3->4
			//蚊子的生成是在此处
			//获取最大边界
			int minX		=	CSystem::GetScreenLeft() + 5;
            int maxX		=	CSystem::GetScreenRight() - 5;
            int minY		=	CSystem::GetScreenBottom() - 5;
            int maxY		=	CSystem::GetScreenTop() + 5;
            int	iPosX = 0, iPosY = 0;		//随机产生的横纵坐标位置
            int iLoop;	//循环控制变量
            for( iLoop = 0; iLoop < m_iMosquitoCount; iLoop++ )
            {
                //利用iLoop产生不同的蚊子名
                char *szName = CSystem::MakeSpriteName("wenzi",iLoop);
                CSprite *wenzi = new CSprite(szName);
                wenzi->CloneSprite("wenziTemplate");	//复制wenziTemplate
                iPosX	=	CSystem::RandomRange(minX, maxX);		//随机产生X坐标
                iPosY	=	CSystem::RandomRange(minY, maxY);		//随机产生Y坐标
                wenzi->SetSpritePosition(iPosX,iPosY);  //设置产生蚊子的位置
                if(iLoop%3==0)
                {
                    wenzi->SetSpriteWidth(3.7f);
                    wenzi->SetSpriteHeight(3.7f);
                }else if(iLoop%3==1)
                {
                    wenzi->SetSpriteWidth(5.7f);
                    wenzi->SetSpriteHeight(5.7f);

                }else{
                    wenzi->SetSpriteWidth(7.7f);
                    wenzi->SetSpriteHeight(7.7f);
                }
                m_mosquitos.push_back(wenzi);		//压入vector中集中管理
            }
		}
        } else if(m_iGameState==4){
			m_fGameTime -= fDeltaTime;
			if(m_fGameTime > 0){
				gameTime->SetTextValue(m_fGameTime);	//若游戏时间未结束,则显示剩余的游戏时间
			}else{
				m_iGameState = 2;		//若游戏时间结束,完成g_iGameState 2->0的转换
				kaishi->SetSpriteVisible(true);	//显示“空格开始”
				m_fGameTime = 0;
				paizi->SetSpritePositionX(-0.852f);
				paizi->SetSpritePositionY(-1.000f);
				gameTime->SetTextValue(m_fGameTime);
		}
        }
}
//=============================================================================
//
// 本局游戏结束
void CGameMain::GameEnd()
{
}
//==========================================================================
//
// 鼠标移动
// 参数 fMouseX, fMouseY:为鼠标当前坐标
void CGameMain::OnMouseMove( const float fMouseX, const float fMouseY )
{
    if(m_iGameState==4)
    {
        paizi->SetSpritePosition(fMouseX, fMouseY);	//使拍子的位置和鼠标一致

    }



}
//==========================================================================
//
// 鼠标点击
// 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
// 参数 fMouseX, fMouseY:为鼠标当前坐标
void CGameMain::OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY )
{

   if(iMouseType == MOUSE_LEFT && m_iGameState == 4)	//鼠标左键按下
	{
		paizi->SetSpriteRotation(m_fOldRotation - 10);		//设置拍子的旋转角,为初始值-10
		m_fRotateTime	=	0.2f;	//拍打的时间间隔 0.2s,即0.2s后恢复拍子初始角度
		//遍历判定蚊子是否被击中
		float fX,fY;int flag = -1;
        for(int i=0;i<m_mosquitos.size();i++){		//遍历vector中的蚊子
			fX = m_mosquitos[i]->GetSpritePositionX();	//获取蚊子所的纵坐标
			fY = m_mosquitos[i]->GetSpritePositionY();	//获取蚊子所在

			if(paizi->IsPointInSprite(fX,fY))			//判断蚊子是否在拍子的范围内
			{
                int h = m_mosquitos[i]->GetSpriteHeight();
                int w = m_mosquitos[i]->GetSpriteWidth();
				char *myName = CSystem::MakeSpriteName("names",i);
				CSprite *myNames = new CSprite(myName);
				myNames->CloneSprite("myName");
				myNames->SetSpritePosition(fX,fY);
				myNames->SetSpriteWidth(w+2);
				myNames->SetSpriteHeight(h);
				m_names.push_back(myNames);
                m_mosquitos[i]->DeleteSprite();	//删除该蚊子
				vector<CSprite*>::iterator it = m_mosquitos.erase(m_mosquitos.begin()+i,m_mosquitos.begin()+i+1);
				m_iGameScore++;							//每打一只蚊子加一分
				score->SetTextValue(m_iGameScore);
                break;
			}


		}
	}
}
//==========================================================================
//
// 鼠标弹起
// 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
// 参数 fMouseX, fMouseY:为鼠标当前坐标
void CGameMain::OnMouseUp( const int iMouseType, const float fMouseX, const float fMouseY )
{
    paizi->SetSpriteRotation(m_fOldRotation);
}
//==========================================================================
//
// 键盘按下
// 参数 iKey:被按下的键,值见 enum KeyCodes 宏定义
// 参数 iAltPress, iShiftPress,iCtrlPress:键盘上的功能键Alt,Ctrl,Shift当前是否也处于按下状态(0未按下,1按下)
void CGameMain::OnKeyDown( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress ){
	if( KEY_SPACE == iKey && 2 ==  m_iGameState )	//按下空格且游戏状态为2时
	{
		m_iGameState =	3;	//设置游戏状态进入倒计时,即3
		countdown->SetSpriteVisible(true);	//显示倒计时文本框
		kaishi->SetSpriteVisible(false);		//隐藏“空格开始”
		m_iGameScore = 0.f;		//初始化新一轮游戏分数
		m_fGameTime = 10.f;		//初始化新一轮游戏时间
		score->SetTextValue(m_iGameScore);
		gameTime->SetTextValue(m_fGameTime);
		for(int i=0;i<m_mosquitos.size();i++){	//删除上一轮游戏中剩余的蚊子
			m_mosquitos[i]->DeleteSprite();
		}
		for(int i=0;i<m_names.size();i++)
        {

            m_names[i]->DeleteSprite();
        }
		m_mosquitos.clear();	//清空vector
		m_names.clear();
	}
}
//==========================================================================
//
// 键盘弹起
// 参数 iKey:弹起的键,值见 enum KeyCodes 宏定义
void CGameMain::OnKeyUp( const int iKey )
{

}
//===========================================================================
//
// 精灵与精灵碰撞
// 参数 szSrcName:发起碰撞的精灵名字
// 参数 szTarName:被碰撞的精灵名字
void CGameMain::OnSpriteColSprite( const char *szSrcName, const char *szTarName )
{

}
//===========================================================================
//
// 精灵与世界边界碰撞
// 参数 szName:碰撞到边界的精灵名字
// 参数 iColSide:碰撞到的边界 0 左边,1 右边,2 上边,3 下边
void CGameMain::OnSpriteColWorldLimit( const char *szName, const int iColSide )
{

}

猜你喜欢

转载自blog.csdn.net/m0_59792745/article/details/124444231