cocos2dx 3.3 跑酷游戏的编写 游戏层

来源:互联网 发布:adobe排版软件 编辑:程序博客网 时间:2024/06/04 16:34

首先新建GameLayer类,要在这层实现人物的创建,地图的创建,金币的生成和碰撞检测,GameLayer是很重的层啊

1.生成简单的地图就好了,地图由地面和墙壁构成,分成2个容器,用来存放生成的地面和墙壁精灵,场景的移动采用背景向左移动的策略,那么,地面,墙壁,金币等都要不断向左移动,同时,判断是否移出屏幕(即x坐标是否小于0,注意,判断时不要直接与0判断,稍微向左边偏离几个格子),移除屏幕时,则从容器中清除,并在容器的最后随机生成相应的精灵,实现无穷的跑动且没有重复场景

2.碰撞检测,设置定时器,每帧检测人物的上下右是否发生碰撞,采用矩形和点是否包含的策略,要注意的是有时要判断一个方向的多个点,否则碰撞效果不好;金币与人物的碰撞使用2个矩形是否相交。

3.随机函数,直接使用c++中的srand和rand配合

上代码+注释

#pragma once#include "cocos2d.h"#include "Player.h"//角色的加入#include "Def.h"#include <vector>using namespace std;USING_NS_CC;class GameLayer :public Layer{public: bool init(); CREATE_FUNC(GameLayer); bool onTouchBegan(Touch *touch, Event *unused_event); Player* player; Sprite *wall; CCTMXTiledMap *tileMap;//载入地图、废弃 CCTMXLayer *tileLay;//废弃 CCTMXObjectGroup *tileObject;//废弃 void timeCallBcak(float f);//地图物体移动 void bobCallBcak(float f);//碰撞检测 void playerCallBcak(float f);//右边有障碍主角移动 SpriteBatchNode *m_batchNode;//地面砖块缓冲池 SpriteBatchNode *m_goldBatchNode;//金币缓冲池 SpriteBatchNode *m_wallBatchNode;//墙壁缓冲池 vector< Sprite* > m_Vector;//存放地面容器 vector< Sprite* > m_goldVector;//存放金币容器 vector< Sprite* > m_wallVector;//存放墙壁容器 bool IscollWithUp(); bool IscollWithDown(); bool IscollWithRight(); bool IscollWithLeft(); bool IscollWithGold(); bool IsDie(); void DownLogic(); void UpLogic(); void RightLogic(); void LeftLogic();};
bool GameLayer::init(){ if (!Layer::init()) {  return false; } //随机种子的初始化 srand((unsigned)time(NULL));  auto visibleSize = Director::getInstance()->getVisibleSize(); auto origin = Director::getInstance()->getVisibleOrigin(); //添加地面缓冲 m_batchNode = SpriteBatchNode::create("wall.png",50); m_batchNode->setAnchorPoint(Point::ZERO); m_batchNode->setPosition(ccp(0, 0)); this->addChild(m_batchNode); //添加金币缓冲 m_goldBatchNode = SpriteBatchNode::create("gold.png", 50); m_goldBatchNode->setAnchorPoint(Point::ZERO); m_goldBatchNode->setPosition(Point::ZERO); this->addChild(m_goldBatchNode); //添加墙壁缓冲 m_wallBatchNode = SpriteBatchNode::create("wall.png", 50); m_wallBatchNode->setAnchorPoint(Point::ZERO); m_wallBatchNode->setPosition(Point::ZERO); this->addChild(m_wallBatchNode); //在地面缓冲中添加精灵,即开始时地面 for (int i = 0; i < 30; i++) {  auto walls = Sprite::create("wall.png");  walls->setAnchorPoint(Point::ZERO);  walls->setPosition(ccp(i * 32, 32));  m_batchNode->addChild(walls);  m_Vector.push_back(walls); }  //建立人物  player = Player::getInstance(); player->setAnchorPoint(ccp(0,0));  player->setPosition(ccp(100,160)); player->setPlayState(STATE_PLAYER_RUN); this->addChild(player);  //触摸建立 auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this); auto dispatcher = Director::getInstance()->getEventDispatcher(); dispatcher->addEventListenerWithSceneGraphPriority(listener, this); //地图定时器//this->schedule(schedule_selector(GameLayer::timeCallBcak), 0.1);//更改到mainScene中调用 //碰撞定时器 this->schedule(schedule_selector(GameLayer::bobCallBcak), 0.016); return true;}
触摸

bool GameLayer::onTouchBegan(Touch *touch, Event *unused_event){CCLOG("on touch begin");player->setSpeed(DEFLAUT_SPEEDY);player->setPlayState(STATE_PLAYER_JUMP);return false;}

地图和物体的移动:

void GameLayer::timeCallBcak(float f)//地图物体的移动{//墙壁的移动int n = m_Vector.size();//容器的遍历for (int i = 0; i < n; i++){m_Vector[i]->setPositionX(m_Vector[i]->getPositionX() - MOVING_GAP);if (m_Vector[i]->getPositionX() <= -m_Vector[i]->getContentSize().width)//跑出屏幕左边则清除同时在最左边随机生成{m_batchNode->removeChild(m_Vector[i], true);m_Vector.erase(m_Vector.begin() + i);int i = rand() % 10;//清除后添加CCLOG("i=%d", i);if (i>0)//在最后添加一个地面块{auto walls = Sprite::create("wall.png");walls->setAnchorPoint(Point::ZERO);walls->setPosition(ccp((*(m_Vector.end() - 1))->getPositionX() + 32, 32));//加到最后m_batchNode->addChild(walls);m_Vector.push_back(walls);}else//空2格再添加地面块(1/10的概率){auto walls = Sprite::create("wall.png");walls->setAnchorPoint(Point::ZERO);walls->setPosition(ccp((*(m_Vector.end() - 1))->getPositionX() + 3 * 32, 32));//加到最后m_batchNode->addChild(walls);m_Vector.push_back(walls);}//右边将要出现的物品//右边将要产生墙壁auto produceWall = rand() % 10;//出现墙壁概率auto wallHigh = rand() % 4;//墙壁高度if (produceWall == 0){for (int j = 0; j < wallHigh; j++){auto wall = Sprite::create("wall.png");wall->setAnchorPoint(Point::ZERO);wall->setPosition(ccp((*(m_Vector.end() - 1))->getPositionX(), 32 * (j + 2)));m_wallVector.push_back(wall);m_wallBatchNode->addChild(wall);}}// 1.产生金币 1/5的概率auto produceGold = rand() % 5;if (produceGold == 0){auto goldHigh = rand() % 3 + 3;//金币高度if (produceWall == 0) goldHigh = wallHigh + 2;//金币在墙壁的上方auto gold = Sprite::create("gold.png");gold->setAnchorPoint(Point::ZERO);gold->setPosition(ccp((*(m_Vector.end() - 1))->getPositionX(), 32 * goldHigh));m_goldVector.push_back(gold);m_goldBatchNode->addChild(gold);}}}//金币的移动for (auto i = 0; i < m_goldVector.size();){m_goldVector[i]->setPositionX(m_goldVector[i]->getPositionX() - MOVING_GAP);if (m_goldVector[i]->getPositionX() < -m_goldVector[i]->getContentSize().width){m_goldBatchNode->removeChild(m_goldVector[i], true);m_goldVector.erase(m_goldVector.begin() + i);}else{i++;}}//墙壁的移动for (auto i = 0; i < m_wallVector.size();){m_wallVector[i]->setPositionX(m_wallVector[i]->getPositionX() - MOVING_GAP);if (m_wallVector[i]->getPositionX() < -m_wallVector[i]->getContentSize().width){m_wallBatchNode->removeChild(m_wallVector[i], true);m_wallVector.erase(m_wallVector.begin() + i);}else i++;}}

void GameLayer::bobCallBcak(float f)//碰撞检测{if (IscollWithDown())//人物和下方有接触{if (player->getPlayState() == STATE_PLAYER_DOWN){Sounder::getInstance()->playTouch();player->setPlayState(STATE_PLAYER_RUN);}}else{if (player->getPlayState()==STATE_PLAYER_RUN)player->setPlayState(STATE_PLAYER_DOWN);}if (IscollWithUp())//人物和上方有接触{if (player->getPlayState() == STATE_PLAYER_JUMP)player->setPlayState(STATE_PLAYER_RUN);}if (IscollWithRight())//人物和右边有接触{this->schedule(schedule_selector(GameLayer::playerCallBcak), 0.1);}else{this->unschedule(schedule_selector(GameLayer::playerCallBcak));}IscollWithLeft();//IscollWithGold();//移到主界面去了,为了和信息界面交互}
bool GameLayer::IsDie()//判断人物是否死亡{<span style="white-space:pre"></span>if (player->getPositionX()<0 || player->getPositionY()<0)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>return true;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>return false;}
bool GameLayer::IscollWithGold()//是否与金币碰撞{for (int i = 0; i < m_goldVector.size(); )//遍历{if (m_goldVector[i]->getBoundingBox().intersectsRect(player->getBoundingBox())){m_goldBatchNode->removeChild(m_goldVector[i], true);//发生碰撞则移除并返回m_goldVector.erase(m_goldVector.begin() + i);return true;}else i++;//无碰撞则往后遍历}return false;}
bool GameLayer::IscollWithDown(){Point point;//中间点point.x = player->getBoundingBox().getMidX();point.y = player->getBoundingBox().getMinY();//增加碰厨点Point point1;//左边点point1.x = player->getBoundingBox().getMinX();point1.y = player->getBoundingBox().getMinY();Point point2;//右边点point2.x = player->getBoundingBox().getMaxX()-10;point2.y = player->getBoundingBox().getMinY();//是否与地面接触for (int i = 0; i < m_Vector.size(); i++){if (m_Vector[i]->getBoundingBox().containsPoint(point)//|| m_Vector[i]->getBoundingBox().containsPoint(point1)|| m_Vector[i]->getBoundingBox().containsPoint(point2)){return true;}}//是否与wall碰撞for (int i = 0; i < m_wallVector.size(); i++){if (m_wallVector[i]->getBoundingBox().containsPoint(point)//|| m_wallVector[i]->getBoundingBox().containsPoint(point1)|| m_wallVector[i]->getBoundingBox().containsPoint(point2)){return true;}}return false;}bool GameLayer::IscollWithUp(){Point point1,point2,point3;point1.x = player->getBoundingBox().getMinX();point1.y = player->getBoundingBox().getMaxY();point2.x = player->getBoundingBox().getMidX();point2.y = player->getBoundingBox().getMaxY();point3.x = player->getBoundingBox().getMaxX();point3.y = player->getBoundingBox().getMaxY();for (int i = 0; i < m_Vector.size(); i++){if (//m_Vector[i]->getBoundingBox().containsPoint(point1)//头发可以穿过 m_Vector[i]->getBoundingBox().containsPoint(point2)| m_Vector[i]->getBoundingBox().containsPoint(point3)){return true;}else if (m_Vector[i]->getPositionX() > point1.x){return false;}}return false;}bool GameLayer::IscollWithRight(){Point point;point.x = player->getBoundingBox().getMaxX();point.y = player->getBoundingBox().getMinY()+10;Point point1;point1.x = player->getBoundingBox().getMaxX();point1.y = player->getBoundingBox().getMidY();Point point2;point2.x = player->getBoundingBox().getMaxX();point2.y = player->getBoundingBox().getMaxY();//判断是否与右侧地面碰撞for (int i = 0; i < m_Vector.size(); i++){if (m_Vector[i]->getBoundingBox().containsPoint(point)//无法在地面上走动,y向上移动一点|| m_Vector[i]->getBoundingBox().containsPoint(point1)|| m_Vector[i]->getBoundingBox().containsPoint(point2)){return true;}/*else if (m_vector[i]->getpositionx() > point.x)//当添加墙壁后应去除{return false;}*/}//判断是否与右边墙壁碰撞for (int i = 0; i < m_wallVector.size(); i++){if (m_wallVector[i]->getBoundingBox().containsPoint(point)|| m_wallVector[i]->getBoundingBox().containsPoint(point1)|| m_wallVector[i]->getBoundingBox().containsPoint(point2)){return true;}}return false;}bool GameLayer::IscollWithLeft(){Point point;point.x = player->getBoundingBox().getMinX();point.y = player->getBoundingBox().getMidY();for (int i = 0; i < m_Vector.size(); i++){if (m_Vector[i]->getBoundingBox().containsPoint(point)){return true;}else if (m_Vector[i]->getPositionX() > point.x){return false;}}return false;}



0 0
原创粉丝点击