一、遊戲的分析(之前沒有接觸過小遊戲,制作的思維還停留在大型ARPG遊戲大家共同協作的想法裡,但是小遊戲講究小而全,大部分時間是一個人獨立開發,所以需要迫使自己養成看到小遊戲先拆分細化的思想)
二、一些必要的參數
台階參數
1: 設置分辨率: 720x1280
2: 台階的原點:
3: 配置好4個中心點,如果跳到就到4個中心點,否則就失敗;
4: 編寫代碼獲得中心點的位置,來初始化Player;
5: 斜率: 0.5560472, 與平行四邊形相當;
6: 塊開始的世界坐标的位置: (180, 350)
參數
1: 監聽事件,開啟蓄積能量, 2秒縮放到0.5;
2: 0.5秒内,scale變形到1;
3: 0.5秒内, 旋轉一周;
4: 0.5秒内,跳躍到目的地;
5: 能量蓄積: 加速度: power: 600, 初始化: 150;
this.speed = dt * this.power;
this.jumpDistance = this.speed * dt;
6:帶上拖尾:
MotionStreak組件: 配置好圖片;(引擎bug,父節點移動,帶有拖尾的子節點顯示效果就會有問題,待解決)
7: ancher_offset: 100
8: 生成地圖: 200, 400的距離随機
9: 地圖滾動參數: y, 随着玩家滾動, x 取最左值和最右值(180, 580);
10:開始位置(180, 350)
三、實現的步驟
1 調整好player,具有旋轉和壓縮兩個動畫
2 實現跳躍,前置條件是有東西可跳,所以要先制作兩個塊
3 制作塊,設置塊的原點,中心點,前後左右點(主要是做跳躍檢測,使用小色塊),currblock nextBlock
4 開始寫game_scene.js腳本
綁定player和block
固定第一個block(坐标轉換)
添加第二個block (add_block方法)
5 調整第一個塊和player的位置
6 實現player的跳躍方法player_jump,以及block的檢測方法is_jump_on_block
7 實現地圖滾動方法move_map
8 完善遊戲代碼
四、代碼
game_scene.js
//game_scene.js
cc.Class({
extends: cc.Component,
properties: {
// foo: {
// // ATTRIBUTES:
// default: null, // The default value will be used only when the component attaching
// // to a node for the first time
// type: cc.SpriteFrame, // optional, default is typeof default
// serializable: true, // optional, default is true
// },
// bar: {
// get () {
// return this._bar;
// },
// set (value) {
// this._bar = value;
// }
// },
player: {
type: cc.Node,
default: null
},
block_prefabs: {
type: cc.Prefab,
default: []
},
block_root: {
default: null,
type: cc.Node
},
left_org: cc.v2(0, 0),
map_root: {
default: null,
type: cc.Node
},
y_radio: 0.5560472,
checkout: {
type: cc.Node,
default: null
}
},
// LIFE-CYCLE CALLBACKS:
// onLoad () {},
start() {
this.block_list = [];
this.cur_block = cc.instantiate(this.block_prefabs[Math.floor(Math.random() * this.block_prefabs.length)]);
this.block_root.addChild(this.cur_block);
// 将第一個塊的位置設置為初始位置
this.cur_block.setPosition(this.block_root.convertToNodeSpaceAR(this.left_org));
var w_pos = this.cur_block.getChildByName('mid').convertToWorldSpaceAR(cc.v2(0, 0));
this.player.setPosition(this.map_root.convertToNodeSpaceAR(w_pos));
this.next_block = this.cur_block;
this.player_comp = this.player.getComponent("player");
this.block_zOrder = -1;
this.add_block();
},
add_block: function() {
this.cur_block = this.next_block;
this.next_block = cc.instantiate(this.block_prefabs[Math.floor(Math.random() * this.block_prefabs.length)]);
this.block_root.addChild(this.next_block);
this.next_block.zIndex = this.block_zOrder;
this.block_zOrder--;
var x_distance = 200 Math.random() * 200;
var y_distance = x_distance * this.y_radio;
var next_pos = this.cur_block.getPosition();
next_pos.x = x_distance * this.player_comp.direction;
next_pos.y = y_distance;
this.next_block.setPosition(next_pos);
this.player_comp.set_next_block(this.next_block.getComponent("block"));
// 删除block
this.block_list.push(this.next_block);
if (this.block_list.length >= 5) {
for (var i = 0; i < 2; i ) {
var block = this.block_list.shift();
block.destroy();
}
}
},
// 地圖滾動
move_map(offset_x, offset_y) {
var m1 = cc.moveBy(0.5, offset_x, offset_y);
var end_func = cc.callFunc(function() {
this.add_block();
}.bind(this));
var seq = cc.sequence([m1, end_func]);
this.map_root.runAction(seq);
},
on_checkout_game: function() {
this.checkout.active = true;
},
on_game_again: function() {
cc.director.loadScene("game_scene");
},
// update (dt) {},
});
player.js
// player.js
var game_scene = require("game_scene");
cc.Class({
extends: cc.Component,
properties: {
// foo: {
// // ATTRIBUTES:
// default: null, // The default value will be used only when the component attaching
// // to a node for the first time
// type: cc.SpriteFrame, // optional, default is typeof default
// serializable: true, // optional, default is true
// },
// bar: {
// get () {
// return this._bar;
// },
// set (value) {
// this._bar = value;
// }
// },
init_speed: 150,
a_power: 600,
y_radio: 0.5560472,
game_manager: {
type: game_scene,
default: null
},
},
// LIFE-CYCLE CALLBACKS:
onLoad() {
this.next_block = null;
this.direction = 1;
},
start() {
this.rot_node = this.node.getChildByName("rotate");
this.anima_node = this.rot_node.getChildByName("anima");
this.is_power_mode = false;
this.speed = 0;
this.x_distance = 0;
this.anima_node.on(cc.Node.EventType.TOUCH_START, function(e) {
this.is_power_mode = true;
this.x_distance = 0;
this.speed = this.init_speed;
this.anima_node.stopAllActions();
this.anima_node.runAction(cc.scaleTo(2, 1, 0.5));
}.bind(this), this);
this.anima_node.on(cc.Node.EventType.TOUCH_END, function(e) {
this.is_power_mode = false;
this.anima_node.stopAllActions();
this.anima_node.runAction(cc.scaleTo(0.5, 1, 1));
this.player_jump();
}.bind(this), this);
this.anima_node.on(cc.Node.EventType.TOUCH_CANCEL, function(e) {
this.is_power_mode = false;
this.anima_node.stopAllActions();
this.anima_node.runAction(cc.scaleTo(0.5, 1, 1));
this.player_jump();
}.bind(this), this);
},
update(dt) {
if (this.is_power_mode) {
this.speed = (this.a_power * dt);
this.x_distance = this.speed * dt;
}
},
player_jump: function() {
var x_distance = this.x_distance * this.direction;
var y_distance = this.x_distance * this.y_radio;
var target_pos = this.node.getPosition();
target_pos.x = x_distance;
target_pos.y = y_distance;
// 跳躍時候旋轉
this.rot_node.runAction(cc.rotateBy(0.5, -360 * this.direction));
var w_pos = this.node.parent.convertToWorldSpaceAR(target_pos);
var is_game_over = false;
if (this.next_block.is_jump_on_block(w_pos, this.direction)) {
target_pos = this.node.parent.convertToNodeSpaceAR(w_pos);
} else {
is_game_over = true;
}
var j = cc.jumpTo(0.5, target_pos, 200, 1);
this.direction = (Math.random() < 0.5) ? -1 : 1;
var end_func = cc.callFunc(function() {
if (is_game_over) {
this.game_manager.on_checkout_game();
} else {
if (this.direction === -1) {
this.game_manager.move_map(580 - w_pos.x, -y_distance);
} else {
this.game_manager.move_map(180 - w_pos.x, -y_distance);
}
}
}.bind(this));
var seq = cc.sequence(j, end_func);
this.node.runAction(seq);
},
set_next_block(block) {
this.next_block = block;
},
});
block.js
// block.js
cc.Class({
extends: cc.Component,
properties: {
// foo: {
// // ATTRIBUTES:
// default: null, // The default value will be used only when the component attaching
// // to a node for the first time
// type: cc.SpriteFrame, // optional, default is typeof default
// serializable: true, // optional, default is true
// },
// bar: {
// get () {
// return this._bar;
// },
// set (value) {
// this._bar = value;
// }
// },
},
start() {
this.mid = this.node.getChildByName("mid");
this.up = this.node.getChildByName("up");
this.down = this.node.getChildByName("down");
this.left = this.node.getChildByName("left");
this.right = this.node.getChildByName("right");
},
// dir 1右跳 -1左跳
is_jump_on_block(w_dst_pos, direction) {
var mid_pos = this.mid.convertToWorldSpaceAR(cc.v2(0, 0));
var dir = w_dst_pos.sub(mid_pos);
var min_len = dir.mag();
var min_pos = mid_pos;
if (direction === 1) {
var up_pos = this.up.convertToWorldSpaceAR(cc.v2(0, 0));
dir = w_dst_pos.sub(up_pos);
var len = dir.mag();
if (min_len > len) {
min_len = len;
min_pos = up_pos;
}
var down_pos = this.down.convertToWorldSpaceAR(cc.v2(0, 0));
dir = w_dst_pos.sub(down_pos);
var len = dir.mag();
if (min_len > len) {
min_len = len;
min_pos = down_pos;
}
} else {
var left_pos = this.left.convertToWorldSpaceAR(cc.v2(0, 0));
dir = w_dst_pos.sub(left_pos);
var len = dir.mag();
if (min_len > len) {
min_len = len;
min_pos = left_pos;
}
var right_pos = this.right.convertToWorldSpaceAR(cc.v2(0, 0));
dir = w_dst_pos.sub(right_pos);
var len = dir.mag();
if (min_len > len) {
min_len = len;
min_pos = right_pos;
}
}
// 找到跳躍位置距離參考點最近的那個點以及位置
dir = w_dst_pos.sub(min_pos);
if (dir.mag() < 100) {
w_dst_pos.x = min_pos.x;
w_dst_pos.y = min_pos.y;
return true;
}
return false;
},
});
作者:orxx
來源:博客園
聲明:發布此文是出于傳遞更多知識以供交流學習之目的。若有來源标注錯誤或侵犯了您的合法權益,請作者持權屬證明與我們聯系,我們将及時更正、删除,謝謝
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!