源代码下载地址:
//////////////////////////////////////////////////////////////////
// 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;
}
//////////////////////////////////////////////////////////////////