cocos creator 檯球小遊戲
阿新 • • 發佈:2018-12-09
所用平臺:cocos creator 所用語言:js
遊戲的實現點: 1.可碰撞物體:以白球、其他球、球袋、球杆、球桌分五類,使用creator內建的操作設定可產生碰撞的節點;新增剛體,以節點形狀選擇剛體形狀。以節點屬性選擇剛體型別是靜態還是動態,其中球袋要多設定一項:sensor,即不產生碰撞效果,只產生碰撞監測。 2.球杆的移動、拉伸:球杆要隨著白球為中心移動,為不接觸白球,要設定最小距離,達到此距離則隱藏。以點選點與白球中心得到一個向量,用得到的向量長度拉伸球杆並改變球杆衝量;向量和水平軸的夾角得到球杆旋轉度數。 3.白球進洞操作區別其他球:白球縮小尺寸,其他球則在完全隱藏,這樣可以繼續對白球的操作,同時,對其他球可以通過每幀執行一個函式:檢查球桌上是否還有其他球(除白球)來判斷遊戲勝利。
程式碼
- 掛在白球節點上
cc.Class({
extends: cc.Component,
properties: {
cue: {
type: cc.Node,
default: null,
},
max_dis: 100,
min_dis: 5, // 如果拖動的距離到白球的中心 < 這個距離,那麼我們就隱藏球杆,否者的話,顯示球杆;
},
start () {
this.body = this.getComponent(cc.RigidBody);
this .cue_inst = this.cue.getComponent("cue");
this.start_x = this.node.x;
this.start_y = this.node.y;
this.node.on(cc.Node.EventType.TOUCH_START, function(e) {
}.bind(this), this);
this.node.on(cc.Node.EventType.TOUCH_MOVE, function(e) {
var w_pos = e.getLocation();
var dst = this.node.parent.convertToNodeSpaceAR(w_pos);
//相對於this.node.parent(canvas)這個為參照物,AR為原點的座標,(假設)白球移動到移動到世界座標為 w_pos
//就是去獲得點選點的二維向量
var src = this.node.getPosition();//白球二維向量
var dir = cc.pSub(dst, src);//向量相減得到的一個方向向量
var len = cc.pLength(dir);
if (len < this.min_dis) {
this.cue.active = false; // 設定球杆為隱藏;
return;
}
if (len > this.max_dis) {
this.cue.active = false; // 設定球杆為隱藏;
return;
}
this.cue.active = true;
var r = Math.atan2(dir.y, dir.x);//得到弧度
var degree = r * 180 / Math.PI;
degree = 360 - degree;
this.cue.rotation = degree + 90; //旋轉球杆
var cue_pos = dst;
var cue_len_half = this.cue.width * 0.1;//本來cue的錨點在中心的,應該是* 0.5的
cue_pos.x += (cue_len_half * dir.x / len);
cue_pos.y += (cue_len_half * dir.y / len);//使得球杆好像在隨著點選點的後移向後拉
this.cue.setPosition(cue_pos);
}.bind(this), this);
this.node.on(cc.Node.EventType.TOUCH_END, function(e) {
if(this.cue.active === false) {
return;
}
this.cue_inst.shoot_at(this.node.getPosition());//朝白球方向射擊
}.bind(this), this);
this.node.on(cc.Node.EventType.TOUCH_CANCEL, function(e) {
if(this.cue.active === false) {
return;
}
this.cue_inst.shoot_at(this.node.getPosition());
}.bind(this), this);
},
reset: function() {
this.node.scale = 0.35;//當時加入的時候就是0.35
this.node.x = this.start_x;
this.node.y = this.start_y;
this.body.linearVelocity = cc.p(0, 0);//線性轉速
this.body.angularVelocity = 0;//角轉速
},
onBeginContact: function(contact, selfCollider, otherCollider) {
// 白球有可能,碰球杆,碰球,碰邊,球袋
if(otherCollider.node.groupIndex == 2) {
// 隔1秒一種,要把白球放回原處;
this.node.scale = 0;//消失
this.scheduleOnce(this.reset.bind(this), 1);//1秒後白球重置
// end
return;
}
},
// update (dt) {},
});
- 掛在其他球節點上
cc.Class({
extends: cc.Component,
// 屬性列表,它將會作為元件例項的資料成員,到元件裡面,繫結到我們的編輯器上;
properties: {
value: 1,
},
onLoad () {//每幀比update先
// this,指的就是當前的元件例項
},
start () {//初始化時
// this,指的就是當前的元件例項
this.body = this.getComponent(cc.RigidBody);//同一節點的其他元件
this.start_x = this.node.x;
this.start_y = this.node.y;
},
// dt: 距離上一次重新整理的時間;
update (dt) {//每幀
// this,指的就是當前的元件例項
},
reset: function() {
this.node.active = true;
this.node.x = this.start_x;
this.node.y = this.start_y;
this.body.linearVelocity = cc.p(0, 0);
this.body.angularVelocity = 0;
},
onBeginContact: function(contact, selfCollider, otherCollider) {
// 白球有可能,碰球杆,碰球,碰邊,球袋
if(otherCollider.node.groupIndex == 2) {
this.node.active = false;
return;
}
},
});
- 掛在canvas節點上的遊戲引擎
cc.Class({
extends: cc.Component,
properties: {
is_debug: false,
gravity: cc.p(0, -320),
},
// onLoad () {},
onLoad: function() {
cc.director.getPhysicsManager().enabled = true;
if(this.is_debug)
{
var Bits = cc.PhysicsManager.DrawBits;
cc.director.getPhysicsManager().debugDrawFlags = Bits.e_jointBit | Bits.e_shapeBit;
}
else
cc.director.getPhysicsManager().debugDrawFlags = 0;
cc.director.getPhysicsManager().gravity = this.gravity;
},
// update (dt) {},
});
- 掛在canvas節點上總場景
cc.Class({
extends: cc.Component,
properties: {
ball_root: {
type: cc.Node,
default: null,
},
w_ball: {
type: cc.Node,
default: null,
},
},
// onLoad () {},
start () {
this.is_game_started = true;
},
restart_game: function() {
for(var i = 0; i < this.ball_root.childrenCount; i ++) {
var b = this.ball_root.children[i];
b.getComponent("ball").reset();
}
this.w_ball.getComponent("w_ball").reset();
this.is_game_started = true;
},
check_game_over: function() {
for(var i = 0; i < this.ball_root.childrenCount; i ++) {
var b = this.ball_root.children[i];
if(b.active === true) {
return;
}
}
this.is_game_started = false; // game_over;
this.scheduleOnce(this.restart_game.bind(this), 3);
},
update (dt) {
if (!this.is_game_started) {
return;
}
// 是否所有的球都打入進去了;
},
});
掛在球杆節點上
cc.Class({
extends: cc.Component,
properties: {
SHOOT_POWER: 18, // 合適的值就可以了
},
// onLoad () {},
start () {
this.body = this.getComponent(cc.RigidBody);
},
shoot_at: function(dst) {
// 衝量: 給這個球杆一個方向的衝量,向量,大小,有方向;
// 方向問題: src---> dst;
var src = this.node.getPosition();//此時的球杆頭位置
var dir = cc.pSub(dst, src);//dst白球位置
// 大小問題;
var cue_len_half = this.node.width * 0.5;
var len = cc.pLength(dir);
var distance = len - cue_len_half;
// end
var power_x = distance * this.SHOOT_POWER * dir.x / len;
var power_y = distance * this.SHOOT_POWER * dir.y / len;
//對該點施加衝量 applyLinearImpulse(衝量大小向量, 球杆的原點轉成世界座標, true)
this.body.applyLinearImpulse(cc.p(power_x, power_y), this.node.convertToWorldSpaceAR(cc.p(0, 0)), true);
},
onPreSolve: function(contact, selfCollider, otherCollider) {
this.node.active = false;
},
// update (dt) {},
});