1. 障碍物预制体的制作
障碍物主要是N和S状态的磁铁,制作NMagnetObstacle和NMagnetObstacle两个预制体。具体预制体制作请参见预制体制作。
2. 障碍物的产生
第一步:
在Game脚本中的onLoad函数里创建NMagnetObstaclePool和SMagnetObstaclePool,并向其中分别添加NMagnetObstacle和SMagnetObstacle预制体。这里添加了5个,意味着在同一时刻的场景中最多同时出现5个障碍物。
this.NMagnetObstaclePool = new cc.NodePool();
this.SMagnetObstaclePool = new cc.NodePool();
for(var i=0;i<5;i++){
this.NMagnetObstaclePool.put(cc.instantiate(this.NMagnetPrefab));
this.SMagnetObstaclePool.put(cc.instantiate(this.SMagnetPrefab));
}
//在场景中加入以下障碍物
this.spawnNMagnetObstacle(cc.p(this.node.width/6,600));
this.spawnSMagnetObstacle(cc.p(this.node.width/6,680));
this.spawnNMagnetObstacle(cc.p(this.node.width*5/6,500));
this.spawnNMagnetObstacle(cc.p(this.node.width*5/6,400));
this.spawnSMagnetObstacle(cc.p(this.node.width*5/6,800));
第二步:
在Game脚本里添加NMagnetObstacle和SMagnetObstacle预制体产生函数。注意,因为要随机产生障碍物,所以需要向函数传递位置参数pos。
//产生N磁铁
spawnNMagnetObstacle: function(pos){
var scene = cc.director.getScene();
var node = null;
// 使用给定的模板在场景中生成一个新节点
if (this.NMagnetObstaclePool.size() > 0) {
node = this.NMagnetObstaclePool.get(this); //
} else {
node = cc.instantiate(this.NMagnetPrefab);
}
node.parent = scene;
node.setPosition(pos);
node.getComponent('NMagnetObstacle').init(this);
},
//产生S磁铁
spawnSMagnetObstacle: function(pos){
var scene = cc.director.getScene();
var node = null;
// 使用给定的模板在场景中生成一个新节点
if (this.SMagnetObstaclePool.size() > 0) {
node = this.SMagnetObstaclePool.get(this); //
} else {
node = cc.instantiate(this.SMagnetPrefab);
}
node.parent = scene;
node.setPosition(pos);
node.getComponent('SMagnetObstacle').init(this);
},
在产生障碍物的函数中分别加入了node.getComponent(‘NMagnetObstacle’).init(this)和node.getComponent(‘SMagnetObstacle’).init(this)以便在NMagnetObstacle和SMagnetObstacle脚本里调用Game脚本的对象。
3. 障碍物产生的位置
分析
障碍物位置主要由Height和Width决定的。Height可以等于屏幕顶端的坐标,即this.node.Height。Width主要分左右。游戏场景被分成左,中、右三个部分。根据每部分宽度,确定障碍物出现的Width。在此小游戏中,Width的值为this.node.width/6和this.node.width*5/6两种。因此可以用随机数实现。
实现
实现代码如下。主要思路是产生一个0到1之间的额随机数,然后用0.5作为阈值进行二值化。可能有点小伙伴有疑问,产生的N和S磁铁应该也是随机的,所以应该在写一个随机产生障碍物种类的函数,其实有这个随机位置,就已经足够了,没必要在随机一个种类。
//产生新的磁铁的坐标
getNewMagnetPos:function () {
var x=cc.random0To1();//产生一个(0,1)之间的随机数
var randY = this.node.height;
var randX=null;
if(x<=0.5){
randX=this.node.width/6;
}
else{
randX=this.node.width*5/6;
}
this.currentY=randY;
return cc.p(randX,randY);
},
4. 障碍物的运动
运动
产生的障碍物需要以一定的速度由屏幕顶端运动到屏幕底端。在Game脚本的onLoad()函数里定义一个速度变量MagnetSpeed。创建一个NMagnetObstacle和一个SMagnetObstacle脚本,分别绑定到NMagnetObstacle预制体和SMagnetObstacle预制体。在脚本的update函数中改变预制体的height即可实现障碍物不断向下运动。
cc.Class({
extends: cc.Component,
properties: {
game: {
default: null,
serializable: false
}
},
onLoad () {
this.enabled = false;
},
// 初始化
init: function (game) {
this.game = game;
this.enabled = true;
},
reuse (game) {
this.init(game);
},
start () {
},
update (dt) {
this.node.y-=this.game.MagnetSpeed; // MagnetSpeed是Game脚本中定义的一个速度
},
});
加速
游戏的难度根据障碍物下落的速度改变。障碍的速度是慢慢加快的,只需要在Game脚本的update()函数里更新MagnetSpeed变量即可。
update (dt) {
this.MagnetSpeed+=dt/20;//具体的数值根据实际速度而定
},
5. 障碍物的销毁
销毁函数
销毁后产生一个新的节点。
//N障碍物销毁
desNMagnetObstacle: function(node){
this.NMagnetObstaclePool.put(node);//销毁该节点
this.spawnNMagnetObstacle(this.getNewMagnetPos());//产生一个新的节点
},
//S障碍物销毁
desSMagnetObstacle: function(node){
this.SMagnetObstaclePool.put(node);//销毁一个节点
this.spawnSMagnetObstacle(this.getNewMagnetPos());//产生一个新的节点
},
触发逻辑
方法一:位置
判断脚本中this.node.y值,当y到达屏幕底端时,调用desNMagnetObstacle(this.node)函数销毁该节点。
方法二:碰撞
本小游戏采用的是碰撞的方法。
第一步:添加碰撞分组。点击1-编辑,弹出分组管理窗口。然后添加window和MagnetObstacle两个Group,如2所示。在允许产生碰撞的分组配对矩阵,勾选window-MagnetObstacle,如3所示,表示允许window和MagnetObstacle分组下的所有物体产生碰撞。
第二步:给NMagnetObstacle添加碰撞。在下图1中选择NMagnetObstacle分组,然后添加BoxCollider碰撞组件,如2所示。设置Tag为3333,如3所示。设置Offset和Size,使其覆盖住NMagnetObstacle预制体,如4所示。
第三步:给SMagnetObstacle添加碰撞,方法同NMagnetObstacle。
第四步:给gamescence的canvas添加碰撞组件。位置位于屏幕底端,height为10,width为960。Tag设置为0。
第五步:分别给NMagnetObstacle和SMagnetObstacle注册碰撞检测事件。以NMagnetObstacle为例,在NMagnetObstacle脚本的onLoad()函数添加如下代码:
cc.director.getCollisionManager().enabled=true;
第六步:碰撞检测函数实现。以NMagnetObstacle为例:
onCollisionEnter: function(other,self){
if(other.tag === 0){//如果Tag为0,即到达屏幕底端
this.game.desNMagnetObstacle(this.node);//销毁
}
},
至此,可以实现左右障碍物的随机产生、向下运动和销毁。