用键盘控制地图左右移动

这是一个使用C++实现的程序,通过键盘控制地图在窗口中左右移动。程序使用了SexyAppBase库,图像加载和绘制功能,以及键盘事件处理来实现地图的滚动效果。源代码包括了一个主程序和一个自定义的Widget类,Widget类负责绘制和更新地图位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


源代码下载地址:

http://cid-620792b9d0909341.skydrive.live.com/self.aspx/.Public/src/%e7%94%a8%e9%94%ae%e7%9b%98%e6%8e%a7%e5%88%b6%e5%9c%b0%e5%9b%be%e5%b7%a6%e5%8f%b3%e7%a7%bb%e5%8a%a8.rar

 

 

//////////////////////////////////////////////////////////////////

// main.cpp

// 用键盘控制地图左右移动

 

#include <SexyAppBase.h>

#include <WidgetManager.h>

#include <ResourceManager.h>

#include <Widget.h>

#include <Image.h>

 

#define ASSERT(value) if (!(value)) { _asm{int 3};}

 

using   namespace       Sexy;

 

#pragma comment( lib, "winmm.lib" )

#pragma comment( lib, "wsock32.lib" )

 

#ifdef  _DEBUG

#pragma comment( lib, "SexyAppFramework_D.lib" )

#else

#pragma comment( lib, "SexyAppFramework.lib" )

#endif

 

 

const int Img_Width = 800;

const int Img_Hight = 2400;

 

const int LevelWidth = 700;

const int LevelHeight = 3000;

 

const int G_WINDOW_WIDTH = 550;

const int G_WINDOW_HEIGHT = 650;

 

int mBackImagePos = 0;  // 绘制地图时,取这个做为y 坐标 

 

// 窗体在关卡中的位置

// 实际上,在窗体上画地图是用这个坐标(mBackPos.mX, mBackImagePos)

Point mBackPos;

 

 

int  mUpdateCnt;

enum

{

    SCROLL_SPEED = 1,

    UPDATE_FPS = 20, //20 fps

};

 

class   CApp;

 

class   CWidget : public Widget

{                       

public:

    CWidget( CApp *app );

    ~CWidget();

 

    void    Draw( Graphics *g );

    void    Update();

public:

    CApp    *mApp;

};

 

class CWidget;

 

class   CApp : public SexyAppBase

{

public:

    CApp();

    ~CApp();

 

    virtual void Init();

    virtual void LoadingThreadProc();

    virtual void LoadingThreadCompleted();

 

public:

    Image* mMapImg;

    CWidget* mWidget;

};

 

CApp::CApp()

{

    mWidth  =       G_WINDOW_WIDTH;

    mHeight =       G_WINDOW_HEIGHT;

    mTitle  =       "APP";

    mNoSoundNeeded          = true;

    mAutoEnable3D       = true;

    mMapImg = NULL;

}

 

CApp::~CApp()

{

    mWidgetManager->RemoveWidget(mWidget);

    delete mWidget;

}

 

void CApp::Init()

{

    SexyAppBase::Init();

}

 

void CApp::LoadingThreadProc()

{

    mMapImg = (Image*)GetImage("./image/map");  // /Debug/image/map.jpg  // Debug 目录是生成的EXE 所在目录

    ASSERT(mMapImg != NULL);

}

 

void CApp::LoadingThreadCompleted()

{

    SexyAppBase::LoadingThreadCompleted();

 

    if (mLoadingFailed)

        return;

 

    mWidget = new CWidget(this);

    mWidget->Resize(0, 0, mWidth, mHeight);

    mWidgetManager->AddWidget(mWidget);     

}

 

 

CWidget::CWidget( CApp *app )

{

    mApp = app;

 

    // 窗体位于关卡的中间

    mBackPos.mX = ( LevelWidth - G_WINDOW_WIDTH  ) / 2;  // 75

    mBackPos.mY =   LevelHeight - G_WINDOW_HEIGHT;         // 2350  

 

    mUpdateCnt = 0;

}

 

CWidget::~CWidget()

{

 

}

 

void    CWidget::Draw( Graphics *g )

{

    if (mBackImagePos + G_WINDOW_HEIGHT <= Img_Hight)  // 从图片的y = mBackImagePos 的位置足够画一屏  

    {

        // DrawImageF(img, 窗体坐标x, 窗体坐标y, Rect(图片坐标x, 图片坐标y, 宽, 高) )

        g->DrawImageF( mApp->mMapImg, 0, 0, Rect( mBackPos.mX, mBackImagePos, 

            550, 650 ) );

    }

    else  // 不够一屏,分两次画;先从y = mBackImagePos 画到 2400,然后不足的部分从 y = 0 处开始画

    {

        g->DrawImageF( mApp->mMapImg, 0, 0, Rect( mBackPos.mX, mBackImagePos, 

            550,  Img_Hight - mBackImagePos) );

 

        g->DrawImageF( mApp->mMapImg, 0, Img_Hight - mBackImagePos, Rect( mBackPos.mX, 0, 

            550,  G_WINDOW_HEIGHT - (Img_Hight - mBackImagePos) ) );

    }

}

 

void SetBackPosX( int xadd )

{

    mBackPos.mX += xadd;

 

    if( mBackPos.mX < 0 )

        mBackPos.mX = 0;

    if( mBackPos.mX > LevelWidth - G_WINDOW_WIDTH )

        mBackPos.mX = LevelWidth - G_WINDOW_WIDTH;

}

 

void OnLeftKey()

{

    SetBackPosX( -1 );

}

 

void OnRightKey()

{

 

    SetBackPosX( 1 );

}

 

void CWidget::Update()

{   

    Widget::Update();

 

    // 按键处理每秒一百次

    if( mApp->mWidgetManager->mKeyDown[ KEYCODE_LEFT ] )

    {

        OnLeftKey();

    }   

 

    if( mApp->mWidgetManager->mKeyDown[ KEYCODE_RIGHT ] )

    {

        OnRightKey();

    }

 

 

    // 地图位置更新每秒 5次

    mUpdateCnt ++;

    if( mUpdateCnt >= 100 / UPDATE_FPS)

    {

        mUpdateCnt = 0;

 

        mBackImagePos -= SCROLL_SPEED;

 

        if (mBackImagePos < 0)

        {

            mBackImagePos = Img_Hight - 1;  // 注意不是2400,如果把地图圈成一个圆圈,y = 0 和 y = 2400 是同一个位置

        }

 

    }

 

    MarkDirty();

}

 

 

int     WINAPI  WinMain( HINSTANCE      hInstance, HINSTANCE    hPrevInstance, 

                        LPSTR   lpCmdLine, int nCmdShow )

{

 

    gHInstance      =       hInstance;

 

    CApp    *app    =       new     CApp();

 

    app->Init();

    app->Start();

 

    delete  app;

 

    return 0;

}

 

//////////////////////////////////////////////////////////////////

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值