飞机打方块(二)游戏界面制作
一、背景
1.新建bg节点
二、飞机节点功能实现
1.移动
1.新建plane节点
2.新建脚本GameController.ts,并绑定Canvas
GameControll.ts
const { ccclass, property } = cc._decorator;@ccclass
export default class NewClass extends cc.Component {@property(cc.Node)canvas: cc.Node = null;@property({ type: cc.Node, displayName: "飞机(主角)", tooltip: "主角,也就是飞机节点" })plane: cc.Node = null;@property({ displayName: "飞机和炮弹是否能移动", tooltip: "飞机和炮弹是否能移动" })is_plane_move: boolean = true;onLoad() {//给Canvas绑定事件this.canvas.on(cc.Node.EventType.TOUCH_MOVE, this.onMove, this)}//移动飞机函数,当手指在屏幕上移动时将执行这个函数onMove(event: cc.Event.EventTouch) {//打印logconsole.log("手指在屏幕上移动了");/* //触摸点的坐标var pos = new cc.Vec2(event.getLocationX(), event.getLocationY())//转换坐标//将一个点转换到节点(局部)空间坐标系,这个坐标系以锚点为位置pos = this.canvas.convertToNodeSpaceAR(pos)//给飞机赋值this.plane.position = cc.v3(pos) *///获取触点在上一次事件时的位置对象,对象包含x和y属性if (this.is_plane_move == true) {let last_pos = event.getPreviousLocation();//获取触点位置let pos = event.getLocation()//做向量减法var dir = last_pos.sub(pos)//移动飞机的坐标this.plane.x -= dir.x;this.plane.y -= dir.y;}}update(dt: number): void{//屏幕上下左右,用来防止飞机飞出屏幕let l = (this.canvas.width / 2) + (this.plane.width / 2);let r = (this.canvas.width / 2) - (this.plane.width / 2);let t = (this.canvas.height / 2) - (this.plane.height / 2);let b = (this.canvas.height / 2) + (this.plane.height / 2);//超过边界检测if (this.plane.x > r) {this.plane.x = r;}if (this.plane.x < l) {this.plane.x = l;}if (this.plane.y > t) {this.plane.y = t;}if (this.plane.y < b) {this.plane.y = b;}}
}
三.子弹
1.新建粒子
2.新建Bullet脚本,新建bullet预制体
Game.ts
@property({ type: cc.Prefab, displayName: "炮弹预制体", tooltip: "炮弹的预制体,飞机每时每刻都在发射子弹" })bullet: cc.Prefab = null;@property({ displayName: "炮弹生成左侧坐标", tooltip: "炮弹生成左侧坐标,以飞机锚点为原点建立坐标系时炮弹的位置" })bullet_left_pos: cc.Vec2 = null;@property({ displayName: "炮弹生成右侧坐标", tooltip: "炮弹生成右侧坐标,以飞机锚点为原点建立坐标系时炮弹的位置" })bullet_right_pos: cc.Vec2 = null;@property({ type: cc.Float, displayName: "每秒发射几个炮弹", tooltip: "每秒发射几个炮弹,这个值是始终不变的,当这个值过大时,设备会明显卡顿" })bullet_num: number = 10;@property({ type: cc.Float, displayName: "炮弹发射速度", tooltip: "子弹发射速度,单位是每秒发射多少个像素,吃到buff会提高" })bullet_speed: number = 100;@property({ type: cc.Float, displayName: "炮弹攻击力", tooltip: "攻击力,炮弹打到障碍物时减少的生命值,吃到buff会提高" })ATK: number = 2;@property({ displayName: "是否可以发射炮弹", tooltip: "是否可以发射炮弹,为false时飞机将不再发射炮弹" })is_fire: boolean = true@property({ displayName: "飞机和炮弹是否能移动", tooltip: "飞机和炮弹是否能移动" })is_plane_move: boolean = true;//生成飞机左侧炮弹用的变量l: number = 0;//生成飞机右侧炮弹用的变量r: number = 0update(dt: number): void {//炮弹生成let time = 1 / this.bullet_num;//飞机左侧炮弹生成this.l += dt;if (this.l > time && this.is_fire == true) {//打印logconsole.log("生成左侧炮弹");//清零this.l = 0;//创建炮弹this.create_bullet(cc.v3(this.bullet_left_pos))}//飞机右侧炮弹生成this.r += dtif (this.r > time && this.is_fire == true) {console.log("飞机右侧炮弹生成");this.r = 0;this.create_bullet(cc.v3(this.bullet_right_pos))}}//生成炮弹函数,pos以飞机锚点为原点建立坐标系时炮弹的位置create_bullet(pos: cc.Vec3) {//实例化新节点let node = cc.instantiate(this.bullet);//父节点为canvasnode.parent = this.canvas;//获取xlet x = pos.x + this.plane.x;//获取ylet y = pos.y + this.plane.y;//将坐标转换let p = this.canvas.convertToNodeSpaceAR(cc.v3(x, y))//求出最终坐标let position: cc.Vec3 = cc.v3(p.x + (this.canvas.width / 2), p.y + (this.canvas.height / 2))//赋值node.position = cc.v3(position);}
Bullet.ts:
const { ccclass, property } = cc._decorator;@ccclass
export default class NewClass extends cc.Component {//子弹速度speed: number = 100;//子弹攻击力ATK: number = 2;onLoad(): void {//获取GameController脚本let gc = cc.find("Canvas").getComponent("GameController");//获取速度和攻击力并赋值let speed: number = gc.bullet_speed;let ATK: number = gc.ATK;this.speed = speed;this.ATK = ATK;}update(dt: number) {//获取GameController脚本let gc = cc.find("Canvas").getComponent("GameController");//自身移动if (gc.is_plane_move == true) {this.node.y += dt * this.speed;}//获取canvas节点let canvas = cc.find("Canvas");//如果自身到了屏幕最上方if (this.node.y >= (canvas.height / 2) + (this.node.height / 2)) {this.node.destroy();console.log("子弹超出了屏幕,自动销毁");}}
}
3.子弹信息显示:
1.新建state_lb_parent节点:
2.新建Label节点
绑定Canvas
GameController.ts
@property({ type: cc.Label, displayName: "显示状态的文字", tooltip: "显示状态的文字,显示射速,攻击力,两个label前后位置无所谓" })state_lb: cc.Label[] = [];update(dt: number): void {//炮弹生成let time = 1 / this.bullet_num;//飞机左侧炮弹生成this.l += dt;if (this.l > time && this.is_fire == true) {//打印logconsole.log("生成左侧炮弹");//清零this.l = 0;//创建炮弹this.create_bullet(cc.v3(this.bullet_left_pos))}//飞机右侧炮弹生成this.r += dtif (this.r > time && this.is_fire == true) {console.log("飞机右侧炮弹生成");this.r = 0;this.create_bullet(cc.v3(this.bullet_right_pos))}//显示状态//子弹射速let speed = Math.floor(this.bullet_speed);//子弹攻击力let ATK = Math.floor(this.ATK)//如果速度不为满级正常显示if (this.bullet_speed < 10000) {this.state_lb[0].string = "子弹射速:" + speed;}//如果速度不为满级正常显示else {this.state_lb[0].string = "子弹射速:Max";}this.state_lb[1].string = "子弹攻击力:" + ATK;}
四、显示分数
1.新建摄像机
2.新建节点
GameController.ts
@property({ type: cc.Label, displayName: "显示分数文字", tooltip: "显示分数的文字" })score_lb: cc.Label = null;//分数score: number = 0;update(dt: number): void {//炮弹生成let time = 1 / this.bullet_num;//飞机左侧炮弹生成this.l += dt;if (this.l > time && this.is_fire == true) {//打印logconsole.log("生成左侧炮弹");//清零this.l = 0;//创建炮弹this.create_bullet(cc.v3(this.bullet_left_pos))}//飞机右侧炮弹生成this.r += dtif (this.r > time && this.is_fire == true) {console.log("飞机右侧炮弹生成");this.r = 0;this.create_bullet(cc.v3(this.bullet_right_pos))}//显示状态//子弹射速let speed = Math.floor(this.bullet_speed);//子弹攻击力let ATK = Math.floor(this.ATK)//如果速度不为满级正常显示if (this.bullet_speed < 10000) {this.state_lb[0].string = "子弹射速:" + speed;}//如果速度不为满级正常显示else {this.state_lb[0].string = "子弹射速:Max";}this.state_lb[1].string = "子弹攻击力:" + ATK;//显示分数//如果分数小于1000正常显示if (this.score < 1000) {this.score_lb.string = "分数:" + Math.floor(this.score);}//如果分数大于1000小于10000就用k表示else if (this.score < 10000) {let s = (Math.floor(this.score) / 1000).toFixed(2);this.score_lb.string = "分数:" + s + "K";}//如果分数大于10000就用w表示else {let s = (Math.floor(this.score) / 10000).toFixed(2);this.score_lb.string = "分数:" + s + "W";}}
五、障碍
1.生成障碍
1.新建所有障碍父节点
2.新建预制体barrier ,新建Barrier脚本
3.新建子节点
GameController.ts
@property({ type: cc.Node, displayName: "所有障碍父节点", tooltip: "所有障碍父节点,这个节点用来消除所有障碍" })barrier_parent: cc.Node = null;@property({ type: cc.Prefab, displayName: "障碍物预制体", tooltip: "障碍物预制体" })barrier: cc.Prefab = null;@property({ displayName: "每个障碍物间距范围", tooltip: "每个障碍物间距范围,最小多少,最大多少" })barrier_spacing: cc.Vec2 = cc.v2(10, 50)@property({ displayName: "障碍物宽度(必填)", tooltip: "障碍物宽度(必填),代码将根据这个值来计算出障碍物生成的最佳位置" })barrier_width: number = 100;@property({ displayName: "障碍我高度(必填)", tooltip: "障碍物高度(必填),代码将根据这个值来计算出障碍物生成的最佳位置" })barrier_height: number = 100;@property({ displayName: "障碍物初始生命值", tooltip: "障碍物初始生命值,其实就是障碍物上面文字的数值,当值为0时障碍物销毁,但是这个值并不是障碍物初始的生命值,因为最终障碍物还加上了随机数" })barrier_health: number = 100;@property({ type: cc.Float, displayName: "障碍物移动速度", tooltip: "障碍物移动速度,单位是每秒多少个像素" })barrier_speed: number = 100;@property({ type: cc.Float, displayName: "障碍物生成时间间隔", tooltip: "障碍物生成时间间隔,通过控制这个来调整生成频率,最终的频率为(这个变量*Math.random())+(障碍物高/障碍物移动速度)" })generation_interval: number = 0.8;@property({ type: cc.Float, displayName: "每生成一次障碍物,障碍物锁增加的生命值", tooltip: "每生成一次障碍物,障碍物锁增加的生命值,最终结果是(这个变量*Math.random())" })increase: number = 2;@property({ displayName: "是否生成障碍物", tooltip: "是否生成障碍物" })is_barrier_create: boolean = true;@property({ displayName: "障碍物和buff是否可以移动", tooltip: "障碍物和buff是否可以移动" })is_barrier_move: boolean = true;//创建障碍物用的变量(当前)cre_bar: number = 0;//创建障碍物用的变量(满的)cre_bar_f: number = 0;onLoad() {cc.game.setFrameRate(90)//恢复游戏,避免游戏暂停导致无法继续cc.director.resume();//给Canvas绑定事件this.canvas.on(cc.Node.EventType.TOUCH_MOVE, this.onMove, this)//创建障碍物this.create_barrier();this.cre_bar_f = (this.barrier_height / this.barrier_speed) + Math.random() * this.generation_interval;}update(dt: number): void {//炮弹生成let time = 1 / this.bullet_num;//飞机左侧炮弹生成this.l += dt;if (this.l > time && this.is_fire == true) {//打印logconsole.log("生成左侧炮弹");//清零this.l = 0;//创建炮弹this.create_bullet(cc.v3(this.bullet_left_pos))}//飞机右侧炮弹生成this.r += dtif (this.r > time && this.is_fire == true) {console.log("飞机右侧炮弹生成");this.r = 0;this.create_bullet(cc.v3(this.bullet_right_pos))}//生成障碍物//如果能生成障碍物就加if (this.is_barrier_create == true) {this.cre_bar = this.cre_bar + dt;}//可以生成障碍物时if (this.cre_bar >= this.cre_bar_f) {this.cre_bar = 0;this.cre_bar_f = (this.barrier_height / this.barrier_speed) + (Math.random() * this.generation_interval);this.create_barrier();}//显示状态//子弹射速let speed = Math.floor(this.bullet_speed);//子弹攻击力let ATK = Math.floor(this.ATK)//如果速度不为满级正常显示if (this.bullet_speed < 10000) {this.state_lb[0].string = "子弹射速:" + speed;}//如果速度不为满级正常显示else {this.state_lb[0].string = "子弹射速:Max";}this.state_lb[1].string = "子弹攻击力:" + ATK;//显示分数//如果分数小于1000正常显示if (this.score < 1000) {this.score_lb.string = "分数:" + Math.floor(this.score);}//如果分数大于1000小于10000就用k表示else if (this.score < 10000) {let s = (Math.floor(this.score) / 1000).toFixed(2);this.score_lb.string = "分数:" + s + "K";}//如果分数大于10000就用w表示else {let s = (Math.floor(this.score) / 10000).toFixed(2);this.score_lb.string = "分数:" + s + "W";}}//创建障碍物函数create_barrier(): void {//l为最左边,也就是从哪里生成,就是屏幕最左边加上一个随机数let l = ((-this.canvas.width / 2) + (this.barrier_width / 2)) + Math.random() * 100;//r为最右边,也就是从哪里结束生成,就是屏幕最右边减去一个随机数let r = (this.canvas.width / 2) - (this.barrier_width / 2) - Math.random() * 50;//获取屏幕最上面的Y坐标let top = (this.canvas.height / 2) + (this.barrier_height / 2);//获取障碍物之间的间距,值是随机的let barrier_spacing = this.randomNumber(this.barrier_spacing.x, this.barrier_spacing.y);//while循环生成障碍物//如果左边小于右边while (l < r) {let barrier = cc.instantiate(this.barrier);barrier.parent = this.barrier_parent;barrier.position = cc.v3(l, top)//随机数生成障碍物的间距barrier_spacing = this.randomNumber(this.barrier_spacing.x, this.barrier_spacing.y);//打印logconsole.log("生成障碍物,目前值为:" + l.toString());//左边的值加上障碍物宽和障碍物的间距l = l + this.barrier_width + barrier_spacing;}
//障碍物的生命值加上障碍物的宽和障碍物的间距this.barrier_health += Math.floor(Math.random() * this.increase)}//随机函数 min为最小值,max为最大值,将返回一个number,值大小的范围为min-maxrandomNumber(min: number, max: number) {return (Math.round(Math.random() * (min - max) + max))}
Barrier.ts
const { ccclass, property } = cc._decorator;@ccclass
export default class Barrier extends cc.Component {@property({ type: cc.Label, displayName: "显示数值的文字", tooltip: "显示数值的文字" })num_lb: cc.Label = null;//@property({type: cc.Float, displayName: "自身数值", tooltip: "自身数值,当数值为0时当前节点销毁"})num: number = 20;//自身速度speed: number = 2;onLoad(): void {//自身和文字随机颜色 this.node.color = cc.color(this.random_color().x, this.random_color().y, this.random_color().z, 255);this.num_lb.node.color = cc.color(this.random_color().x, this.random_color().y, this.random_color().z, 255);//防止颜色一样//如果自身和文字颜色一样if (this.num_lb.node.color == this.node.color) {//文字如果不为红色if (this.num_lb.node.color != cc.color(255, 0, 0, 255)) {//文字变为红色this.num_lb.node.color = cc.color(255, 0, 0, 255);} else {//如果不,则变成黑色this.num_lb.node.color = cc.color(0, 0, 0, 255);}}//获取GameController脚本let gc = cc.find("Canvas").getComponent("GameController");//获取脚本下障碍物的生命值并加上随机数let h = (gc.barrier_health) + Math.floor(Math.random() * 10);//获取脚本下障碍物的速度let s = gc.barrier_speed;//赋值this.num = h;this.speed = s;}//随机颜色函数random_color(): cc.Vec3 {let r = this.randomNumber(0, 255);let g = this.randomNumber(0, 255);let b = this.randomNumber(0, 255);return (cc.v3(r, g, b))}update(dt: number) {//将自身生命值取整let num = Math.floor(this.num);//在Label上显示this.num_lb.string = num.toString();//获取GameController脚本let gc = cc.find("Canvas").getComponent("GameController");//自身移动if (gc.is_barrier_move == true) {this.node.y -= dt * this.speed;}//获取canvas节点let canvas = cc.find("Canvas");//如果自身到了屏幕最下方if (this.node.y <= -(canvas.height / 2)) {//获取GameController脚本let gc = cc.find("Canvas").getComponent("GameController");//调用游戏结束函数/* gc.gameOver() */}}// 随机数函数 min为最小值 max为最大值 将返回一个number,值大小的范围为min-maxrandomNumber(min: number, max: number): number {return (Math.round(Math.random() * (min - max) + max));}
}
4.绑定Canvas
2.消除障碍
GameController.ts
onLoad() {cc.game.setFrameRate(90)//恢复游戏,避免游戏暂停导致无法继续cc.director.resume();//给Canvas绑定事件this.canvas.on(cc.Node.EventType.TOUCH_MOVE, this.onMove, this)//开启碰撞引擎let manager = cc.director.getCollisionManager();manager.enabled = true;//如果要调试if (this.is_debug == true) {// 是否绘制碰撞组件的形状,默认为不绘制manager.enabledDebugDraw = true;//是否绘制碰撞组件的包围盒,默认为不绘制manager.enabledDrawBoundingBox = true;}//创建障碍物this.create_barrier();this.cre_bar_f = (this.barrier_height / this.barrier_speed) + Math.random() * this.generation_interval;}
Brrier.ts
//碰撞回调//当碰撞产生的时候调用other产生碰撞的另一个组件 self产生碰撞的自身的碰撞组件onCollisionEnter(other, self) {if (other.node.group == "bullet") {//获取GameController脚本let gc = cc.find("/Canvas").getComponent("GameController");//获取Bullet脚本let c = other.getComponent("Bullet");//从脚本获取攻击力较少自身生命值this.reduce_num(c.ATK);//销毁子弹other.node.destroy();}//如果自身生命值小于0if (this.num <= 0) {//自身销毁this.node.destroy();}}
六、Buff
1.生成buff
1.新建显示获得buff类型节点
2.新建Buff脚本,新建buff预制资源
3.新建buff子节点
GameController.ts
@property({ type: cc.Prefab, displayName: "buff预制体", tooltip: "buff预制体" })buff: cc.Prefab = null;//创建障碍物函数create_barrier(): void {//l为最左边,也就是从哪里生成,就是屏幕最左边加上一个随机数let l = ((-this.canvas.width / 2) + (this.barrier_width / 2)) + Math.random() * 100;//r为最右边,也就是从哪里结束生成,就是屏幕最右边减去一个随机数let r = (this.canvas.width / 2) - (this.barrier_width / 2) - Math.random() * 50;//获取屏幕最上面的Y坐标let top = (this.canvas.height / 2) + (this.barrier_height / 2);//获取障碍物之间的间距,值是随机的let barrier_spacing = this.randomNumber(this.barrier_spacing.x, this.barrier_spacing.y);//while循环生成障碍物//如果左边小于右边while (l < r) {//利用随机数,有概率生成buff球let n = Math.random() * 100;if (n > this.probability) {let barrier = cc.instantiate(this.barrier);barrier.parent = this.barrier_parent;barrier.position = cc.v3(l, top)} else if (n < this.probability) {//生成buff球,Y坐标是屏幕上方let buff = cc.instantiate(this.buff);buff.parent = this.barrier_parent;buff.position = cc.v3(1, top);}//随机数生成障碍物的间距barrier_spacing = this.randomNumber(this.barrier_spacing.x, this.barrier_spacing.y);//打印log/* console.log("生成障碍物,目前值为:" + l.toString()); *///左边的值加上障碍物宽和障碍物的间距l = l + this.barrier_width + barrier_spacing;}//障碍物的生命值加上障碍物的宽和障碍物的间距this.barrier_health += Math.floor(Math.random() * this.increase)}
Buff.ts
const { ccclass, property } = cc._decorator;@ccclass
export default class NewClass extends cc.Component {//自身移动速度speed: number = 2;onLoad(): void {//获取GameController脚本let gc = cc.find("Canvas").getComponent("GameController");//获取障碍物移动速度let s = gc.barrier_speed;this.speed = s;}update(dt: number) {//获取GameController脚本let gc = cc.find("Canvas").getComponent("GameController");//自身移动if (gc.is_barrier_move == true) {this.node.y -= dt * this.speed;}}}
4.绑定Canvas
2.buff碰撞
1.新建double_lb节点
Buff.ts
//碰撞回调onCollisionEnter(other,self){//获取GameController脚本let gc = cc.find("Canvas").getComponent("GameController");//如果子弹射速满了,就不增加射速了if(gc.bullet_speed<10000){//随机数0-10let n = this.randomNumber(0,10);//有一半几率执行子弹加速函数//也有一半几率执行子弹加攻击函数if(n>5){//加速buffgc.enhance_speed();}else{//加攻击buffgc.enhance_ATK();}}else{gc.enhance_ATK()}//自身销毁this.node.destroy()}// 随机数函数 min为最小值 max为最大值 将返回一个number,值大小的范围为min-maxrandomNumber (min: number, max: number): number {return(Math.round(Math.random() * (min - max) + max));}
GameController.ts
@property({ type: cc.Node, displayName: "显示获得buff类型的label", tooltip: "显示获得buff类型的label" })label_parent: cc.Node = null;@property({ type: cc.Node, displayName: "显示双倍分数的label", tooltip: "显示双倍分数的label" })double_lb: cc.Node = null;@property({ type: cc.Prefab, displayName: "buff预制体", tooltip: "buff预制体" })buff: cc.Prefab = null;@property({ displayName: "是否双倍分数", tooltip: "是否双倍分数" })is_double: boolean = false;//增加子弹射速enhance_speed() {//增加射速this.bullet_speed = this.bullet_speed + this.add_buff_num[0];//射速加的越来越多this.add_buff_num[0] = this.add_buff_num[0] * 1.1;//新建一个label来显示吃到的buff//新建节点let node = new cc.Node//父节点是label_parent,这个节点上有Layout组件node.parent = this.label_parent;//添加cc.Labelnode.getComponent(cc.Label);//显示内容node.getComponent(cc.Label).string = "子弹射速提升";//定时器1秒后销毁this.scheduleOnce(function () {node.destroy();}, 1);//双倍分数this.double_score(8);}//增强子弹攻击力enhance_ATK() {//增加攻击力this.ATK = this.ATK + this.add_buff_num[1];//攻击力加的越来越多this.add_buff_num[1] = this.add_buff_num[1] * 1.1;// 新建一个label来显示吃到的buff// 新建节点let node = new cc.Node;// 父节点是label_parent,这个节点上有Layout组件node.parent = this.label_parent;// 添加cc.Labelnode.addComponent(cc.Label);// 显示内容node.getComponent(cc.Label).string = "子弹攻击力提升";// 定时器 1秒后销毁this.scheduleOnce(function () {node.destroy();}, 1);// 双倍分数this.double_score(8);}//双倍分数函数,执行后得分翻倍,time为多少秒后恢复double_score(time: number) {let self = this;//开启双倍分数并且显示文字this.is_double = true;this.double_lb.active = true;//定时器关闭双倍分数并且隐藏文字this.scheduleOnce(function () {self.is_double = false;self.double_lb.active = false;}, time);}
2.绑定Canvas
七、加分
Barrier.ts
//碰撞回调//当碰撞产生的时候调用other产生碰撞的另一个组件 self产生碰撞的自身的碰撞组件onCollisionEnter(other, self) {if (other.node.group == "bullet") {//获取GameController脚本let gc = cc.find("/Canvas").getComponent("GameController");//获取Bullet脚本let c = other.getComponent("Bullet");//从脚本获取攻击力较少自身生命值this.reduce_num(c.ATK);// 如果可以加双倍分数if(gc.is_double==true){//加分gc.add_score((c.ATK)*2)}//如果不可以加双倍分数if(gc.is_double == false){gc.add_score(c.ATK);}//销毁子弹other.node.destroy();}//如果自身生命值小于0if (this.num <= 0) {//自身销毁this.node.destroy();}}
GameController.ts
update(dt: number): void {//炮弹生成let time = 1 / this.bullet_num;//飞机左侧炮弹生成this.l += dt;if (this.l > time && this.is_fire == true) {//打印log/* console.log("生成左侧炮弹"); *///清零this.l = 0;//创建炮弹this.create_bullet(cc.v3(this.bullet_left_pos))}//飞机右侧炮弹生成this.r += dtif (this.r > time && this.is_fire == true) {/* console.log("飞机右侧炮弹生成"); */this.r = 0;this.create_bullet(cc.v3(this.bullet_right_pos))}//生成障碍物//如果能生成障碍物就加if (this.is_barrier_create == true) {this.cre_bar = this.cre_bar + dt;}//可以生成障碍物时if (this.cre_bar >= this.cre_bar_f) {this.cre_bar = 0;this.cre_bar_f = (this.barrier_height / this.barrier_speed) + (Math.random() * this.generation_interval);this.create_barrier();}//显示状态//子弹射速let speed = Math.floor(this.bullet_speed);//子弹攻击力let ATK = Math.floor(this.ATK)//如果速度不为满级正常显示if (this.bullet_speed < 10000) {this.state_lb[0].string = "子弹射速:" + speed;}//如果速度不为满级正常显示else {this.state_lb[0].string = "子弹射速:Max";}this.state_lb[1].string = "子弹攻击力:" + ATK;//显示分数//如果分数小于1000正常显示if (this.score < 1000) {this.score_lb.string = "分数:" + Math.floor(this.score);}//如果分数大于1000小于10000就用k表示else if (this.score < 10000) {let s = (Math.floor(this.score) / 1000).toFixed(2);this.score_lb.string = "分数:" + s + "K";}//如果分数大于10000就用w表示else {let s = (Math.floor(this.score) / 10000).toFixed(2);this.score_lb.string = "分数:" + s + "W";}//加分函数add_score(num: number) {this.score = this.score + num;}
相关文章:
飞机打方块(二)游戏界面制作
一、背景 1.新建bg节点 二、飞机节点功能实现 1.移动 1.新建plane节点 2.新建脚本GameController.ts,并绑定Canvas GameControll.ts const { ccclass, property } cc._decorator;ccclass export default class NewClass extends cc.Component {property(cc.Node)canvas:…...
自我理解:精度(precision)和召回(recall)
1、精度(precision) 精度是用于评估分类模型的一个重要指标。它反映了模型预测为正例的样本中,实际真正为正例样本的比例。 【注】正例样本指在二分类问题中,被标注为正类的样本。 例如:在垃圾邮件分类任务中,正例样本就是真实的…...
Nginx 使用 HTTPS(准备证书和私钥)
文章目录 Nginx生成自签名证书和配置Nginx HTTPS(准备证书和私钥)准备证书和私钥 Nginx生成自签名证书和配置Nginx HTTPS(准备证书和私钥) 准备证书和私钥 生成私钥 openssl genrsa -des3 -out server.key 2048这会生成一个加密…...
Java:集合框架:Set集合、LinkedSet集合、TreeSet集合、哈希值、HashSet的底层原理
Set集合 创建一个Set集合对象,因为Set是一个接口不能直接new一个对象,所以要用一个实现类来接 HashSet来接 无序性只有一次,只要第一次运行出来后,之后再运行的顺序还是第一次的顺序。 用LinkedSet来接 有序 不重复 无索引 用Tree…...
自定义Taro的navBar的宽度和高度
本方法是计算自定义navbar的宽度和高度,输出的参数有 navBarHeight, menuBottom,menuHeight, menuRectWidth,windowWidth, windowHeight,具体代码如下: export function getCustomNavBarRect():| {navBarHeight: number;menuBottom: number;menuHeight:…...
用Python编程实现百度自然语言处理接口的对接,助力你开发智能化处理程序
用Python编程实现百度自然语言处理接口的对接,助力你开发智能化处理程序 随着人工智能的不断进步,自然语言处理(Natural Language Processing,NLP)成为了解决文本处理问题的重要工具。百度自然语言处理接口提供了一系…...
系统架构设计专业技能 · 系统工程与系统性能
系列文章目录 系统架构设计专业技能 网络技术(三) 系统架构设计专业技能 系统安全分析与设计(四)【系统架构设计师】 系统架构设计高级技能 软件架构设计(一)【系统架构设计师】 系统架构设计高级技能 …...
初识网络原理(笔记)
目录 编辑局域网 网络通信基础 IP 地址 端口号 协议 协议分层 TCP / IP 五层网络模型 网络数据传输的基本流程 发送方的情况: 接收方的情况 局域网 搭建网络的时候,需要用到 交换机 和 路由器 路由器上,有 lan 口 和 wan 口 虽…...
嵌入式C语言基本操作方法之经典
C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。 C语言不但执行效率高而且可移植性好,可以用来开发应用软件、驱动、操作系统等。 C语言也是其它众多高级语言的鼻祖语言,所以说学习C语言是进入编程世界的必…...
postgresql \watch实用的使用方法
文章目录 1.介绍2.语法3.实用的使用方法3.1 慢sql监控3.2 长wait事件3.3 日志输出量3.3结合pg_stat_database使用3.4 结合pg_stat_bgwriter使用3.5 其他 1.介绍 \watch Postgres 9.3 版带来的一个有用的命令,与linux watch指令类似,可以帮我们在指定间隔…...
Cocos2d 项目问题记录
环境搭建 正常运行 Android 端的 Cocos2d 项目,本机至少需要 Android SDK、NDK 环境、Android Studio 项目报错总结 CMake Error: CMake was unable to find a build program corresponding to "Ninja" 默认创建工程的 gradle.tools 版本为 3.1.0&…...
系统架构合理性的思考 | 京东云技术团队
最近牵头在梳理部门的系统架构合理性,开始工作之前,我首先想到的是如何定义架构合理性? 从研发的角度来看如果系统上下文清晰、应用架构设计简单、应用拆分合理应该称之为架构合理。 基于以上的定义可以从以下三个方面来梳理评估࿱…...
Amelia预订插件:WordPress企业级预约系统
并非所有WordPress预订插件都像他们所设计的那样。其中一些缺乏运行高效预约操作所需的功能,而其他一些则看起来陈旧过时。您不需要其中任何一个,但Amelia预订插件似乎希望确保所有用户都对功能和风格感到满意。 在这篇Amelia企业级预约系统插件评测中&…...
共享门店模式:线下门店的商家如何利用它增加客户
随着数字化时代的到来,商业模式正在不断创新与演变,而共享经济正成为引领这一变革的重要力量。在这个大背景下,共享门店模式作为共享经济的一种体现,正在逐渐走进人们的生活,并为商家和消费者带来了新的商机和体验。 共…...
实现矩阵地图与rviz地图重合
文章目录 一、rviz地图转换矩形地图(只能用于全局规划)二、在rviz上显示地图边界信息,可视化调整,实现重合(只能用于局部规划)一、rviz地图转换矩形地图(只能用于全局规划) 此方法矩形地图可能会与rviz地图不重合,通过改变偏移量x_offset,y_offset接近地图 可以将矩…...
设计模式十九:备忘录模式(Memento Pattern)
备忘录模式是一种行为型设计模式,它允许对象在不暴露其内部状态的情况下捕获和恢复其状态。该模式的主要目标是在不破坏封装性的前提下,实现对象状态的备份和恢复。备忘录模式常用于需要保存对象历史状态、撤销操作或者实现快照功能的情况。 备忘录模式…...
【题解】二叉搜索树与双向链表
二叉搜索树与双向链表 题目链接:二叉搜索树与双向链表 解题思路1:递归中序遍历 首先题目最后要求的是一个的递增的双向链表,而二叉搜索树也是一类非常有特色的树,它的根节点大于所有左侧的节点,同时又小于所有右侧的…...
【真实案例】解决后端接口调用偶尔超时问题
文章目录 背景分析代码分析二次日志分析排查Gateway服务解决解决办法1:添加重试机制解决办法2:优化网关内存分配解决办法3:调整OOM策略背景 项目从虚拟机迁移到k8s云原生平台(RainBond)后,发现偶尔会出现接口调用超时的问题。 统计了一下从上线到现在近一个月的调用失败…...
操作符详解(1)
1. 操作符分类: 算术操作符 移位操作符 位操作符 赋值操作符 单目操作符 关系操作符 逻辑操作符 条件操作符 逗号表达式 下标引用、函数调用和结构成员 2. 算术操作符 - * / % 1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。 2. 对…...
<指针进阶>指针数组和数组指针傻傻分不清?
✨Blog:🥰不会敲代码的小张:)🥰 🉑推荐专栏:C语言🤪、Cpp😶🌫️、数据结构初阶💀 💽座右铭:“記住,每一天都是一個新的開始…...
无代码集成飞书连接更多应用
场景描述: 基于飞书开放平台能力,无代码集成飞书连接更多应用,打通数据孤岛。通过Aboter可轻松搭建业务自动化流程,实现多个应用之间的数据连接。 支持包括飞书事件监听和接口调用的能力: 事件监听: 用…...
三分钟解决AE缓存预览渲染错误、暂停、卡顿问题
一、清除RAM缓存(内存) 你应该做的第一件事是清除你的RAM。这将清除当前存储在内存中的所有临时缓存文件。要执行此操作,请导航到编辑>清除>所有内存。这将从头开始重置RAM缓存 二、清空磁盘缓存 您也可以尝试清空磁盘缓存。执行此操作…...
朴实无华的数据增强然后训练一下应用在电网异物检测领域,好像有自己的数据集就能发文了
RCNN-based foreign object detection for securing power transmission lines (RCNN4SPTL) Abstract 本文提出了一种新的深度学习网络——RCNN4SPTL (RCNN -based Foreign Object Detection for Securing Power Transmission lines),该网络适用于检测输电线路上的…...
【使用教程】在Ubuntu下运行CANopen通信PMM伺服电机使用教程(NimServoSDK_V2.0.0)
本教程将指导您在Ubuntu操作系统下使用NimServoSDK_V2.0.0来运行CANopen通信的PMM系列一体化伺服电机。我们将介绍必要的步骤和命令,以确保您能够成功地配置和控制PMM系列一体化伺服电机。 NimServoSDK_V2.0.0是一款用于PMM一体化伺服电机的软件开发工具包。它提供了…...
vue3+ts+vite项目页面初始化loading加载效果
简介 一分钟实现 vue-pure-admin 同款项目加载时的 loading 效果 一、先看效果 1.1 静态效果 1.2 动态效果 二、上代码 核心代码在body里面,代码中已标明。找到你项目的 index.html ,复制粘贴进去即可 <!DOCTYPE html> <html lang"en…...
ElasticSearch 数据聚合、自动补全(自定义分词器)、数据同步
文章目录 数据聚合一、聚合的种类二、DSL实现聚合1、Bucket(桶)聚合2、Metrics(度量)聚合 三、RestAPI实现聚合 自动补全一、拼音分词器二、自定义分词器三、自动补全查询四、实现搜索款自动补全(例酒店信息࿰…...
神经网络基础-神经网络补充概念-18-多个样本的向量化
概念 多个样本的向量化通常涉及将一组样本数据组织成矩阵形式,其中每一行代表一个样本,每一列代表样本的特征。这种向量化可以使你更有效地处理和操作多个样本,特别是在机器学习和数据分析中。 代码实现 import numpy as np# 多个样本的数…...
*看门狗1
//while部分是我们在项目中具体需要写的代码,这部分的程序可以用独立看门狗来监控 //如果我们知道这部分代码的执行时间,比如是500ms,那么我们可以设置独立看门狗的 //溢出时间是600ms,比500ms多一点,如果要被监控的程…...
nginx防盗链
防盗链介绍 通过二次访问,请求头中带有referer,的方式不允许访问静态资源。 我们只希望用户通过反向代理服务器才可以拿到我们的静态资源,不希望别的服务器通过二次请求拿到我们的静态资源。 盗链是指在自己的页面上展示一些并不在自己服务…...
8月16日上课内容 第二章 部署LVS-DR群集
本章结构: 数据包流向分析: 数据包流向分析: (1)客户端发送请求到 Director Server(负载均衡器),请求的数据报文(源 IP 是 CIP,目标 IP 是 VIP)到达内核空间。 …...
织梦dedecms医院类网站在线预约挂号插件_utf8/seo工具查询
来源:小林coding想必不少小伙伴面试过程中,会遇到「当键入网址后,到网页显示,其间发生了什么」的面试题。这次,小林我带大家一起探究下,一个数据包在网络中的心路历程。每个阶段都有数据包的「心路历程」&a…...
建站网站设计/南宁百度首页优化
第三章 面向对象时间:2017年4月24日17:51:37~2017年4月25日13:52:34章节:03章_01节 03章_02节视频长度:30:11 21:44内容:面向对象设计思想 心得:与以往的各种语言的根本不同的是,它的设计出发点就是为了更…...
wordpress最近更新模块/哪个公司做网站推广最好
偶然间发现了Redis的这本书,和拥有这本书的网站,感觉相当不错,一个突来的亮点,记录下来以后慢慢看。 The goal of this book is to build the foundation you’ll need to master Redis. We’ll focus on learning Redis’ five …...
哪些网站可以做视频搬运/太原首页推广
向饼图添加显示每个扇区说明的图例。 定义 x 并创建一个饼图。 x = [1,2,3]; figure pie(x) 在元胞数组 labels 中指定每个饼图扇区的说明。按照您在 x 中指定数据的顺序指定说明。 labels = {Product A,Product B,Product C}; 在饼图下方显示水平图例。将包含在 labels 中...
宁波网站制作公司官网/百度关键词排名快速排名
ADO.NET Entity Framework 在哪些场景下使用?在知乎回答了下,顺手转回来. Enity Framework已经是.NET下最主要的ORM了.而ORM从一个Mapping的概念开始,到现在已经得到了一定的升华,特别是EF等对ORM框架面向对象能力的 ...【转载】input 中 type&equal…...
企业网站建设制作/360优化大师最新版下载
第四章 对象与类 面向对象程序设计简称OOP,面向对象的程序是由对象组成的。 类是构造对象的模板或蓝图,对象中的数据称为实例域,操纵数据的过程称为方法。 对象有三个主要特性:1.对象的行为—可以对对象施加哪些操作,…...