funcode实验--海底世界(c++实现)

4 篇文章 7 订阅

C++语言课程设计一海底世界

一、实验内容

海底有若干条鱼,其中若干条相同的鱼向一个方向游动,另一条来回随机游动,由玩家用键盘W A S D控制另外一条游动。

要求如下:

1、 来回游动的鱼,从屏幕左边游进来,均已一个随机速度水平游动。从屏幕右侧游出去,很快又从屏幕右侧游出来,就这样来回游动。

2、 玩家用WASD键控制一条鱼向上、左、下、右方向游动。松开按键时,玩家的鱼就停止游动。

3、 玩家的鱼游到屏幕边界时,不能继续往前游。

(下载地址:点击打开链接

二、实验代码

LessonX.h

/
//
//
//
//
/
#ifndef _LESSON_X_H_
#define _LESSON_X_H_
//
#include <Windows.h>
#include<vector>
using namespace std;

/
//
// 游戏总管类。负责处理游戏主循环、游戏初始化、结束等工作
class	CGameMain
{
private:
    CSprite*	m_pMyFish;
    CSprite*	yu1;
    int				m_iGameState;				// 游戏状态,0:结束或者等待开始;1:初始化;2:游戏进行中
    CSprite*		m_pFish;
    float		m_fScreenLeft	;	// 屏幕左边界值
    float		m_fScreenRight	;	// 屏幕右边界值
    float		m_fScreenTop	;	// 屏幕上边界值
    float		m_fScreenBottom	;	// 屏幕下边界值
    vector<CSprite*>	m_vFish;
    float		m_fSpeedLeft	;// 鱼4个方向的速度
    float		m_fSpeedRight	;
    float		m_fSpeedTop		;
    float		m_fSpeedBottom;
    void			Swimming();


public:
    void			OnKeyUp( const int iKey );
    void			OnKeyDown( const int iKey, const int iAltPress, const int iShiftPress, const int iCtrlPress );
    CSprite*		FindSpriteByName(const char* szName, const int iColSide);
    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			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"

//
//
CGameMain		g_GameMain;

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

//==============================================================================
//
// 构造函数
CGameMain::CGameMain()
{
    m_pFish=new CSprite("yu_0");
    yu1=new CSprite("yu1");
    m_iGameState			=	1;


    m_pMyFish=new CSprite("kongzhiyu");
    m_fSpeedBottom=	0.f;
    m_fSpeedLeft=	0.f;
    m_fSpeedRight=	0.f;
    m_fSpeedTop=	0.f;


}
//==============================================================================
//
// 析构函数
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()
{
    // 获取屏幕的边界值
    m_fScreenLeft = CSystem::GetScreenLeft();
    m_fScreenRight = CSystem::GetScreenRight();
    m_fScreenTop = CSystem::GetScreenTop();
    m_fScreenBottom = CSystem::GetScreenBottom();

    // 设置精灵世界边界
    m_pFish->SetSpriteWorldLimit(WORLD_LIMIT_NULL, m_fScreenLeft, m_fScreenTop, m_fScreenRight, m_fScreenBottom);
    m_pFish->SetSpriteLinearVelocity( 15, 0);
    yu1->SetSpriteLinearVelocity( 15, 0);
    yu1->SetSpriteWorldLimit(WORLD_LIMIT_NULL, m_fScreenLeft, m_fScreenTop, m_fScreenRight, m_fScreenBottom);



    for(int i=0; i<4; i++)
    {

        char  szName[128];
        float fPosX, fPosY;
        float fSpeedX;
//将szName的值赋为”fish”加I,级循环因子
        sprintf(szName, "fish%d",i);
        CSprite* tmpSprite=new CSprite(szName);
        tmpSprite->CloneSprite("yu1");//创建精灵

        fPosX = CSystem::RandomRange(m_fScreenLeft+10.f, m_fScreenRight-10.f);
        fPosY = CSystem::RandomRange(m_fScreenTop+10.f,m_fScreenBottom-10.f);
        tmpSprite->SetSpritePosition(fPosX, fPosY);
        tmpSprite->SetSpriteWorldLimit(WORLD_LIMIT_NULL, m_fScreenLeft-20.f, m_fScreenTop, m_fScreenRight+20.f, m_fScreenBottom);

        fSpeedX = CSystem::RandomRange(10, 20);
        tmpSprite->SetSpriteLinearVelocity(fSpeedX, 0);
        m_vFish.push_back(tmpSprite);

    }


}
//=============================================================================
//
// 每局游戏进行中
void CGameMain::GameRun( float fDeltaTime )
{
    //m_pFish->SetSpriteLinearVelocity(30, 30);
}
//=============================================================================
//
// 本局游戏结束
void CGameMain::GameEnd()
{
}
void CGameMain::OnSpriteColWorldLimit( const char *szName, const int iColSide )
{
    bool	bFlip;
    float	fSpeedX;
    if(strcmp(szName, "yu_0")==0)
    {
        if(iColSide == 1)  // 右边
        {
            bFlip = true;
            fSpeedX = -15.f;
            m_pFish->SetSpriteLinearVelocity(fSpeedX, 0);
            m_pFish->SetSpriteFlipX( bFlip);
        }

        else if(iColSide == 0)   // 左边
        {
            bFlip = false;
            fSpeedX = 15.f;
            m_pFish->SetSpriteLinearVelocity(fSpeedX, 0);
            m_pFish->SetSpriteFlipX( bFlip);
        }

    }

}
CSprite* CGameMain::FindSpriteByName(const char* szName, const int iColSide)
{
    for(int i=0; i<m_vFish.size(); i++)
        if(strcmp(szName,m_vFish[i]->GetName())==0)
            return m_vFish[i];
    bool	bFlip;
    float	fSpeedX;
    float fPosY;
    if(strstr(szName,"fish2") != NULL)
    {
        if(iColSide == 1)  // 右边
        {
            bFlip = true;
            fSpeedX = -CSystem::RandomRange(10, 20);
        }

    }

    else if(iColSide == 0)   // 左边
    {
        bFlip = false;
        fSpeedX = CSystem::RandomRange(10, 20);
    }
    CSprite* tmpSprite=FindSpriteByName(szName,iColSide);
    tmpSprite->SetSpriteFlipX(bFlip);
    tmpSprite->SetSpriteLinearVelocity(fSpeedX, 0);
    fPosY=CSystem::RandomRange(m_fScreenTop+10.f,
                               m_fScreenBottom-10.f);
    //因为有不同的鱼,因此随机生成Y方向的速度后需要分配给不同的
    //鱼,这样多条鱼就不会重复了
    tmpSprite->SetSpritePositionY(fPosY);



}
void CGameMain::OnKeyDown( const int iKey, const int iAltPress, const int iShiftPress, const int iCtrlPress )
{

    switch(iKey)
    {
    case KEY_W:
        m_fSpeedTop = -10.f;
        break;
    case KEY_A:
        m_fSpeedLeft = -15.f;
        break;
    case KEY_S:
        m_fSpeedBottom = 10.f;
        break;
    case KEY_D:
        m_fSpeedRight = 15.f;
        break;
    }
    Swimming();


}

void CGameMain::OnKeyUp( const int iKey )
{

    switch(iKey)
    {
    case KEY_W:
        m_fSpeedTop = 0.f;
        break;
    case KEY_A:
        m_fSpeedLeft = 0.f;
        break;
    case KEY_S:
        m_fSpeedBottom = 0.f;
        break;
    case KEY_D:
        m_fSpeedRight = 0.f;
        break;
    }
    Swimming();
}
void CGameMain::Swimming()
{
    if((m_fSpeedLeft + m_fSpeedRight) > 0)
        m_pMyFish->SetSpriteFlipX(false);
    else if((m_fSpeedLeft + m_fSpeedRight) < 0)
        m_pMyFish->SetSpriteFlipX(true);

    m_pMyFish->SetSpriteLinearVelocity( m_fSpeedLeft + m_fSpeedRight, m_fSpeedTop + m_fSpeedBottom);

}


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 )
{
    // 可以在此添加游戏需要的响应函数

}
//==========================================================================
//
// 引擎捕捉鼠标点击消息后,将调用到本函数
void CSystem::OnMouseClick( const int iMouseType, const float fMouseX, const float 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 )
{
    // 可以在此添加游戏需要的响应函数
    g_GameMain.OnKeyUp(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);
}


三、运行结果


(下载地址:点击打开链接


  • 17
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值