PopCap地图卷动(一)

本文详细阐述了游戏开发中地图滚动的实现方法,包括窗口、关卡、地图及飞机等元素的绘制与移动逻辑,以及如何通过关卡管理器进行地图的动态更新与平移。介绍了窗口、关卡、地图的尺寸设定,飞机在地图上的移动速度与窗口的移动速度对比,以及地图滚动的原理与代码实现细节。

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

 

 

 

窗口:宽 550   高 650

 

关卡:宽 700   高 3000

 

地图:宽 800   高 2400

 

飞机:宽 64    高 58

 

 

源代码下载地址:

 

http://cid-620792b9d0909341.skydrive.live.com/self.aspx/.Public/src/PopCap%e5%9c%b0%e5%8d%b7%e5%8a%a8%ef%bc%88%e4%b8%80%ef%bc%89.rar

 

 

因为飞机在地图上的移动速度是2,窗体在地图上的移动速度是1

 

 

窗体的X 值是0 ~ 150 ,飞机在地图中的X 值是0 ~ 636 ,所以当地图到达关卡边界时飞机动不了,但飞机还是可以横向移动。

 

CLevelMgr::Draw()  

 

 

        if( mBackImagePos + G_WINDOW_HEIGHT < Img_Hight )  

              // 从地图y = 0 的位置绘制650 的长度

              // 第一次绘制,从地图的y = 0 开始画650 的长度(窗口高)  // mBackImagePos = 0  

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

              G_WINDOW_WIDTH, G_WINDOW_HEIGHT ) );

 

 

 

        else

               // 从地图y = 2398 的位置绘制2 的长度,然后再从地图y = 0 的位置绘制650 - 2 = 648 的长度

               // 第二次绘制,是在CLevelMgr::Update() 函数执行后(具体是执行两次后)  // mBackImagePos = 2398 

 

               // CLevelMgr::Update()

 

               // mBackImagePos -= SCROLL_SPEED;

               // if( mBackImagePos < 0 )

               // {

 

               //         mBackImagePos = Img_Hight - 1;

 

               // }

 

 

 

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

                                       G_WINDOW_WIDTH, Img_Hight - mBackImagePos ) );

 

 

 

               g->DrawImageF( mWidget->mApp->mBackImage, 0, Img_Hight - mBackImagePos,

                                       Rect(  mBackPos.mX, 0, G_WINDOW_WIDTH,  

                                       G_WINDOW_HEIGHT - ( Img_Hight - mBackImagePos )) );

 

 

 

 

CLevelMgr( CWidget *widget )

        mBackImagePos = 0;         // 关卡负责绘制地图,就是从mBackImagePos (指的是y 轴的位置) 开始画一个窗口的长度 

 

        mBackPos.mX = ( 700 - 550  ) / 2;    // 75    // 窗体在地图上的位置;关卡左上角那个点位于地图的( 75,  2350 ) 

        mBackPos.mY =  3000 - 650;     // 2350   

 

 

 

CPlayer::Init()

 

        mProperty.mColRect.mWidth  = 64;

        mProperty.mColRect.mHeight = 58;

 

 

 

        mProperty.mMapPos.mX = ( 700 - 64 ) / 2;  // 318    // 窗口x 轴的中心,y 轴的底部

 

        mProperty.mMapPos.mY =  3000 - 58;        // 2942   // 飞机左上角那个点位于地图的( 318, 2942 )

 

 

        mProperty.mCVX =   // the const x speed  // 2        // 移动速度

        mProperty.mCVY =   // the const y speed  // 2

 

 

 

CWidget::Update()

 

        mLevelMgr->Update();

        mPlayer->Update();

        MarkDirty();

 

 

 

// 关卡管理器会更新飞机在地图中的位置

CLevelMgr::Update()

 

        // 此函数是放在CWidget::Update() 里面的,每秒被调用100 次

 

 

 

        // 这几行代码保证在它后面的代码每次只执行5 次

        mUpdateCnt ++;

        if( mUpdateCnt < 100 / UPDATE_FPS )  // enum UPDATE_FPS= 20

                return false;

 

 

 

        mUpdateCnt = 0;

        mBackPos.mY -= SCROLL_SPEED;  // enum SCROLL_SPEED= 1  // 更新窗体在地图中的位置

        mWidget->mPlayer->mProperty.mMapPos.mY -= SCROLL_SPEED;  // 更新飞机在地图中的位置

 

 

 

        mBackImagePos -= SCROLL_SPEED;  // 更新地图的绘制位置,实现向下卷动 

        if( mBackImagePos < 0 )

        {

                mBackImagePos = Img_Hight - 1;

        }

 

 

 

        mDistance += SCROLL_SPEED;  // 飞机移动的总距离

 

 

 

 

CPlayer::Update()

 

        // 飞机在窗体上的坐标  =  飞机的地图坐标  - 窗体的地图地标

        LevelPosToScrPos( mWidget->mLevelMgr->GetBackPos().mX, mWidget->mLevelMgr->GetBackPos().mY );

        mProperty.mScrPos.mX = mProperty.mMapPos.mX - mapX;  

        mProperty.mScrPos.mY = mProperty.mMapPos.mY - mapY;  

 

 

 

        // 键盘按键处理

        bool bLeftKeyPress = false;

        bool bRightKeyPress= false;

        if( mWidget->mApp->mWidgetManager->mKeyDown[ KEYCODE_LEFT ] )  // 如果按下了左键

        {

                OnLeftKey();

                         // 飞机在地图中的X 坐标 - 2

                        mProperty.mMapPos.mX -= mProperty.mCVX;

                        if( mProperty.mMapPos.mX < 0 )

                                mProperty.mMapPos.mX = 0;

 

 

 

                        // 窗体在地图中的X 坐标 - 1

                        mWidget->mLevelMgr->SetBackPosX( -1 );

                                mBackPos.mX += xadd; // -1

 

 

 

                                if( mBackPos.mX < 0 )

                                        mBackPos.mX = 0;

                                if( mBackPos.mX > mLevelWidth - G_WINDOW_WIDTH )   // 窗体的X 方向只能在关卡管理器中移动,

                                                                        // 窗体的X 值是0 ~ 150 (从150 画一个窗口的宽度 =700,不能再大了)

                                        mBackPos.mX = mLevelWidth - G_WINDOW_WIDTH;

 

                bLeftKeyPress = true;

        }

 

 

        if( mWidget->mApp->mWidgetManager->mKeyDown[ KEYCODE_RIGHT ] )  // 如果按下了右键

        {

                OnRightKey();

                        // 飞机在地图中的X 坐标 + 2

                        mProperty.mMapPos.mX += mProperty.mCVX;

                        if( mProperty.mMapPos.mX > mWidget->mLevelMgr->mLevelWidth - mProperty.mColRect.mWidth)  //

                                                   //  飞机在地图中的X 值是0 ~ 636 (从636 画一个飞机的宽度 =700,不能再大了)

                                mProperty.mMapPos.mX = mWidget->mLevelMgr->mLevelWidth - mProperty.mColRect.mWidth;

 

                                // 窗体在地图中的X 坐标 + 1

                                mWidget->mLevelMgr->SetBackPosX( 1 );

                                        mBackPos.mX += xadd; // 1

 

                                        if( mBackPos.mX < 0 )

                                                mBackPos.mX = 0;

                                        if( mBackPos.mX > mLevelWidth - G_WINDOW_WIDTH )   // 窗体的X 方向只能在关卡管理器中移

                                                                      // 动,窗体的X 值是0 ~ 150 (从150 画一个窗口的宽度 =700,不能再大了)

                                                mBackPos.mX = mLevelWidth - G_WINDOW_WIDTH;

 

                bRightKeyPress = true;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值