飞机在关卡中上下左右移动

 

源码下载地址:

 

http://cid-620792b9d0909341.skydrive.live.com/self.aspx/.Public/src/飞机在关卡中上下左右移动.rar

 

//////////////////////////////////////////////////////////////////
// main.cpp
// 飞机在关卡中上下左右移动

#include <SexyAppBase.h>
#include <WidgetManager.h>
#include <ResourceManager.h>
#include <Widget.h>
#include <Image.h>

#include  <SWTri.h>

#include "res/res.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;

Rect mColRect; //used for collision check

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


// 在窗体上画战争迷雾用这个坐标(mBackPos.mX, mBackFogPos)
// fog1 比fog2 下降的速度快两倍
// fog1 和fog2 使用的是同一张图片
int     mBackFogPos  = 0;  // fog 1
int     mBackFogPos2 = 0;  // fog 2

// 窗体在关卡中的位置
// 实际上,在窗体上画地图是用这个坐标(mBackPos.mX, mBackImagePos)
Point mBackPos;

typedef TPoint<float> fPoint;


// player
fPoint  mMapPos;       // 飞机在关卡中的位置
fPoint  mScrPos;       // 飞机在窗口中的位置
const float mCVX = 2;  // 飞机X 速度
const float mCVY = 2;  // 飞机Y 速度


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()
{

    //you must call this to enable all the transform function
    SWTri_AddAllDrawTriFuncs();

    //first, it should load resouces
    LoadResourceManifest();
    mResourceManager->StartLoadResources("Game");

    while (mResourceManager->LoadNextResource())
    {
        mCompletedLoadingThreadTasks++;

        //mLoadingWidget->MarkDirty();
    }

    if (mResourceManager->HadError() || !ExtractGameResources(mResourceManager))
    {
        ASSERT(false);
        ShowResourceError(false);
        mLoadingFailed = true;

        return;
    }

    mMapImg = (Image*)GetImage("./data/images/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 

    mBackFogPos  = 0;

    mUpdateCnt = 0;

 


    // 初始化飞机数据

    mColRect.mWidth = 64;
    mColRect.mHeight = 58;

    // 飞机在关卡的位置
    mMapPos.mX = ( LevelWidth - mColRect.mWidth ) / 2;  // 关卡中间
    mMapPos.mY =  LevelHeight - mColRect.mHeight;  // 关卡底部
}

CWidget::~CWidget()
{

}

void    CWidget::Draw( Graphics *g )
{
    // 清屏,否则会有重影
    g->SetColor( Color( 0, 0, 0 ) );
    g->FillRect( 0, 0, mWidth, mHeight );


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

    // fog

    if (mBackFogPos + G_WINDOW_HEIGHT <= BACK_FOG->GetHeight())
    { 
        // X 值用mBackPos.mX 而不是0,因为要保证这张图与地图的相对位置固定不变
        g->DrawImageF( BACK_FOG, 0, 0, Rect( mBackPos.mX, mBackFogPos,  
            G_WINDOW_WIDTH, G_WINDOW_HEIGHT ) );
    }
    else
    {
        g->DrawImageF( BACK_FOG, 0, 0, Rect( mBackPos.mX, mBackFogPos,
            G_WINDOW_WIDTH,  BACK_FOG->GetHeight() - mBackFogPos) );

        g->DrawImageF( BACK_FOG, 0, BACK_FOG->GetHeight() - mBackFogPos, Rect( mBackPos.mX, 0,
            550,  G_WINDOW_HEIGHT - (BACK_FOG->GetHeight() - mBackFogPos) ) );
    }


    // fog 2

    if (mBackFogPos2 + G_WINDOW_HEIGHT <= BACK_FOG->GetHeight())
    { 
        // X 值用mBackPos.mX 而不是0,因为要保证这张图与地图的相对位置固定不变
        g->DrawImageF( BACK_FOG, 0, 0, Rect( mBackPos.mX, mBackFogPos2,  
            G_WINDOW_WIDTH, G_WINDOW_HEIGHT ) );
    }
    else
    {
        g->DrawImageF( BACK_FOG, 0, 0, Rect( mBackPos.mX, mBackFogPos2,
            G_WINDOW_WIDTH,  BACK_FOG->GetHeight() - mBackFogPos2) );

        g->DrawImageF( BACK_FOG, 0, BACK_FOG->GetHeight() - mBackFogPos2, Rect( mBackPos.mX, 0,
            550,  G_WINDOW_HEIGHT - (BACK_FOG->GetHeight() - mBackFogPos2) ) );
    }


    // Player
    // 飞机要画在窗体的中间,X 坐标是窗体宽度的半 - 飞机宽度的一半

    g->DrawImage( PLAYER_IMAGE,  mScrPos.mX/*(G_WINDOW_WIDTH - mColRect.mWidth) / 2*/, mScrPos.mY, Rect(0,0,64,58) );

    //g->DrawImage( mResMgr.mImage, mProperty.mScrPos.mX, mProperty.mScrPos.mY, Rect(0,0,64,58) );
}

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()

    // 更新飞机在关卡中的X 位置
    mMapPos.mX -= mCVX;
    if( mMapPos.mX < 0 )
        mMapPos.mX = 0;

    // 更新
    SetBackPosX( -1 );

}

void OnRightKey()
{
    // 更新飞机在关卡中的X 位置
    mMapPos.mX += mCVX;
    if(  mMapPos.mX >  LevelWidth - mColRect.mWidth)
        mMapPos.mX = LevelWidth - mColRect.mWidth;
 
    SetBackPosX( 1 );
}

void OnUpKey()
{
    // 飞机在关卡中的Y 位置是不能小于窗口在关卡中的Y 位置的
    // 这里,让飞机最小到窗口的 1 / 5 处
    if( mMapPos.mY > mBackPos.mY + G_WINDOW_HEIGHT / 5 )
        mMapPos.mY -= 2;
}

void OnDownKey()
{
    // 飞机在关卡中的Y 位置是不能大于窗口在关卡中的Y 位置 + 一个窗口的高 - 飞机高度
    if( mMapPos.mY < mBackPos.mY + G_WINDOW_HEIGHT - mColRect.mHeight )
        mMapPos.mY += 2; 
}

void LevelPosToScrPos( int mapX, int mapY )
{
    // 窗体在关卡中的坐标 - 飞机在关卡中的坐标 = 飞机在窗口中的坐标
    mScrPos.mX = mMapPos.mX - mapX;
    mScrPos.mY = mMapPos.mY - mapY;
}

void CWidget::Update()
{  
    Widget::Update();

    // 按键处理每秒一百次
    if( mApp->mWidgetManager->mKeyDown[ KEYCODE_LEFT ] )
    {
        OnLeftKey();
    }  

    if( mApp->mWidgetManager->mKeyDown[ KEYCODE_RIGHT ] )
    {
        OnRightKey();
    }

    if( mApp->mWidgetManager->mKeyDown[ KEYCODE_UP ] )
    {
        OnUpKey();
    }

    if( mApp->mWidgetManager->mKeyDown[ KEYCODE_DOWN ] )
    {
        OnDownKey();
    }


    // 计算飞机在窗口中的位置
    LevelPosToScrPos(mBackPos.mX,mBackPos.mY );

    // 地图位置更新每秒 5次
    mUpdateCnt ++;
    if( mUpdateCnt >= 100 / UPDATE_FPS)
    {
        mUpdateCnt = 0;

        mBackImagePos -= SCROLL_SPEED;

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

        // fog
        mBackFogPos -= SCROLL_SPEED * 2;
        if( mBackFogPos < 0 )
        {
            mBackFogPos = BACK_FOG->GetHeight() - 1;
        }

        // fog1
        mBackFogPos2 -= SCROLL_SPEED * 3;
        if( mBackFogPos2 < 0 )
        {
            mBackFogPos2 = BACK_FOG->GetHeight() - 1;
        }

    }

    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、付费专栏及课程。

余额充值