文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

CocosCreator制作射击游戏的方法

2023-06-14 13:52

关注

这篇文章给大家分享的是有关CocosCreator制作射击游戏的方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

场景布置

游戏资源

CocosCreator制作射击游戏的方法

CocosCreator制作射击游戏的方法

CocosCreator制作射击游戏的方法

炮塔旋转

机制与之前手柄实例的小车相同,使用touchmove监听触摸事件,

  1. 获取触摸位置

  2. 通过位置用signAngle方法将该位置与cc.v2(1,0)位置的角度差求出(记得要加负号,比较所得逆时针为负,赋值angle逆指针为正)。

  3. 所求的的角度即为最终角度。

CocosCreator制作射击游戏的方法

 onLoad(){        //初始化为90度        this.node.angle=90;        this.node.on('touchstart',this.onTouchStart,this);        this.node.on('touchmove',this.onTouchMove,this);        this.node.on('touchend',this.onTouchEnd,this);        this.node.on('touchconcel',this.onTouchConcel,this);    }       onTouchStart(e:cc.Event.EventTouch){        //获取开始的位置        this.starPos=this.node.parent.convertToNodeSpace(e.getLocation());        //获取炮口的初始角度        this.starAngle=this.node.angle;    }    onTouchEnd(e:cc.Event.EventTouch){    }    onTouchMove(e:cc.Event.EventTouch){        //获取触点当前的位置        let pos:cc.Vec2=this.node.parent.convertToNodeSpace(e.getLocation());        //获取角度        //angle顺时针为负逆时针为正        let sweep_radian=pos.signAngle(this.starPos);//pos相对于starPose的角度p相对s顺时针为正        let sweep_angle=sweep_radian*180/Math.PI;//弧度制换算角度                //让炮塔的角度指向最终的角度        let angle=this.starAngle-sweep_angle;              //将角度限制在45~135之间        if(angle<45)angle=45;        if(angle>135)angle=135;        cc.log("炮口摆动:"+sweep_angle+"最终角度位置:"+angle);        this.node.angle=angle;    }

动态生成子弹

CocosCreator制作射击游戏的方法

  1. 生成节点cc.Node,并增加组件addComponent(cc.Sprite)

  2. 为组件的属性赋值,将图片的spriteFrame赋值

  3. 将组件挂载在一个父节点下

  4. 设置位置、角度等

  5. 控制其运动可以导入新建的脚本,并将该脚本增加到动态生成节点的组件中

 onTouchEnd(e:cc.Event.EventTouch){        this.fire();    }    onTouchConcel(e:cc.Event.EventTouch){    }    fire(){        if(this.bulleteicon==null)return;        let bullet:cc.Node=new cc.Node();        let sprite:cc.Sprite=bullet.addComponent(cc.Sprite);        sprite.spriteFrame=this.bulleteicon;                //挂载到射击系统节点下        bullet.parent=this.node.parent;        //设置相对父节点位置        let ration=this.node.angle*Math.PI/180;        let direction=cc.v2(Math.cos(ration),Math.sin(ration));        bullet.angle=this.node.angle;        let r=100;        bullet.setPosition(cc.v3(r*direction.x,r*direction.y,0));               //附加脚本组件         let script=bullet.addComponent(Buletet);         script.explodeImg=this.explodeImg;         script.direction=direction;    }
 start () {         this.schedule(this.onTimer,0.01);    }    onTimer(){        if(this.node.y>300){            this.unschedule(this.onTimer);            this.explode();                       return;        }        let dx=this.direction.x*5;        let dy=this.direction.y*5;        this.node.y+=dy;        this.node.x+=dx;    }    explode(){        let sp:cc.Sprite=this.getComponent(cc.Sprite);        sp.spriteFrame=this.explodeImg;              //将子弹缩小        this.node.scale=0.1;        //爆炸动画效果缓动系统        let self=this;        cc.tween(this.node)            .to(0.5,{scale:1,opacity:0})            .call(function(){                self.afterExplode();            })            .start();                }    afterExplode(){        this.node.destroy();    }

本次bug:

  1. 导入的类名与文件名不同,注意重命名文件不会自动修改代码中的类名,需要修改两次

  2. setposition()方法使用时参数写在了cc.v3的构造函数内,一定注意参数的位置

碰撞计算

CocosCreator制作射击游戏的方法

计算子弹和靶标的相对位置,若小于范围,则判断为命中靶,执行命中的操作,否则判断为没有命中,执行没有命中的操作。

脚本需传入靶子节点,增加target属性

   @property(cc.SpriteFrame)    explodeImg: cc.SpriteFrame = null;        direction: cc.Vec2 = null;    target: cc.Node = null;    onLoad() {    }    start() {        this.schedule(this.onTimer, 0.01);    }    onTimer() {        if (this.node.y > 350) {            if (this.isHit()) {                //播放爆炸效果                this.explode();                console.log("命中靶");            }            else {                console.log("脱靶");                this.disMiss();            }            this.unschedule(this.onTimer);            return;        }        let dx = this.direction.x * 5;        let dy = this.direction.y * 5;        this.node.y += dy;        this.node.x += dx;    }    //判断是否命中    isHit(): boolean {        let targetPos: cc.Vec2 = this.geWorldLocation(this.target);        let selfPos: cc.Vec2 = this.geWorldLocation(this.node);        let distance = Math.abs(targetPos.x - selfPos.x);        console.log("靶标x=" + targetPos.x + " , 子弹x=" + selfPos.x);        if (distance < 50) {            return true;        }        else {            return false;        }    }    explode() {        let sp: cc.Sprite = this.getComponent(cc.Sprite);        sp.spriteFrame = this.explodeImg;        //将子弹缩小        this.node.scale = 0.1;        //爆炸动画效果缓动系统        let self = this;        cc.tween(this.node)            .to(0.5, { scale: 1, opacity: 0 })            .call(function () {                self.disMiss();            })            .start();    }    geWorldLocation(node: cc.Node): cc.Vec2 {        let pos = node.getPosition();        //注意这里是node.parent。方法的调用者要是当前节点的坐标系        return node.parent.convertToWorldSpaceAR(pos);    }    disMiss() {        this.node.destroy();    }

本次bug:

获取世界坐标时,没有调用其父节点的坐标系,用了当前节点的坐标系,所以返回的依然是自身当前坐标系的值。记得转换世界坐标的方法调用者是当前节点的坐标系,一般为其父节点return node.parent.convertToWorldSpaceAR(pos);(以锚点为原点)

增加效果

CocosCreator制作射击游戏的方法

在靶子的节点下增加脚本,控制移动,左右来回移动
同时,当子弹命中后增加文字提示效果。

文字提示:

 cheer() {        //创建节点并挂载        let node: cc.Node = new cc.Node();        node.parent = this.node.parent;//两者同一级,同一个父对象        let label: cc.Label = node.addComponent(cc.Label);        label.string = "+10分";        //设置位置、透明度等        node.setPosition(cc.v3(0, 250, 0));        node.opacity = 200;        node.color = new cc.Color(255, 0, 0);        //动效        cc.tween(node)            .to(0.5, { scale: 1.5 })            .to(0.2, { opacity: 0 })            .call(function () {                node.destroy();            })            .start();    }

靶子移动

 update (dt) {         let speed=3;         if(this.isLeft){             speed=-speed;         }         this.node.x+=speed;         if(this.isLeft&&this.node.x<-350){             this.isLeft=false;         }         if(!this.isLeft&&this.node.x>350){            this.isLeft=true;        }    }

增加弹药库的显示

CocosCreator制作射击游戏的方法

  1. 增加弹药库节点,批量生成子弹图片(可用widget组件设置位置)

  2. 增加减少子弹方法,并通过设置子弹图片的active属性来减少子弹。

  3. 在炮塔的fire方法中调用减少子弹的方法

调用方法有两种,一种为在炮塔脚本中获取弹药库节点在调用,另一种为设置公共类,(静态变量),在onLoad()方法中就初始化该节点,然后直接调用。用后者。

 @property(cc.SpriteFrame)    bulleteIcon: cc.SpriteFrame = null;    capacity: number = 10;    stockNumber: number = 10;    onLoad() {        let space: number = this.node.width / this.capacity;        for (let i = 0; i < this.capacity; i++) {            //生成图片            let bulleteNode: cc.Node = new cc.Node();            let bulleteSprite: cc.Sprite = bulleteNode.addComponent(cc.Sprite);            bulleteSprite.spriteFrame = this.bulleteIcon;            this.node.addChild(bulleteNode);            //设置位置            bulleteNode.x += space * i + 10;            bulleteNode.y = 0;        }    }    start() {    }    consum(num: number) {        this.stockNumber -= num;        if (this.stockNumber < 0) {            this.stockNumber = 0;        }        this.display();    }    display() {        let nodes: cc.Node[] = this.node.children;        console.log(nodes.length);        for(let i=0;i<nodes.length;i++){            if(i>=this.stockNumber){                nodes[i].active=false;            }                   }    }

Common公共类

  //静态类,全局变量,将所有会公用的变量、类定义在Common类中    static ammo:Ammo=null;    onLoad() {        Common.ammo=cc.find('Canvas/弹药').getComponent('Ammo');        console.log(Common.ammo);    }

此处bug:

cc.find()方法中记得用除法的斜杠。

子弹耗尽提示分数

CocosCreator制作射击游戏的方法

  1. 创建遮罩层,将脚本类导入到Common类中,设置active属性为false

  2. 在ResultDialog脚本 增加show方法,让其active属性变为true同时将分数显示在屏幕上。

  3. 在Bullete(控制子弹运动脚本)中判断子弹数量是否<=0,并调用Common中show方法显示分数提示框。

ResultDialog脚本(控制分数提示框)

 onLoad () {         let replay:cc.Node=cc.find('Canvas/结束提示框/再玩一局');         console.log(replay);         replay.on('touchstart',this.dismiss,this);         this.node.on('touchstart',this.onTouchdisable,this);         this.node.on('touchmove',this.onTouchdisable,this);         this.node.on('touchend',this.onTouchdisable,this);        }     //显示提示框     show(){        this.node.active=true;          let scoreNode : cc.Node = cc.find('分数框/分数', this.node);        let scoreLabel : cc.Label = scoreNode.getComponent(cc.Label);           scoreLabel.string = Common.score + '分';                       }     //隐藏提示框     dismiss(){         this.node.active=false;     }     //遮罩显示时屏蔽     onTouchdisable(e:cc.Event.EventTouch){         e.stopPropagation();     }    start () {    }

Common脚本

 //静态类,全局变量,将所有会公用的变量、类定义在Common类中    static ammo:Ammo=null;    static score : number = 0;    static resultdialog : ResultDialog = null;      onLoad() {        Common.resultdialog=cc.find('Canvas/结束提示框').getComponent('ResultDialog');        Common.ammo=cc.find('Canvas/弹药').getComponent('Ammo');    }

在Bullete方法中增加分数增加

  if (this.isHit()) {                //播放爆炸效果                this.explode();                //显示+10分                this.cheer();                //总分数+10                Common.score += 10;                console.log("命中靶");            }

游戏重开

CocosCreator制作射击游戏的方法

该小游戏比较简单,重开只需要重置弹药库节点即可,因此reset方法放在Ammo脚本中
在公共类中创建Ammo对象,设置静态方法,重置得分、以及调用Ammo的reset方法。

Ammo(弹药库类)脚本添加

 reset(){        this.stockNumber=this.capacity;        this.display();    }

更改Common脚本

 //静态类,全局变量,将所有会公用的变量、类定义在Common类中    static ammo:Ammo=null;    static score : number = 0;    static resultdialog : ResultDialog = null;      onLoad() {        Common.resultdialog=cc.find('Canvas/结束提示框').getComponent('ResultDialog');        Common.ammo=cc.find('Canvas/弹药').getComponent('Ammo');        console.log(Common.ammo);    }    static resetGame() {        Common.score=0;        Common.ammo.reset();    }

增加一些细节

CocosCreator制作射击游戏的方法

增加游戏声音以及炮塔激活的变化

炮塔脚本增加属性

 //音效    @property(cc.AudioClip)    audioFire: cc.AudioClip = null;    @property(cc.AudioClip)    audioExplode: cc.AudioClip = null;    //炮塔图片    @property(cc.SpriteFrame)    iconNormal: cc.SpriteFrame = null;    @property(cc.SpriteFrame)    iconActive: cc.SpriteFrame = null;

图片切换

 onTouchStart(e: cc.Event.EventTouch) {方法最后添加   //炮塔图片切换至激活        this.node.getComponent(cc.Sprite).spriteFrame = this.iconActive;
 onTouchEnd(e: cc.Event.EventTouch) {方法最后添加          //图片恢复        this.node.getComponent(cc.Sprite).spriteFrame = this.iconNormal;      }

音效播放

fire(){   方法后添加       //将子弹爆炸音频传送至子弹脚本        script.audioExplode = this.audioExplode; if (this.audioFire != null) {            cc.audioEngine.play(this.audioFire, false, 1);        }    }

播放音频的方法:==cc.audioEngine.play(this.audioFire, false, 1);==第二个参数为是否循环播放,第三个参数为音量大小

子弹脚本

//添加属性@property(cc.SpriteFrame)explodeImg: cc.SpriteFrame = null;在判断子弹命中靶子的操作后添加if(this.audioExplode!=null){cc.audioEngine.play(this.audioExplode,false,1);}

感谢各位的阅读!关于“CocosCreator制作射击游戏的方法”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯