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
- cocos2dx 3.3 跑酷游戏的编写 游戏层
- cocos2dx 3.3 跑酷游戏的编写
- cocos2dx 3.3 跑酷游戏 信息层
- cocos2dx 3.3 跑酷游戏 背景层
- 【Cocos2dx】跑酷游戏
- cocos2dx 3.3 跑酷游戏 人物的创建
- cocos2dx 3.3 跑酷游戏 声音的加入
- 使用CoCos2dx-3.4开发一套可以商用的跑酷游戏 之三 初始界面的编写(1)
- 使用CoCos2dx-3.4开发一套可以商用的跑酷游戏 之三 初始界面的编写(2)
- 我的cocos2dx游戏
- 【cocos2dx-3.0beta-制作flappybird】——游戏控制层的设计以及控制层和游戏层的关系
- 扫雷游戏的编写
- 【cocos2dx-3.0beta-制作flappybird】布告栏中的玄机—游戏状态层的设计与实现
- 17、Cocos2dx 3.0游戏开发找小三之内置的常用层:三剑客LayerColor、LayerGradient、Menu
- Cocos2dx游戏开发系列笔记7:一个简单的跑酷游戏《萝莉快跑》的消化(附下载)
- cocos2dx 3.3 魂斗罗初步尝试 游戏层(暂停段时间,以后再写)。。。
- 关于cocos2dx编写的游戏由vs2013项目打包成apk文件
- 【cocos2dx 3.2】一个都不能死4 游戏层
- Python正则表达式指南
- 让你理解什么是三层架构
- vector中erase用法注意事项
- 2015阿里巴巴实习生招聘笔试题,带答案,欢迎一起来讨论哇!
- udp编程的学习
- cocos2dx 3.3 跑酷游戏的编写 游戏层
- xCode 4.2 安装离线帮助文档
- 对驱动的理解
- 线程
- 静态数据的初始化
- 一个人的ACM(我们一起追过的ACM)
- 三级联动
- 2014双十一
- codeforces Round #261(div2) E解题报告