这个系列是准备把之前写的一个挂机游戏的代码整理一下,改成一个ARPG游戏。
一、游戏开始
1 | function gameInit(qqpost){ |
其中myloading
是自己写的加载模块,allResource
中保存了所有资源的路径,因为使用了plist,所以区分开了plist和其他资源。PlayerCache中预先把动画的图片加载了进来,创建好action对象。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49var PlayerCache = cc.Class.extend({
actionMap: null,
ctor: function(){
var self = this;
self.actionMap = {};
},
init: function(){
var
self = this,
dirctions = [0, 1, 2, 3, 4, 5, 6, 7],
actions = ['idel', 'move'];
for(var dirction in dirctions){
for(var action in actions){
self.initAction(dirctions[dirction], actions[action], "player");
}
}
},
initAction: function(dirction, action, type){
var
self = this,
animFrames = [],
i = 0;
while(1){
var
key = type + "_" + dirction + "_" + action,
frameName = key + "_" + i + ".png",
frame = cc.spriteFrameCache.getSpriteFrame(frameName);
if(frame){
animFrames.push(frame);
var animation = cc.Animation.create(animFrames, 0.1);
self.actionMap[key] = animation;
}else{
if(i == 0){
cc.log("no action: " + frameName);
}
break;
}
i++;
}
}
});
PlayerCache._instance = null;
PlayerCache.getInstance = function(){
if(PlayerCache._instance == null){
PlayerCache._instance = new PlayerCache();
}
return PlayerCache._instance;
};
module.exports = PlayerCache;
这里人物的图片分为八个方向,两种状态,每个方向的状态有大概八帧画面,PlayerCache
将这些图片依次读取下来,创建好动画对象保存下来。
二、游戏场景
在start事件中运行的场景,就是主要游戏场景GameScene
。1
2
3
4
5
6
7
8
9
10
11GameScene = cc.Scene.extend({
ctor: function(){
var self = this;
self._super();
self.initMapBg();
},
onEnter: function(){
var self = this;
self._super();
}
});
先初始化大地图背景,在initMapBg
方法中,先要绘制地图层。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16GameScene = cc.Scene.extend({
...
...
initMapBg: function(){
var self = this;
// 创建地图
self.map_layer = cc.Layer.create();
self.map_layer.setAnchorPoint(0, 0);
self.addChild(self.map_layer);
// 添加地图图片到地图涂层
var map_bg_sp = cc.Sprite.create(allResource.others["map_bg"]);
map_bg_sp.setAnchorPoint(0, 0);
self.map_layer.addChild(map_bg_sp);
}
});
然后为地图添加点击事件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// 添加地图点击效果到地图层
self.map_click_sp = cc.Sprite.create();
self.map_layer.addChild(self.map_click_sp);
//为地图添加点击事件
var mapTouchFun = cc.EventListener.create({
event: cc.EventListener.TOUCH_ONE_BY_ONE,
swallowTouches: true,
onTouchBegan: function(touch, event){
var
target = event.getCurrentTarget(),
pos = self.map_layer.convertTouchToNodeSpace(touch),
paths = aStarSearch.getPath(mapObject.getBlockXY(self.player.getPosition()), mapObject.getBlockXY(pos), mapObject.mapArray);
if(!paths || paths.length == 0){
//目标点不可到达
}
// 播放移动效果
}
});
cc.eventManager.addListener(mapTouchFun, map_bg_sp);
点击地图后,先要判断点击的地点是否可以到达,这个判断整合到了aStarSearch
模块中去做。mapObject
这个对象中是地图的数据,把整个大地图分块为长度32的正方形,getBlockXY
方法是将点击的像素值,转化为分块的坐标值。
然后调用getPath
方法获得路径数组,如果目标地点不可到达,要在点击的地方播放一个无效的动画。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16if(!paths || paths.length == 0){
//目标点不可到达
var effectAnimation = PlayerCache.getInstance().getAnimation('click_move_disable');
self.map_click_sp.stopAllActions();
self.map_click_sp.runAction(cc.sequence([
cc.callFunc(function(){
self.map_click_sp.setPosition(pos);
self.map_click_sp.setVisible(true);
}),
cc.Animate.create(effectAnimation),
cc.delayTime(0.1),
cc.callFunc(function(){
self.map_click_sp.setVisible(false);
})
]));
}
如果目标地点可用,则先在点击地点播放一个成功的反馈动画,然后根据路径数组path
分别执行player
的moveTo
和场景的getMapMoveto
方法,获得执行动画所需要的对应数据结构,同时移动角色和地图。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19var effectAnimation = PlayerCache.getInstance().getAnimation('click_move_effect');
self.map_click_sp.stopAllActions();
self.map_click_sp.runAction(cc.sequence([
cc.callFunc(function(){
self.map_click_sp.setPosition(pos);
self.map_click_sp.setVisible(true);
}),
cc.Animate.create(effectAnimation),
cc.callFunc(function(){
self.map_click_sp.setVisible(false);
})
]));
//移动角色
self.player.moveTo(pos, paths, function(){
self.player.setPlayerStatus("idel");
});
//移动地图
self.map_layer.stopAllActions();
self.map_layer.runAction(self.getMapMoveto(pos, paths));
地图这里主要要处理一下边界的问题,如果人物移动到边界附近时,要判断一下,不要把地图移走。1
2
3
4
5
6
7
8
9
10
11
12
13
14getMapMoveto: function(point, paths){
point = mapObject.getBlockCenter(mapObject.getBlockXY(point));
var
self = this,
moveX = point.x,
moveY = point.y;
moveX = cc.visibleRect.width / 2 - moveX;
moveY = cc.visibleRect.height / 2 - moveY;
if(moveX > 0){moveX = 0;}
if(moveY > 0){moveY = 0;}
if(moveX < cc.visibleRect.width - mapObject.mapWidth){moveX = cc.visibleRect.width - mapObject.mapWidth;}
if(moveY < cc.visibleRect.height - mapObject.mapHeight){moveY = cc.visibleRect.height - mapObject.mapHeight;}
return cc.moveTo(.3 * paths.length, cc.p(moveX, moveY));
}