自己编写的一个小游戏,本来打算做贪吃蛇,结果不会使蛇的身子随蛇头方向改变而改变就换了种想法,最后变成了这样一个另类的小游戏,“笑哭“,下面是程序的主要代码,如果有兴趣也可以下载完整程序代码资源:https://download.csdn.net/download/yt201758501112/10488198。
Lessonx.h
/
//
 //
 //
 //
 /
 #ifndef _LESSON_X_H_
 #define _LESSON_X_H_
 //
 #include <Windows.h>
 #include <stdio.h>
 #include <vector>
 using namespace std;
 /
 //
 // 游戏总管类。负责处理游戏主循环、游戏初始化、结束等工作
 class CGameMain
 {
 private:
 int m_iGameState; // 游戏状态,0:结束或者等待开始;1:初始化;2:游戏进行中
     CSprite * m_pControlSnake;         //定义蛇头部精灵
     CSprite * m_pSnakebody1;            //定义一节蛇身
     CSprite * tmpsprite;             //定义两个中间变量精灵
     CSprite * tmpsprite1;
     vector<CSprite*>  m_pSnakefood;      //定义食物精灵组
     vector<CSprite*>  m_pzhangai;        //定义障碍精灵组
     CTextSprite * m_pStarttext;      //定义开始文本精灵
     CTextSprite * m_pgamescore;      //定义分数文本精灵
     CTextSprite * m_plevel;        //定义级别文本精灵
     CSprite * m_pgameover;          //定义游戏结束时背景精灵
     CSprite * m_pbeijing;          //定义开始时背景精灵
     CTextSprite * m_ptime;         //定义游戏时间文本精灵
     CTextSprite * m_pend1;         //定义文本精灵
     CTextSprite * m_pend2;
     CSound * m_bjmusic;          //定义音效精灵
     CSound * m_eatmusic;
     int m_foodminX;        //定义食物出现的最小X坐标
     int m_foodmaxX;         //定义食物出现的最大X坐标
     int m_foodminY;         //定义食物出现的最小Y坐标
     int m_foodmaxY;         //定义食物出现的最大Y坐标
     int m_foodcount;        //定义食物出现的数目
     int m_zhangaimaxY;      //定义障碍出现的最大Y坐标
     int m_zhangaiminY;      //定义障碍出现的最小Y坐标
     int m_zhangaicount;     //定义障碍出现的数目
     float DeltaTime;        //定义时间
     float speedsnake;       //定义蛇移动的速度
     int weizhi;        //定义需要的变量
     int judge;
     float speedbeijing;
     int t;
     char foodname[1000];      //定义需要存储的数组
     char zhangainame[1000];
     int fenshu;         //定义级别,分数
     int level;
     float mintime,maxtime;
     float basetime;
 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 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 <algorithm>
 #include <cstring>
 #include <time.h>
 #include <stdlib.h>
 #include<windows.h>
 #pragma comment(lib,"winmm.lib")
 
 //
 //
 CGameMain g_GameMain;
 //==============================================================================
 //
 // 大体的程序流程为:GameMainLoop函数为主循环函数,在引擎每帧刷新屏幕图像之后,都会被调用一次。
 //==============================================================================
 //
 // 构造函数
 CGameMain::CGameMain()
 {
 m_iGameState = 0;
 m_pControlSnake =new CSprite("Snake_0");        //导入精灵
 m_pSnakebody1 =new CSprite("snake_1");
 m_pStarttext =new CTextSprite("start");        //导入文本精灵
 m_pgamescore=new CTextSprite("gamescore");
 m_plevel=new CTextSprite("level");
 m_pgameover=new CSprite("gameend");
 m_pbeijing=new CSprite("beijing");
 m_ptime=new CTextSprite("time");
 m_bjmusic=new CSound("bjmusic.wav",1,1);        //导入音乐精灵
 m_eatmusic=new CSound("eatmusic.wav",0,1);
 m_pend1=new CTextSprite("end1");
 m_pend2=new CTextSprite("end2");
 m_foodmaxX=0;          //初始化变量
 m_foodmaxY=0;
 m_foodminX=0;
 m_foodminY=0;
 m_foodcount=0;
 DeltaTime=0;
     speedbeijing=10.f;
     speedsnake=15.f;
     basetime=0.f;
     m_iHook=0;
 weizhi=0;
 judge=1;
 t=0;
 fenshu=0;
 level=1;
 mintime=2.f;
 maxtime=4.f;
 iTime=0;
 }
 //==============================================================================
 //
 // 析构函数
 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 0:
 default:
 break;
 };
 }
 //=============================================================================
 //
 // 每局开始前进行初始化,清空上一局相关数据
 void CGameMain::GameInit()
 {
 }
 //=============================================================================
 //
 // 每局游戏进行中
 void CGameMain::GameRun( float fDeltaTime )
 {
        DeltaTime+=fDeltaTime;       //累加时间来判断是否产生障碍
        basetime+=fDeltaTime;           //累加时间以用来计时
      m_ptime->SetTextValueFloat(basetime);
      if(judge==1)            //判断当蛇头吃到食物时产生新的食物
      {
         sprintf(foodname,"food%d",m_foodcount++);          //改变食物的名字
         tmpsprite=new CSprite(foodname);          //初始化中间精灵
         tmpsprite->CloneSprite("food0");        //克隆初始食物精灵
         m_foodmaxX=31;             //根据原图判断边界坐标
         m_foodminX=-49;
         m_foodmaxY=31;
         m_foodminY=-36;
         int iposX=CSystem::RandomRange(m_foodminX,m_foodmaxX);           //随机产生食物的X坐标
         int iposY=CSystem::RandomRange(m_foodminY,m_foodmaxY);           //随机产生食物的Y坐标
         tmpsprite->SetSpritePosition(iposX,iposY);               //根据随机产生的坐标将精灵置入游戏界面中
         m_pControlSnake->SetSpriteCollisionSend(true);           //设置头部精灵发送信号
         tmpsprite->SetSpriteCollisionReceive(true);            //设置食物精灵接受信号
         judge=0;             //把判断值初始化
      }
      if(DeltaTime>mintime&&DeltaTime<maxtime)             //当达到相应的时间时产生一障碍
      {
          sprintf(zhangainame,"box%d",m_zhangaicount++);           //改变障碍的名字
          tmpsprite1=new CSprite(zhangainame);            //初始化中间变量精灵
          tmpsprite1->CloneSprite("box0");             //克隆初始障碍
          m_zhangaiminY=-35;             //根据原图判断坐标范围
          m_zhangaimaxY=35;
          int posY=CSystem::RandomRange(m_zhangaiminY,m_zhangaimaxY);             //随机产生Y值
          int posX=50;
          tmpsprite1->SetSpritePosition(posX,posY);             //置入障碍
          tmpsprite1->SetSpriteCollisionReceive(true);               //设置障碍可以接受信号
          tmpsprite1->SetSpriteLinearVelocity(-speedbeijing,0);           //设置障碍的移动速度
          DeltaTime=0;          //初始化变量
      }
      if(fenshu>=50&&fenshu<=100)             //根据分数的不同变化关卡
      {
         speedbeijing=15.f;               //设置第二关障碍,蛇的移动速度
         speedsnake=20.f;
         level=2;          //改变关卡级别
         m_plevel->SetTextValue(level);
         mintime=1.8;         //改变障碍出现的时间间隔
         maxtime=3.6;
        // m_pbeijing->SetSpriteLinearVelocity(speedbeijing,0);
      }
      if(fenshu>100&&fenshu<=150)
      {
          speedbeijing=20.f;         //设置第三关障碍,蛇的移动速度
          speedsnake=25.f;
          level=3;           //改变关卡级别
         m_plevel->SetTextValue(level);
         mintime=1.6;            //改变障碍出现的时间间隔
         maxtime=3.2;
        // m_pbeijing->SetSpriteLinearVelocity(speedbeijing,0);
      }
      if(fenshu>150&&fenshu<=200)
      {
          speedbeijing=25.f;             //设置第四关障碍,蛇的移动速度
          speedsnake=30.f;
          level=4;           //改变关卡级别
         m_plevel->SetTextValue(level);
         mintime=1.4;            //改变障碍出现的时间间隔
         maxtime=2.8;
      //   m_pbeijing->SetSpriteLinearVelocity(speedbeijing,0);
      }
      if(fenshu>200)
      {
          speedbeijing=30.f;             //设置第五关障碍,蛇的移动速度
          speedsnake=35.f;
          level=5;           //改变关卡级别
          m_plevel->SetTextValue(level);
          mintime=1.0;           //改变障碍出现的时间间隔
          maxtime=2;
       //s   m_pbeijing->SetSpriteLinearVelocity(speedbeijing,0);
      }
 }
 //=============================================================================
 //
 // 本局游戏结束
 void CGameMain::GameEnd()
 {
 }
 //==========================================================================
 //
 // 鼠标移动
 // 参数 fMouseX, fMouseY:为鼠标当前坐标
 void CGameMain::OnMouseMove( const float fMouseX, const float fMouseY )
 {
 }
 //==========================================================================
 //
 // 鼠标点击
 // 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
 // 参数 fMouseX, fMouseY:为鼠标当前坐标
 void CGameMain::OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY )
 {
 }
 //==========================================================================
 //
 // 鼠标弹起
 // 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
 // 参数 fMouseX, fMouseY:为鼠标当前坐标
 void CGameMain::OnMouseUp( const int iMouseType, const float fMouseX, const float fMouseY )
 {
 }
 //==========================================================================
 //
 // 键盘按下
 // 参数 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 && 0 == GetGameState() )
 {
 SetGameState( 1 );
         m_pStarttext->SetSpriteVisible(false);          //设置当按下空格时开始文本精灵消失
     }
     float fSpeedX=0.f,fSpeedY=0.f;
     float fdirector=0.f;
     switch(iKey)             //设置按键对蛇头精灵速度的影响
     {
         case KEY_W:
             fSpeedY=-speedsnake;
             fdirector=270.f;
             break;
         case KEY_A:
             fSpeedX=-speedsnake;
             fdirector=180.f;
             break;
         case KEY_S:
             fSpeedY=speedsnake;
             fdirector=90.f;
             break;
         case KEY_D:
             fSpeedX=speedsnake;
             fdirector=0.f;
             break;
     };
     m_pControlSnake->SetSpriteLinearVelocity(fSpeedX, fSpeedY);       //改变蛇头的速度
     m_pControlSnake->SetSpriteRotation(fdirector);            //改变蛇头的朝向
 }
 //==========================================================================
 //
 // 键盘弹起
 // 参数 iKey:弹起的键,值见 enum KeyCodes 宏定义
 void CGameMain::OnKeyUp( const int iKey )
 {
 }
 //==========================================================================
 //
 // 精灵与精灵碰撞
 // 参数 szSrcName:发起碰撞的精灵名字
 // 参数 szTarName:被碰撞的精灵名字
 void CGameMain::OnSpriteColSprite( const char *szSrcName, const char *szTarName)
 {
     if(stricmp("snake_0",szSrcName)==0&&stricmp(foodname,szTarName)==0)           //当蛇头与食物碰撞时
     {
         weizhi=weizhi-2;
         tmpsprite->SpriteMountToSprite("snake_0",weizhi,0);           //将食物接在蛇头后面
         judge=1;             //改变判断变量
         fenshu+=10;          //改变分数
         m_pgamescore->SetTextValue(fenshu);
         PlaySound("E:\\eatmusic.wav",0,SND_FILENAME|SND_ASYNC);        //播放吃食物的音效
     }
     else
         judge=0;
     if(stricmp("snake_0",szSrcName)==0&&stricmp(foodname,szTarName)!=0)             //当蛇头与障碍碰撞时
     {
         m_pControlSnake->DeleteSprite();              //删除蛇头与蛇身
         m_pgameover->SetSpritePosition(0,0);          //导入游戏结束界面
         m_pgameover->SetSpriteVisible(true);
         m_pend1->SetSpritePosition(-2.5,0);           //导入游戏终结文本
         m_pend2->SetSpritePosition(-4.9,6);
         m_pend2->SetTextValue(fenshu);
     }
 }
 //===========================================================================
 //
 // 精灵与世界边界碰撞
 // 参数 szName:碰撞到边界的精灵名字
 // 参数 iColSide:碰撞到的边界 0 左边,1 右边,2 上边,3 下边
 void CGameMain::OnSpriteColWorldLimit( const char *szName, const int iColSide )
 {
     if(stricmp(szName,"snake_0")==0&&iColSide==0)             //设置当蛇头碰到边界时结束游戏
     {
         m_pControlSnake->DeleteSprite();
         m_pgameover->SetSpritePosition(0,0);
         m_pgameover->SetSpriteVisible(true);
         m_pend1->SetSpritePosition(-2.5,0);
         m_pend2->SetSpritePosition(-4.9,6);
         m_pend2->SetTextValue(fenshu);
     }
     if(stricmp(szName,"snake_0")==0&&iColSide==1)
     {
         m_pControlSnake->DeleteSprite();
         m_pgameover->SetSpritePosition(0,0);
         m_pgameover->SetSpriteVisible(true);
         m_pend1->SetSpritePosition(-2.5,0);
         m_pend2->SetSpritePosition(-4.9,6);
         m_pend2->SetTextValue(fenshu);
     }
     if(stricmp(szName,"snake_0")==0&&iColSide==2)
     {
         m_pControlSnake->DeleteSprite();
         m_pgameover->SetSpritePosition(0,0);
         m_pgameover->SetSpriteVisible(true);
         m_pend1->SetSpritePosition(-2.5,0);
         m_pend2->SetSpritePosition(-4.9,6);
         m_pend2->SetTextValue(fenshu);
     }
     if(stricmp(szName,"snake_0")==0&&iColSide==3)
     {
         m_pControlSnake->DeleteSprite();
         m_pgameover->SetSpritePosition(0,0);
         m_pgameover->SetSpriteVisible(true);
         m_pend1->SetSpritePosition(-2.5,0);
         m_pend2->SetSpritePosition(-4.9,6);
         m_pend2->SetTextValue(fenshu);
     }
 }