日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实现超级玛丽上下左右运动

發布時間:2024/7/23 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现超级玛丽上下左右运动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

注:在實現這個功能的時候,由于把等于寫成賦值,發生了許多靈異的錯誤,要小心啊,等于與賦值。

運行結果

總結

以上是生活随笔為你收集整理的实现超级玛丽上下左右运动的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。