cocos2dx 3.3 跑酷游戏的编写 游戏层
2014-10-22 22:04
330 查看
首先新建GameLayer类,要在这层实现人物的创建,地图的创建,金币的生成和碰撞检测,GameLayer是很重的层啊
1.生成简单的地图就好了,地图由地面和墙壁构成,分成2个容器,用来存放生成的地面和墙壁精灵,场景的移动采用背景向左移动的策略,那么,地面,墙壁,金币等都要不断向左移动,同时,判断是否移出屏幕(即x坐标是否小于0,注意,判断时不要直接与0判断,稍微向左边偏离几个格子),移除屏幕时,则从容器中清除,并在容器的最后随机生成相应的精灵,实现无穷的跑动且没有重复场景
2.碰撞检测,设置定时器,每帧检测人物的上下右是否发生碰撞,采用矩形和点是否包含的策略,要注意的是有时要判断一个方向的多个点,否则碰撞效果不好;金币与人物的碰撞使用2个矩形是否相交。
3.随机函数,直接使用c++中的srand和rand配合
上代码+注释
地图和物体的移动:
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; }
相关文章推荐
- cocos2dx 3.3 跑酷游戏的编写
- cocos2dx 3.3 跑酷游戏 人物的创建
- cocos2dx 3.3 跑酷游戏 信息层
- cocos2dx 3.3 跑酷游戏 背景层
- cocos2dx 3.3 跑酷游戏 声音的加入
- 使用CoCos2dx-3.4开发一套可以商用的跑酷游戏 之三 初始界面的编写(1)
- 使用CoCos2dx-3.4开发一套可以商用的跑酷游戏 之三 初始界面的编写(2)
- Cocos2d-x虚拟摇杆控制精灵上下左右运动----之游戏开发《赵云要格斗》(1) cocos2dx 3.3移植版
- Cocos2d-x怪物智能AI怪物也有智商--之游戏开发《赵云要格斗》(6) cocos2dx 3.3移植版
- cocos2dx 3.3 魂斗罗初步尝试 游戏层(暂停段时间,以后再写)。。。
- Cocos2dx游戏开发系列笔记7:一个简单的跑酷游戏《萝莉快跑》的消化(附下载)
- cocos2dx 3.3 + lua 学习笔记(02)--- 游戏场景的基本搭建
- 笔记:利用Cocos2dx 3.3 lua 做一个动作类游戏(一)
- Cocos2d-x自定义按钮类控制精灵攻击----之游戏开发《赵云要格斗》(2) cocos2dx 3.3移植版
- Cocos2dx系列笔记7:一个简单的跑酷游戏《萝莉快跑》的消化(附下载)
- cocos2dx 3.3 + QT5.3制作游戏编辑器
- 使用CoCos2dx-3.4开发一套可以商用的跑酷游戏 之二 视频演示
- cocos2dx 3.3 + QT5.3制作游戏编辑器
- Cocos2d-x 自定义血条及其美化----之游戏开发《赵云要格斗》(4)cocos2dx 3.3移植版
- Cocos2dx------详细介绍如何编写扫雷这个游戏含源码(一)