实现超级玛丽上下左右运动
生活随笔
收集整理的這篇文章主要介紹了
实现超级玛丽上下左右运动
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
用Cocos2dx實現超級瑪麗,首先用幀循環定時器判斷方向,再在類中實現運行以及判斷是否能運動。
方向控制
void LayerGame::moveMario(float dt) { #ifdef WIN32short key;key = GetKeyState('F');if (key < 0) _marioDir = Common::RIGHT;key = GetKeyState('D');if (key < 0) _marioDir = Common::LEFT;key = GetKeyState('J');if (key < 0)_mario->jump();#endifif (_marioDir==Common::LEFT){//CCLog("left\n");_marioDir=Common::NONE;_mario->moveLeft(dt);}else if(_marioDir==Common::RIGHT){//CCLog("right\n");_marioDir=Common::NONE;_mario->moveRight(dt);}else{//CCLog("stop\n");_menuShow->setTexture(_textureDirNone);_mario->stop();}_mario->moveUp(dt);_mario->moveDown(dt); }判斷是否能向上,向左,向右,向下運動,利用碰撞檢測
bool Mario::canMoveLeft(float dt) {//judge if mario is out of the mapCCRect rcMario=this->boundingBox();CCPoint ptMario=ccp(rcMario.getMinX(),rcMario.getMinY());CCTMXTiledMap *map=getMap();CCPoint ptMarioInWorld=map->convertToWorldSpace(ptMario);if (ptMarioInWorld.x-dt*_speed<0) {return false;}//judge if partition by a wallCCPoint pt[3];pt[0] = ccp(rcMario.getMinX() - dt*_speed, rcMario.getMidY());pt[1] = ccp(rcMario.getMinX() - dt*_speed, rcMario.getMinY());pt[2] = ccp(rcMario.getMinX() - dt*_speed, rcMario.getMaxY());//transform position,change pt into tile and get gid to decide whether be stoped by wallfor(int i=0;i<3;i++){if (pt[i].y >= map->getContentSize().height)continue;CCPoint ptTile=Common::Point2Tile(map,pt[i]);//wall water pipe and floorstatic const char* layerName[3] = { "block", "pipe", "land" };for(int j=0;j<3;j++){CCTMXLayer *layer=map->layerNamed(layerName[j]);int gid=layer->tileGIDAt(ptTile);if (gid!=0){return false;}}}return true; } bool Mario::canMoveRight(float dt) {CCRect rcMario = boundingBox();CCTMXTiledMap* map = getMap();CCPoint pt[3];pt[0] = ccp(rcMario.getMaxX() + dt*_speed, rcMario.getMidY());pt[1] = ccp(rcMario.getMaxX() + dt*_speed, rcMario.getMinY());pt[2] = ccp(rcMario.getMaxX() + dt*_speed, rcMario.getMaxY());// 坐標轉換,將pt轉化成地圖格子坐標,然后獲取gid,判斷gid是不是被阻擋for (int i = 0; i < 3; ++i){if (pt[i].y >= map->getContentSize().height)continue;CCPoint ptTile = Common::Point2Tile(map, pt[i]);// 水管、磚頭,地板static const char* layerName[3] = { "block", "pipe", "land" };for (int j = 0; j < 3; ++j){CCTMXLayer* layer = map->layerNamed(layerName[j]);int gid = layer->tileGIDAt(ptTile);if (gid != 0){return false;}}}return true; } bool Mario::canMoveDown(float dt) {CCRect rcMario = boundingBox();CCTMXTiledMap* map = getMap();CCPoint pt[3];//dt*_speedDownpt[0] = ccp(rcMario.getMidX(), rcMario.getMinY() - dt*_speedDown);pt[1] = ccp(rcMario.getMinX(), rcMario.getMinY() - dt*_speedDown);pt[2] = ccp(rcMario.getMaxX(), rcMario.getMinY() - dt*_speedDown);if (pt[0].y >= map->getContentSize().height)return true;// 坐標轉換,將pt轉化成地圖格子坐標,然后獲取gid,判斷gid是不是被阻擋for (int i = 0; i < 3; ++i){CCPoint ptTile = Common::Point2Tile(map, pt[i]);// 水管、磚頭,地板static const char* layerName[3] = { "block", "pipe", "land" };for (int j = 0; j < 3; ++j){CCTMXLayer* layer = map->layerNamed(layerName[j]);int gid = layer->tileGIDAt(ptTile);if (gid != 0){// 微調CCPoint ptLB = Common::Tile2PointLB(map, ptTile+ccp(0, -1));this->setPositionY(ptLB.y);return false;}}}return true; } bool Mario::canMoveUp(float dt) {CCRect rcMario = boundingBox();CCTMXTiledMap* map = getMap();CCPoint pt[3];pt[0] = ccp(rcMario.getMidX(), rcMario.getMaxY() + dt*_speedUp);pt[1] = ccp(rcMario.getMinX(), rcMario.getMaxY() + dt*_speedUp);pt[2] = ccp(rcMario.getMaxX(), rcMario.getMaxY() + dt*_speedUp);if (pt[0].y >= map->getContentSize().height)return true;// 坐標轉換,將pt轉化成地圖格子坐標,然后獲取gid,判斷gid是不是被阻擋for (int i = 0; i < 3; ++i){CCPoint ptTile = Common::Point2Tile(map, pt[i]);// 水管、磚頭,地板static const char* layerName[3] = { "block", "pipe", "land" };for (int j = 0; j < 3; ++j){CCTMXLayer* layer = map->layerNamed(layerName[j]);int gid = layer->tileGIDAt(ptTile);if (gid != 0){// 微調CCPoint ptLB = Common::Tile2PointLB(map, ptTile);this->setPositionY(ptLB.y);return false;}}}return true; }運行實現
void Mario::moveLeft(float dt) {if (_dirRun!=Common::LEFT){_dirRun=Common::LEFT;_dirFace=Common::LEFT;updateStatus();}if (!canMoveLeft(dt))return;Common::moveNode(this,ccp(-dt*_speed,0));//scroll mapCCNode *map=this->getParent();CCPoint ptWorld=map->convertToWorldSpace(this->getPosition());if (ptWorld.x<winSize.width/2&&map->getPositionX()<0){Common::moveNode(map,ccp(dt*_speed,0));} }void Mario::moveRight(float dt) {if (_dirRun!=Common::RIGHT){_dirRun=Common::RIGHT;_dirFace=Common::RIGHT;updateStatus();}if (!canMoveRight(dt))return;Common::moveNode(this,ccp(dt*_speed,0));//scroll mapCCNode *map=this->getParent();CCPoint ptWorld=map->convertToWorldSpace(this->getPosition());if (ptWorld.x>winSize.width/2){Common::moveNode(map,ccp(-dt*_speed,0));} }void Mario::moveUp(float dt) {if (_speedUp<=0){return;}if (!canMoveUp(dt)){// 反彈效果_speedDown = _speedUp;_speedUp = 0; // 不繼續上升了return;}Common::moveNode(this,ccp(0,dt*_speedUp));_speedUp-=_speedAcc;//_speedDown=_speedUp; } void Mario::moveDown(float dt) {if(_speedUp<=0){if (canMoveDown(dt)){if (_bFly==false){_bFly=true;updateStatus();}Common::moveNode(this,ccp(0,-dt*_speedDown));_speedDown+=_speedAcc;}else{if (_bFly){_bFly = false;_speedDown = _speedAcc;updateStatus();}}}}void Mario::stop() {if (_dirRun!=Common::NONE){_dirRun=Common::NONE;updateStatus();} } void Mario::jump() {static int i=0;CCLog("speed%d=%d",++i,_speedUp);if (_bFly)return;_speedUp=300;_bFly=true;updateStatus(); }運行狀態機,控制運行時的動畫
void Mario::updateStatus() {stopAllActions();if (_bFly){if (_dirFace==Common::LEFT){setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("SmallJumpLeft"));}else if(_dirFace==Common::RIGHT){setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("SmallJumpRight"));}return;}if (_dirRun==Common::LEFT){this->runAction(CCRepeatForever::create(CCAnimate::create(CCAnimationCache::sharedAnimationCache()->animationByName("SmallWalkLeft"))));}else if (_dirRun==Common::RIGHT){this->runAction(CCRepeatForever::create(CCAnimate::create(CCAnimationCache::sharedAnimationCache()->animationByName("SmallWalkRight"))));}else{if (_dirFace==Common::LEFT){this->setDisplayFrameWithAnimationName("SmallWalkLeft",0);}else if(_dirFace==Common::RIGHT){this->setDisplayFrameWithAnimationName("SmallWalkRight",0);}} }注:在實現這個功能的時候,由于把等于寫成賦值,發生了許多靈異的錯誤,要小心啊,等于與賦值。
運行結果
總結
以上是生活随笔為你收集整理的实现超级玛丽上下左右运动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: comparing ORB and AK
- 下一篇: Android下利用Bitmap切割图片