懒骨头(http://blog.csdn.net/iamlazybone QQ:124774397 )

写下这些东西的同时

旁边放了两部电影

周星驰的《还魂夜》

甄子丹的《特殊身份》

骨头听着电影读代码

别有一番风味

接上篇,今天继续看一下这个demo。

----------------------------------------------------------------------------------------------------------------------------------------------------------

 GameScene.cpp类。 

----------------------------------------------------------------------------------------------------------------------------------------------------------

这个类里主要有两层,上层是控制层:HudLayer,下层是游戏层:GameLayer

init初始化方法里有个输入更新函数:

this->schedule(schedule_selector(GameScene::inputUpdate));

void GameScene::inputUpdate(float dt)
{
CCPoint velocity = mHudLayer->mJoystick->getVelocity();
//std::cout << velocity.x << std::endl; if (velocity.x >= 0.4f || velocity.x <= -0.4f ||
velocity.y >= 0.4f || velocity.y <= -0.4f) {
mGameLayer->mHero->walkWithDirection(velocity);
} else if (mGameLayer->mHero->mActionState == kActionStateWalk) {
mGameLayer->mHero->idle();
} if (attackInterval <= 0.0f) {
if (mHudLayer->mButtonA->getIsActive()) {
mGameLayer->mHero->attack();
attackInterval = 0.5f; if (mGameLayer->mHero->mActionState == kActionStateAttack) {
CCObject* item;
CCARRAY_FOREACH(mGameLayer->mRobots, item) {
Robot* robot = dynamic_cast<Robot*>(item);
if (robot->mActionState != kActionStateKnockedOut) {
if (fabs(mGameLayer->mHero->getPositionY() - robot->getPositionY()) < 10) {
//std::cout << "yew" << std::endl;
if (mGameLayer->mHero->mAttackBox.actual.intersectsRect(robot->mHitBox.actual)) {
robot->hurtWithDamage(mGameLayer->mHero->mDamage);
//std::cout << "yew!!!!!!!!!!!!" << std::endl;
}
}
}
}
}
}
} else {
attackInterval -= dt;
}
}

通过Joystick虚拟摇杆获取速度

CCPoint velocity = mHudLayer->mJoystick->getVelocity(); 

如果x,y两个方向的速度大于0.4的话,主角移动。

否则,主角原地不动。

继续判断

如果攻击按钮被按下,则主角进行攻击。

if (mHudLayer->mButtonA->getIsActive())
mGameLayer->mHero->attack();

此时,遍历所有的robot机器人,看我们的主角击中了哪个robot,

击中的那个(矩形相交),调用受伤方法

robot->hurtWithDamage(mGameLayer->mHero->mDamage);

----------------------------------------------------------------------------------------------------------------------------------------------------------

GameLayer 主要逻辑类

----------------------------------------------------------------------------------------------------------------------------------------------------------

class GameLayer : public CCLayer
{
public :
GameLayer();
bool init();
CCTMXTiledMap* mTileMap; void initTileMap();
void initHero();
Hero* mHero;
CCSpriteBatchNode* mActors;
void update(float dt);
void updatePosition(float dt);
void setViewpointCenter(CCPoint position);
CCArray* mRobots;
void initRobots();
void reorderActors();
void updateRobots(float dt);
};

这个类里有瓦片地图类: CCTMXTiledMap

有主角和初始化方法:Hero* ,initHero

有更新方法:void update(float dt),void updatePosition(float dt)

一一看来

初始化机器人方法:

void GameLayer::initRobots()
{
int robotCount = 50;
this->mRobots = new CCArray(robotCount); for (int i = 0; i < robotCount; ++i) {
Robot* robot = new Robot();
//mActors->addChild(robot);
this->addChild(robot);
mRobots->addObject(robot); int minX = SCREEN.width + robot->mCenterToSide;
int maxX = mTileMap->getMapSize().width * mTileMap->getTileSize().width
- robot->mCenterToSide;
int minY = robot->mCenterToBottom;
int maxY = 3 * mTileMap->getTileSize().height + robot->mCenterToBottom; if (rand() % 2)
robot->setFlipX(true);
robot->setPosition(
ccp(random_range(minX, maxX), random_range(minY, maxY)));
robot->mDesiredPosition = robot->getPosition();
robot->idle();
}
}

new一个Robot类,放到CCArray数组里。

然后定义机器人的活动范围:即xy的最大值最小值

如图:机器人最早出现的x位置是第二屏最近的位置,即

SCREEN.width + robot->mCenterToSide;  //  mCenterToSide 半个机器人宽度

最远是的位置是地图的最后边:

mTileMap->getMapSize().width * mTileMap->getTileSize().width - robot->mCenterToSide;

即 :tile的个数Xtile的宽度-机器人半个宽度

最高和最低也是同理。

然后在这个范围内随机放50个机器人。

重新排序方法 reorderActors:

void GameLayer::reorderActors()
{
CCObject* item;
//CCARRAY_FOREACH(mActors->getChildren(), item)
CCARRAY_FOREACH(this->getChildren(), item) {
CCNode *node = dynamic_cast<CCNode *>(item);
if (node->getTag() == ACTION_SPRITE_TAG) {
ActionSprite *sprite = dynamic_cast<ActionSprite *>(item);
this->reorderChild(sprite, mTileMap->getMapSize().height * mTileMap->getTileSize().height
- sprite->getPositionY());
}
}
}

循环所有的CCSprite,从新计算z轴,来修正遮挡关系。

更新机器人方法:void GameLayer::updateRobots(float dt)

		if (robot->mActionState != kActionStateKnockedOut) {
++alive;
robot->mNextDecisionTime -= dt;
if (robot->mNextDecisionTime <= 0.0f) {
distanceSQ = ccpDistanceSQ(robot->getPosition(), mHero->getPosition());
if (distanceSQ <= 50*50) {
robot->mNextDecisionTime = frandom_range(0.5f, 1.0f, 0.1f);
randomChoice = random_range(0, 1);
if (randomChoice == 0) {
if (mHero->getPositionX() > robot->getPositionX()) {
robot->setFlipX(false);
} else {
robot->setFlipX(true);
} robot->attack();
if (robot->mActionState == kActionStateAttack) {
if (fabs(mHero->getPositionY() - robot->getPositionY()) < 10) {
if (mHero->mHitBox.actual.intersectsRect(robot->mAttackBox.actual)) {
mHero->hurtWithDamage(robot->mDamage);
}
}
}
} else {
robot->idle();
}
} else if (distanceSQ <= SCREEN.width * SCREEN.width) {
robot->mNextDecisionTime = frandom_range(1.0f, 1.5f, 0.1f);
robot->mNextDecisionTime = random_range(5, 10) * 0.1f;
randomChoice = random_range(0, 2);
if (randomChoice == 0) {
CCPoint moveDirection = ccpNormalize(ccpSub(mHero->getPosition(), robot->getPosition()));
robot->walkWithDirection(moveDirection);
} else {
robot->idle();
}
}
}

这个方法大体流程是:

如果机器人还没死,就看看到没到行动时间,到时间了,就计算下机器人和主角之前的距离:

distanceSQ = ccpDistanceSQ(robot->getPosition(), mHero->getPosition());

如果主角在机器人左边,机器人向左走,反之,向右边走:

if (mHero->getPositionX() > robot->getPositionX()) { robot->setFlipX(false);

机器人进入攻击状态,检测下主角是否在机器人的攻击范围内:

if (mHero->mHitBox.actual.intersectsRect(robot->mAttackBox.actual)) {

如果离的远了,就往主角那走:

robot->walkWithDirection(moveDirection);

定位到地图中心 

void GameLayer::setViewpointCenter(CCPoint position)
{
CCSize winSize = CCDirector::sharedDirector()->getWinSize(); int x = GetMAX(position.x, winSize.width / 2);
int y = GetMAX(position.y, winSize.height / 2); x = GetMIN(x, (mTileMap->getMapSize().width *
mTileMap->getTileSize().width - winSize.width / 2));
y = GetMIN(y, (mTileMap->getMapSize().height *
mTileMap->getTileSize().height - winSize.height / 2)); CCPoint actualPosition = ccp(x, y);
CCPoint centerOfView = ccp(winSize.width / 2, winSize.height / 2);
CCPoint viewPoint = ccpSub(centerOfView, actualPosition); this->setPosition(viewPoint);
}

如果主角往右走,如果此时移动到地图中心,那么主角保持在地图的中心,但是地图往左移动。

然后让整个地图向左移动,来表现主角向右走。this->setPosition(viewPoint);

更新位置方法

void GameLayer::updatePosition(float dt)
{
float posX = GetMIN(mTileMap->getMapSize().width * mTileMap->getTileSize().width - mHero->mCenterToSide,
GetMAX(mHero->mCenterToSide, mHero->mDesiredPosition.x));
float posY = GetMIN(3 * mTileMap->getTileSize().height + mHero->mCenterToBottom,
GetMAX(mHero->mCenterToBottom, mHero->mDesiredPosition.y)); //std::cout << mHero->mDesiredPosition.x << std::endl;
mHero->setPosition(ccp(posX, posY)); CCObject* item;
CCARRAY_FOREACH(mRobots, item) {
Robot* robot = dynamic_cast<Robot*>(item);
posX = GetMIN(mTileMap->getMapSize().width * mTileMap->getTileSize().width - robot->mCenterToSide,
GetMAX(robot->mCenterToSide, robot->mDesiredPosition.x));
posY = GetMIN(3 * mTileMap->getTileSize().height + robot->mCenterToBottom,
GetMAX(robot->mCenterToBottom, robot->mDesiredPosition.y)); robot->setPosition(ccp(posX, posY));
} this->setViewpointCenter(mHero->getPosition());
}

其实就是常见的2D卷轴算法,不过看起来确实费劲。

注释掉机器人的攻击方法,然后在游戏中跑一跑,看看主角的可移动范围。

GetMAX(mHero->mCenterToSide, mHero->mDesiredPosition.x)  这句的意思是:

比如英雄往左边走,他能走的左的距离是mCenterToSide,也就是半个宽度,也就是

float posX 是通过GetMIN取得的,他限制了你不能超过整个tile地图的最后边。

然后把这个合法的 xy设置到hero上。

呼呼,简简单单的分析了下游戏的主要代码。

还有个Sneaky包暂时忽略,骨头打算另开笔记学习虚拟遥控杆。

CCTMXTiledMap 相关的也是重点,这个等以后研究工具的时候好好看看。

明天就是周五了,离周末越来越近了。倍感欣慰啊。

准备休息。

------------------- 飞船起飞--------------------

Cocos2dx游戏开发系列笔记11:解刨《战神传说》完结篇

Cocos2dx游戏开发系列笔记10:解刨《战神传说》

Cocos2dx游戏开发系列笔记9:android手机上运行《战神传说》,并解决横竖屏即分辨率自适应问题

Cocos2dx游戏开发系列笔记8:开搞一个射击游戏《战神传说》//就个打飞机的

Cocos2dx游戏开发系列笔记7:一个简单的跑酷游戏《萝莉快跑》的消化(附下载)

Cocos2dx游戏开发系列笔记6:怎样让《萝莉快跑》的例子运行在vs和手机上

Cocos2dx游戏开发系列笔记5:继续润色《忍者飞镖射幽灵》

Cocos2dx游戏开发系列笔记4:怎样新加一个Scene类?

Cocos2dx游戏开发系列笔记3:牛刀小试->忍者飞镖射幽灵的Demo

Cocos2dx游戏开发系列笔记2:一个刚创建的cocos2dx中的demo里都有什么

Cocos2dx游戏开发系列笔记1:一个崭新的开始,cocos2dx2.2+ndkr9+Cygwin+vs2012游戏开发环境搭建

-------------------- 飞船降落--------------------

最后,骨头介绍一下陪在身边的哲哲(右边就是低调的哲哲)

哲哲,小名 YIYI ,手工爱好者,文艺范,手艺人,《YiYiの妙舍》创始人,很有自己想法。

Cocos2dx游戏开发系列笔记13:一个横版拳击游戏Demo完结篇的更多相关文章

  1. (译)【Unity教程】使用Unity开发Windows Phone上的横版跑酷游戏

    译者注: 目前移动设备的跨平台游戏开发引擎基本都是采用Cocos2d-x或者Unity.一般而言2d用cocos2d-x 3d用unity,但是对于Windows Phone开发者, cocos2d- ...

  2. 《MFC游戏开发》笔记六 图像双缓冲技术:实现一个流畅的动画

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9334121 作者:七十一雾央 新浪微博:http:/ ...

  3. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程:简介及目录》(附上完整工程文件)

    介绍:讲述如何使用Genesis-3D来制作一个横版格斗游戏,涉及如何制作连招系统,如何使用包围盒实现碰撞检测,软键盘的制作,场景切换,技能读表,简单怪物AI等等,并为您提供这个框架的全套资源,源码以 ...

  4. [置顶] 《MFC游戏开发》笔记一 系列简介

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9299121 作者:七十一雾央 新浪微博:http:/ ...

  5. 《MFC游戏开发》笔记十 游戏中的碰撞检测进阶:地图类型&障碍物判定

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9394465 作者:七十一雾央 新浪微博:http:// ...

  6. 《MFC游戏开发》笔记九 游戏中的碰撞判定初步&怪物运动简单AI

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9374935 作者:七十一雾央 新浪微博:http:// ...

  7. 《MFC游戏开发》笔记八 游戏特效的实现(二):粒子系统

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9360993 作者:七十一雾央 新浪微博:http:// ...

  8. 《MFC游戏开发》笔记七 游戏特效的实现(一):背景滚动

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9344721 作者:七十一雾央 新浪微博:http:// ...

  9. 《MFC游戏开发》笔记五 定时器和简单动画

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9332377 作者:七十一雾央 新浪微博:http:// ...

随机推荐

  1. PHP自学3——在html的<table>标签中显示用户提交表单

    为了更好地显示用户提交表单,本节将在上一节的基础上将读取的用户表单显示在html的<table>标签中,这一节将用到和数组有关的知识. 本节代码将从外部文件(.txt文件)中读取信息于指定 ...

  2. node.js(八) 有趣的东西才开始哦

    ### Express介绍 npm提供了大量的第三方模块,其中不乏许多Web框架,比如我们本章节要讲述的一个轻量级的Web框架 ——— Express. Express是一个简洁.灵活的node.js ...

  3. jq方法

    DOM属性-获取和设置页面元素的DOM属性 .addClass()..attr()..prop()..hasClass()..html()..removeAttr()..removeClass().. ...

  4. NodeJS + express访问html、css、JS等静态资源文件

    原先做前端开发时都是用XAMPP或LAMP,把HTML.CSS.JS等前端资源放到htdocs下,测试自己的前端代码,但有些不方便的地方是,在调用Ajax请求后无法模拟请求返回的数据,最近学了点Nod ...

  5. IE 第三方设置cookie失效

    公司的产品,采用多服务分摊压力,中间必须涉及的当然是单点登陆.一般的单点登陆都是通过去用户中心登陆,302或页面回调的方式,返回到登陆前的页面. 公司项目,想用户体验更好些,采用弹框登陆,可以考虑if ...

  6. 提取 ECharts 中的svg地图信息

    地图的需求还是蛮大的,全国都要自己画的话,还是需要投入比较大的人力. ECharts中有地图,那我们能不能把里面的地图文件提取出来呢,主要逻辑在map.js中. 看源代码发现,ECharts中地图信息 ...

  7. hdu 4635 Strongly connected 强连通

    题目链接 给一个有向图, 问你最多可以加多少条边, 使得加完边后的图不是一个强连通图. 只做过加多少条边变成强连通的, 一下子就懵逼了 我们可以反过来想. 最后的图不是强连通, 那么我们一定可以将它分 ...

  8. 在windows 8.1 64位配置python和opencv

    之前在linux下安装python和opencv及相关的库,都可以直接命令行操作.最近需要在windows下配置一下,查了一些资料,发现网上有很多关于python和opencv的配置,但由于不同版本问 ...

  9. Java 拾遗

    1.选择表达式中的类型转换 public class Test { public void static main(String args[]){ int i = 5; System.out.prin ...

  10. java反射机制(笔记)

    java反射机制就是获取出class的相应方法 例如 获取构造函数: 模版: Class test = Class.forName("cn.test.Person");//得到相应 ...