【Cocos Creator实战教程(8)】——打砖块(物理引擎)
转自:http://blog.csdn.net/potato47/article/details/73197021 失踪人口回归
新建一个工程,取名叫做brick-breaker,brick是什么意思呢,就是砖块的意思,每次给工程起名字,我都能学会一个新单词。 目录结构如下: game场景,设置Canvas 先搭一个游戏背景 再建一个物理层,用来装游戏里的带有物理属性的东西,设置锚点为左下角 又到了学单词的时间,请拿出你们的小本本: wall:墙//小球碰到就会反弹的那种墙 这个wall肯定是要有碰撞属性的,在属性面板,添加一个物理组件 因为我们的墙有上,左,右三面,所以再添加三个碰撞组件(一个节点可以有多个碰撞组件)。 编辑一下 地面同理,小球同理,托盘同理 现在已经编辑了几个物理节点的碰撞包围盒,但还没有编辑他们的物理属性(cc.RigidBody) 先从小球开始,点击ball节点,在属性检查器可以看到 把第一个参数勾选,代表启用碰撞回调,可以在脚本里写回调函数 Bullet:高速运动的物体开启,避免穿透,这里不用勾选 type选择Dynamic,
为什么不选kinematic呢?留个作业。 Gravity Scale设置为0(标准是1,数值代表比例),也就是没有重力。 设置线速度(1000,1000)
因为小球是我们的主角,左右的碰撞都是对球来说的,所以碰撞属性都在小球这一方设置就可以了。 另外要设置wall,ground,paddle,brick的type为static 下面来看脚本 BrickLayout.js cc.Class({
extends: cc.Component,properties: {
padding: 0,spacing: 0,cols: 0,brickPrefab: cc.Prefab,bricksNumber: 0,},init(bricksNumber) {
this.node.removeAllChildren();
this.bricksNumber = bricksNumber;
for (let i = 0; i < this.bricksNumber; i++) {
let brickNode = cc.instantiate(this.brickPrefab);
brickNode.parent = this.node;
brickNode.x = this.padding + (i % this.cols) * (brickNode.width + this.spacing) + brickNode.width / 2;
brickNode.y = -this.padding - Math.floor(i / this.cols) * (brickNode.height + this.spacing) - brickNode.height / 2;
}
}
});
自己写了一个动态添加砖块的布局脚本,传入需要添加的砖块数量就可以动态加入的布局节点中。 BrickPrefab长这样,我就默认你会做prefab了 OverPanel.js cc.Class({
extends: cc.Component,properties: {
resultLabel:cc.Label,scoreLabel:cc.Label,// use this for initialization
onLoad: function () {
},init(gameCtl){
this.gameCtl = gameCtl;
this.node.active = false;
},show(score,isWin){
this.node.active = true;
if(isWin){
this.resultLabel.string = 'YOU WIN!';
}else{
this.resultLabel.string = 'YOU LOSE!';
}
this.scoreLabel.string = score+'';
},onBtnRestart(){
this.gameCtl.startGame();
}
});
结束界面 Paddle.js cc.Class({
extends: cc.Component,onLoad: function () {
this.node.parent.on("touchmove",(event) => {
//将世界坐标转化为本地坐标
let touchPoint = this.node.parent.convertToNodeSpace(event.getLocation());
this.node.x = touchPoint.x;
});
},init(){
this.node.x = 360;
}
});
托盘随着手指移动 Ball.js cc.Class({
extends: cc.Component,properties: {
},init(gameCtl) {
this.gameCtl = gameCtl;
this.node.position = cc.v2(360,270);//初始化位置
this.getComponent(cc.RigidBody).linearVelocity = cc.v2(800,800);//初始化速度
},onBeginContact(contact,self,other) {
switch (other.tag) {
case 1://球碰到砖块
this.gameCtl.onBallContactBrick(self.node,other.node);
break;
case 2://球碰到地面
this.gameCtl.onBallContactGround(self.node,other.node);
break;
case 3://球碰到托盘
this.gameCtl.onBallContactPaddle(self.node,other.node);
break;
case 4://球碰到墙
this.gameCtl.onBallContactWall(self.node,other.node);
break;
}
},});
球碰到其他物体,让gameCtl处理 GameCtl.js const GameModel = require('GameModel');
cc.Class({
extends: cc.Component,properties: {
gameView: require('GameView'),ball: require('Ball'),paddle: require('Paddle'),brickLayout: require('BrickLayout'),overPanel: require('OverPanel'),// use this for initialization
onLoad: function () {
//安卓返回键退出
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN,(event) => { if (event.keyCode === cc.KEY.back) { cc.director.end(); } }); this.physicsManager = cc.director.getPhysicsManager(); this.gameModel = new GameModel(); this.startGame(); },//this.physicsManager.debugDrawFlags =0; // cc.PhysicsManager.DrawBits.e_aabbBit | // cc.PhysicsManager.DrawBits.e_pairBit | // cc.PhysicsManager.DrawBits.e_centerOfMassBit | // cc.PhysicsManager.DrawBits.e_jointBit | // cc.PhysicsManager.DrawBits.e_shapeBit // ; init() { this.physicsManager.enabled = true; this.gameModel.init(); this.gameView.init(this); this.ball.init(this); this.paddle.init(); this.brickLayout.init(this.gameModel.bricksNumber); this.overPanel.init(this); },startGame() { this.init(); },pauseGame() { this.physicsManager.enabled = false; },resumeGame() { this.physicsManager.enabled = true; },stopGame() { this.physicsManager.enabled = false; this.overPanel.show(this.gameModel.score,this.gameModel.bricksNumber === 0); },onBallContactBrick(ballNode,brickNode) { brickNode.parent = null; this.gameModel.addScore(1); this.gameModel.minusBrick(1); this.gameView.updateScore(this.gameModel.score); if (this.gameModel.bricksNumber <= 0) { this.stopGame(); } },onBallContactGround(ballNode,groundNode) { this.stopGame(); },onBallContactPaddle(ballNode,paddleNode) { },onBallContactWall(ballNode,brickNode) { },onDestroy() { this.physicsManager.enabled = false; } });
GameCtl挂在Canvas上,保证第一个执行,将对应的组件拖入 GameView.js cc.Class({
extends: cc.Component,properties: {
scoreLabel:cc.Label,init(gameCtl){
this.gameCtl = gameCtl;
this.scoreLabel.string = '0';
},updateScore(score){
this.scoreLabel.string = score;
}
});
GameModel.js cc.Class({
extends: cc.Component,properties: {
score:0,bricksNumber:0,init(){
this.score = 0;
this.bricksNumber = 50;
},addScore(score){
this.score += score;
},minusBrick(n){
this.bricksNumber -= n;
},221);">
尝试着写的mvc,并不规范,简单的理解就是,model和view分离,沟通都通过control。 逻辑清楚的代码是不需要过多讲解的,对吧,对的。 源码在此:https://github.com/potato47/brick-breaker-master 游戏试玩:http://119.29.40.244/brick-breaker/ 关爱失踪人口: 《毕业前的程序员》系列正在更新。。。如果你不关注,你就会错过一个天才的成长历程。。。233 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Ajax 表单验证 实现代码
- Cocos2d-x:编译Coco2d-x android 程序出现make: *** No ru
- c# – 如何将委托R函数(T t)转换为Func?
- React Native View 组件通过阴影渲染实现组件浮现效果
- react-native运行时出现java.lang.RuntimeException: SDK l
- ruby-on-rails – Rails 3 I18:缺少翻译:da.datetime.dis
- Swift--基本数据类型(二)
- ios – @synthesize不再自动添加到.m文件中?
- c# – ASP.NET MVC和MemoryCache – 我该如何使用它?
- Redis进阶实践之十四 Redis-cli命令行工具使用详解第一部分