热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(一)

转自:http:www.cnblogs.comhll2008p4235714.html一、前提:完成HelloGame项目的创建编译。具体参考:Cocos2dx.3x_HelloGame

转自:http://www.cnblogs.com/hll2008/p/4235714.html

一、前提:

完成Hello Game项目的创建编译。

具体参考:Cocos2dx.3x_Hello Game项目创建篇

二、本篇目标:

l  说说关于塔防游戏的想法和思路

l  实现一个简单的塔防游戏原型

三、内容:

l  说说关于塔防游戏的想法和思路

首先上一张塔防游戏PSD设计效果图

 

);
sprite
->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
this->addChild(sprite, 0);
return true;
}
);
sprite
->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
this->addChild(sprite, 0);

//在地图起点处放置一个色狼
auto dsSprite = Sprite::create("dashu.png");
dsSprite
->setPosition(Vec2(40, 390));
this->addChild(dsSprite, 0);

//在地图终点处放置一个女主角
auto nhSprite = Sprite::create("girl.png");
nhSprite
->setPosition(Vec2(920, 480));
this->addChild(nhSprite, 0);
…...

第二步:然后运行就可以在画面上看到色狼大叔和女主角了

1、 让色狼大叔沿着地图指定的路线向女主角的位置靠近

这个一个有点难度的任务,首先我们对这张地图的道路路径进行一下坐标分析:

如上图所示,以地图的右下顶点为坐标系原点,整个道路分成12个坐标点,女主角在1号坐标点,色狼大叔在12号坐标点。现在色狼大叔将沿着图中黄色的线路从12点开始 11点、10点、9点…直至到达1点,我的实现思路是这样,色狼从12点出发时告诉它目标点是11点,当色狼到达11点的时候继续告诉它下一个目标点是10点直到1点。

几个实现技术点:

1、  对Sprite(色狼)进行setPosition的方式可以改变Sprite在图上的位置从而实现Sprite的移动

2、  计算Sprite(色狼)位置到目标点的向量值,然后根据这个向量值和色狼移动速度计算Sprite在x,y方向上的距离偏移值,用这个偏移值调整Sprite的位置

判断Sprite(色狼)到达目标点(如:11点),如下图所示通过Sprite坐标点和目标点之间的距离小于一定值的时就判定为到达目标点,需要设置新的下一个目标点。

有了这些实现思路,现在开始代码编写:

第一步:由上面是实现思路可知我们的基本实现是路径点,那么这里先新建一个路径点类对象,名称为:Waypoint.h、Waypoint.cpp,继承自:cocos2d::CCNode。

Waypoint.h:

class Waypoint: public cocos2d::CCNode
{
public:
Waypoint(
void);
~Waypoint(void);
//初始化方法
static Waypoint* nodeWithTheLocation(cocos2d::Point location);
bool initWithTheLocation(cocos2d::Point location);
//设置当前点的下一个路径点
void setNextWaypoint(Waypoint* waypoint);
//获取当前点的下一个路径点
Waypoint* getNextWaypoint();

//当前路径点位置
CC_SYNTHESIZE(cocos2d::Point,_myPosition,MyPosition);

private:
//下一个路径点
Waypoint* _nextWaypoint;
};
Waypoint.cpp:
Waypoint::Waypoint(
void)
{
_nextWaypoint
=NULL;
}
Waypoint::
~Waypoint(void)
{
}
Waypoint
* Waypoint::nodeWithTheLocation(cocos2d::Point location)
{
Waypoint
* pRet=new Waypoint();
if (pRet && pRet->initWithTheLocation(location))
{
pRet
->autorelease();
return pRet;
}
else
{
delete pRet;
pRet
=NULL;
return NULL;
}
}

bool Waypoint::initWithTheLocation(cocos2d::Point location)
{
bool bRet=false;
do
{
_myPosition
=location;
this->setPosition(Point::ZERO);
bRet
=true;
}
while (0);

return bRet;
}

void Waypoint::setNextWaypoint(Waypoint* waypoint)
{
_nextWaypoint
=waypoint;
}

Waypoint
* Waypoint::getNextWaypoint()
{
return _nextWaypoint;
}

第二步:在MainScene.h里声明如下代码

public:
……
//重写Layer的update方法
//我们主要在这个方法里实现色狼移动
virtual void update(float delta);

CREATE_FUNC(MainScene);

private:
//路径开始点
Waypoint *beginningWaypoint;
//路径目标点
Waypoint *destinationWaypoint;
//色狼的移动速度
float walkingSpeed;
//色狼当前位置
cocos2d::Vec2 myPosition;
//色狼大叔
cocos2d::Sprite* dsSprite;
//路径点集合
cocos2d::Vector wayPositions;
//判断2个点是否靠近
bool collisionWithCircle(cocos2d::Vec2 circlePoint,float radius,cocos2d::Vec2 circlePointTwo, float radiusTwo);

这里代码,也对之前代码进行了修改重构,比如把之前在init()方法里声明的dsSprite(色狼)改到了这里变成了一个全局变量,因为在后续的update方法中需要对它进行操作。

第二步:在MainScene.cpp的init()方法中创建路径点集合编写如下代码

……

   //获得色狼大叔的高
   float dsh=dsSprite->getTextureRect().size.height;

//初始化地图路径点集合
this->wayPositiOns= Vector();

//添加地图1号路径点到集合中
Waypoint *waypoint1=Waypoint::nodeWithTheLocation(Point(920, 435+dsh/2.0f));
if(this->wayPositions.size()>0)
{
//设置下一个节点
waypoint1->setNextWaypoint(this->wayPositions.back());
}
this->wayPositions.pushBack(waypoint1);
//添加地图2号路径点到集合中
Waypoint *waypoint2=Waypoint::nodeWithTheLocation(Point(762, 435+dsh/2.0f));
if(this->wayPositions.size()>0)
{
waypoint2
->setNextWaypoint(this->wayPositions.back());
}
this->wayPositions.pushBack(waypoint2);
//添加地图3号路径点到集合中
Waypoint *waypoint3=Waypoint::nodeWithTheLocation(Point(762, 360+dsh/2.0f));
if(this->wayPositions.size()>0)
{
waypoint3
->setNextWaypoint(this->wayPositions.back());
}
this->wayPositions.pushBack(waypoint3);
//添加地图4号路径点到集合中
Waypoint *waypoint4=Waypoint::nodeWithTheLocation(Point(685, 360+dsh/2.0f));
if(this->wayPositions.size()>0)
{
waypoint4
->setNextWaypoint(this->wayPositions.back());
}
this->wayPositions.pushBack(waypoint4);
//添加地图5号路径点到集合中
Waypoint *waypoint5=Waypoint::nodeWithTheLocation(Point(685, 116+dsh/2.0f));
if(this->wayPositions.size()>0)
{
waypoint5
->setNextWaypoint(this->wayPositions.back());
}
this->wayPositions.pushBack(waypoint5);
//添加地图6号路径点到集合中
Waypoint *waypoint6=Waypoint::nodeWithTheLocation(Point(520, 116+dsh/2.0f));
if(this->wayPositions.size()>0)
{
waypoint6
->setNextWaypoint(this->wayPositions.back());
}
this->wayPositions.pushBack(waypoint6);
//添加地图7号路径点到集合中
Waypoint *waypoint7=Waypoint::nodeWithTheLocation(Point(520, 180+dsh/2.0f));
if(this->wayPositions.size()>0)
{
waypoint7
->setNextWaypoint(this->wayPositions.back());
}
this->wayPositions.pushBack(waypoint7);
//添加地图8号路径点到集合中
Waypoint *waypoint8=Waypoint::nodeWithTheLocation(Point(285, 180+dsh/2.0f));
if(this->wayPositions.size()>0)
{
waypoint8
->setNextWaypoint(this->wayPositions.back());
}
this->wayPositions.pushBack(waypoint8);
//添加地图9号路径点到集合中
Waypoint *waypoint9=Waypoint::nodeWithTheLocation(Point(285, 268+dsh/2.0f));
if(this->wayPositions.size()>0)
{
waypoint9
->setNextWaypoint(this->wayPositions.back());
}
this->wayPositions.pushBack(waypoint9);
//添加地图10号路径点到集合中
Waypoint *waypoint10=Waypoint::nodeWithTheLocation(Point(204, 268+dsh/2.0f));
if(this->wayPositions.size()>0)
{
waypoint10
->setNextWaypoint(this->wayPositions.back());
}
this->wayPositions.pushBack(waypoint10);
//添加地图11号路径点到集合中
Waypoint *waypoint11=Waypoint::nodeWithTheLocation(Point(204, 350+dsh/2.0f));
if(this->wayPositions.size()>0)
{
waypoint11
->setNextWaypoint(this->wayPositions.back());
}
this->wayPositions.pushBack(waypoint11);
//添加地图12号路径点到集合中
Waypoint *waypoint12=Waypoint::nodeWithTheLocation(Point(50, 350+dsh/2.0f));
if(this->wayPositions.size()>0)
{
waypoint12
->setNextWaypoint(this->wayPositions.back());
}
this->wayPositions.pushBack(waypoint12);
……

第三步:在MainScene.cpp的init()方法中初始化几个变量以及精灵的初始位置编写如下代码

 ……
//获取集合中的最后一个点,12号点
Waypoint *waypoint0=wayPositions.back();
//设置运动的开始点
beginningWaypoint=waypoint0;
//设置运动的目标点为12号点的下一个点,11号点
destinatiOnWaypoint=waypoint0->getNextWaypoint();
//设置色狼当前位置值
myPosition=waypoint0->getMyPosition();
//设置色狼在地图的初始位置
dsSprite->setPosition(myPosition);
//设置女主角在地图的初始位置,为集合中的1号点
nhSprite->setPosition(wayPositions.front()->getMyPosition());
//设置移动速度
this->walkingSpeed=0.2f;
//定时器
this->scheduleUpdate();
……

第四步:在MainScene.cpp中对collisionWithCircle方法进行实现编写如下代码

//判断2个圆点是否靠近
//circlePoint:第一个圆点坐标
//radius:第一个圆半径
//circlePointTwo:第二个圆点坐标
//radiusTwo:第二个圆半径
bool MainScene::collisionWithCircle(cocos2d::Vec2 circlePoint,float radius,cocos2d::Vec2 circlePointTwo, float radiusTwo)
{
//2点间距离公式计算
float xdif = circlePoint.x - circlePointTwo.x;
float ydif = circlePoint.y - circlePointTwo.y;
float distance = sqrt(xdif * xdif + ydif * ydif);

if(distance <= radius + radiusTwo)
{
return true;
}
return false;
}

第五步:在MainScene.cpp中对update方法进行实现:

//判断色狼大叔是否和目标点碰到
if (this->collisionWithCircle(myPosition,1,destinationWaypoint->getMyPosition(),1) )
{
//是否还有下一个目标点
if (destinationWaypoint->getNextWaypoint())
{
//重新设定开始点和目标点
beginningWaypoint=destinationWaypoint;
destinationWaypoint
=destinationWaypoint->getNextWaypoint();
}
}
//获取目标点的坐标
Point targetPoint=destinationWaypoint->getMyPosition();
//计算目标点的向量
Point normalized=Point(targetPoint.x-myPosition.x,targetPoint.y-myPosition.y).getNormalized();

//根据速度和向量分别计算x,y方式上的偏移值
float ox=normalized.x * walkingSpeed;
float oy=normalized.y *walkingSpeed;
myPosition
= Point(myPosition.x + ox, myPosition.y +oy);
//重新设定色狼的位置实现移动
dsSprite->setPosition(myPosition);

第六步:运行测试游戏效果,看看色狼会不会沿着我们设定的路径移动。

Windows下的效果

在看看android手机下的效果,把新加的2个cpp文件添加到Android.mk文件里然后开始编译打包so文件(不会请参考:Cocos2dx.3x入门三部曲-Hello Game项目解析(三)篇)。完成打包后在eclipse中连接手机运行看到如下效果:

发现在真机上运行时女主角、色狼的位置相当于道路都有点偏上了,并且好像背景地图也没有显示全背景的顶部和底部有一部分没有显示出来,但是在windows下运行确正常,这个是什么原因呢,该怎么调整呢?我的手机分辨率是:960x540 而我们的地图素材图片分辨率是:960x640,所以导致了这个问题,这个是关于不同手机屏幕分辨率适配问题,在下一篇中我们将继续的完善修改这个游戏原型解决这个问题。

作者交流QQ:2303452599

           邮箱:mymoney1001@126.com



推荐阅读
  • 在Ubuntu 16.04 LTS上配置Qt Creator开发环境
    本文详细介绍了如何在Ubuntu 16.04 LTS系统中安装和配置Qt Creator,涵盖了从下载到安装的全过程,并提供了常见问题的解决方案。 ... [详细]
  • Docker的安全基准
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文介绍如何在 Android 中通过代码模拟用户的点击和滑动操作,包括参数说明、事件生成及处理逻辑。详细解析了视图(View)对象、坐标偏移量以及不同类型的滑动方式。 ... [详细]
  • 2023 ARM嵌入式系统全国技术巡讲旨在分享ARM公司在半导体知识产权(IP)领域的最新进展。作为全球领先的IP提供商,ARM在嵌入式处理器市场占据主导地位,其产品广泛应用于90%以上的嵌入式设备中。此次巡讲将邀请来自ARM、飞思卡尔以及华清远见教育集团的行业专家,共同探讨当前嵌入式系统的前沿技术和应用。 ... [详细]
  • 本文详细分析了JSP(JavaServer Pages)技术的主要优点和缺点,帮助开发者更好地理解其适用场景及潜在挑战。JSP作为一种服务器端技术,广泛应用于Web开发中。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 解决PHP与MySQL连接时出现500错误的方法
    本文详细探讨了当使用PHP连接MySQL数据库时遇到500内部服务器错误的多种解决方案,提供了详尽的操作步骤和专业建议。无论是初学者还是有经验的开发者,都能从中受益。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
author-avatar
手机用户2602930391
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有