当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 【自己搭建小游戏(JS)】----CocosCreator -飞机大战(详细教程)

【自己搭建小游戏(JS)】----CocosCreator -飞机大战(详细教程)

2020年07月22日  | 移动技术网IT编程  | 我要评论

前言

helloworld 练习


一、CocosCreator

Cocos是由触控科技推出的游戏开发一站式解决方案,包含了从新建立项、游戏制作、到 打包上线的全套流程。开发者可以通过cocos快速生成代码、编辑资源和动画,最终输出适合于多个平台的游戏产品。

下载地址

https://www.cocos.com/
在这里插入图片描述

  • 安装
    在这里插入图片描述
    在这里插入图片描述
  • 登录
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

Demo练习

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
-测试
在这里插入图片描述
在这里插入图片描述

二、飞机大战

在这里插入图片描述

  • 经典布局

在这里插入图片描述

图片合成工具

https://www.codeandweb.com/texturepacker
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 然后把生成文件,放到我们的编辑器里面
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    • 拖入
      在这里插入图片描述
  • 添加飞机小精灵
    在这里插入图片描述
    在这里插入图片描述

1.飞机屏幕骚动起来—添加游戏轮播背景

  • 创建文件夹,添加脚本
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 关联脚本工具
    https://code.visualstudio.com/
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 然后双击我们的脚本
    在这里插入图片描述
  • 项目使用我们的脚本
    在这里插入图片描述
    -如果实现不了上面的步骤,可以这样操作:
    在这里插入图片描述
    选择【用户脚本组件】-【我们想添加的脚本组件的名称】
    在这里插入图片描述
    在这里插入图片描述
  • 开始浏览,然后通过F12查看内容
    在这里插入图片描述
    在这里插入图片描述
  • 声明组件
    在js脚本中声明我们的组件,使我们背景图进行骚动起来

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • js里面的内容,xy,相当于
    在这里插入图片描述
    在这里插入图片描述

拷贝背景图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


cc.Class({
    extends: cc.Component,

    properties: {
        bg_1:cc.Node,
        bg_2:cc.Node,
    },
    onLoad(){
        this.bg_1.y = 0
        this.bg_2.y = this.bg_1.y + this.bg_1.height
    },

    start () {
        cc.log("开始")
    },
    //项目启动以后每秒进行运行
    update(dt){
        this.bg_1.y=this.bg_1.y-1
        this.bg_2.y= this.bg_2.y-1
        if(this.bg_1.y <= -this.bg_1.height/2){
            this.bg_1.y = this.bg_2.y + this.bg_1.height
        }
        if(this.bg_2.y <= -this.bg_2.height/2){
            this.bg_2.y = this.bg_1.y + this.bg_1.height
        }
    }

   
});


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.添加游戏Logo

  • 添加文件夹,单独存放不同节点内容
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 创建文字渲染节点 label
    在这里插入图片描述
    在这里插入图片描述
  • 修改颜色
    在这里插入图片描述
    在这里插入图片描述
  • 添加动画
    在这里插入图片描述
  • 然后添加组件
    在这里插入图片描述
    选择其他组件
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

3.添加触摸事件

  • 控制游戏背景图,开始进入时不动
cc.Class({
    extends: cc.Component,

    properties: {
        bg_1:cc.Node,
        bg_2:cc.Node,
    },
    onLoad(){
        //控制游戏界面不动
        this.isBgMove=false
        this.bg_1.y = 0
        this.bg_2.y = this.bg_1.y + this.bg_1.height
    },

    start () {
        cc.log("开始")
    },
    setBg:function(){
        this.bg_1.y=this.bg_1.y-1
        this.bg_2.y= this.bg_2.y-1
        if(this.bg_1.y <-this.bg_1.height){
            this.bg_1.y = this.bg_2.y + this.bg_1.height
        }
        if(this.bg_2.y < -this.bg_2.height){
            this.bg_2.y = this.bg_1.y + this.bg_1.height
        }
    },
    //项目启动以后每秒进行运行
    update(dt){
        if(this.isBgMove){
            this.setBg()  
        }
      
    }

   
});


在这里插入图片描述

  • 实现点击屏幕,隐藏logo与“点击游戏几个字”
    在这里插入图片描述
    在这里插入图片描述
  • 编辑器添加node节点关联
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

4.添加暂停按钮

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 添加空节点
  • 添加按钮 --添加UI节点–按钮
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 效果图:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 填写参数
    在这里插入图片描述

5.添加暂停界面

  • 创建新的空节点
  • 创建渲染节点-单色节点
    在这里插入图片描述
    在这里插入图片描述
  • 创建UI节点 --按钮节点
    在这里插入图片描述
    在这里插入图片描述
  • 添加按钮图片
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 修改尺寸
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 给每个按钮添加事件:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 为背景图添加,组件,控制图层
    在这里插入图片描述
    在这里插入图片描述

6.各界面之间的切换

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
-单词写错
在这里插入图片描述
在这里插入图片描述

7.添加飞机和飞机的动画

  • 创建精灵
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 创建飞机动画
    在这里插入图片描述
    在这里插入图片描述
  • 添加组件
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

8.创建预制资源字段

  • 添加精灵
    在这里插入图片描述
    在这里插入图片描述
  • 创建子弹脚本:
    在game中生成子弹,必须保持子弹始终在飞机的上面。
    然后把子弹精灵,当成预制的资源。
    在这里插入图片描述
    在这里插入图片描述
    然后在我们的gam里面声明我们的子弹:
    在这里插入图片描述
    在这里插入图片描述

9.用对象池创建子弹

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 修改子弹、飞机、背景图的层级关系
    在这里插入图片描述
    在这里插入图片描述

10.声明游戏的不同状态

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

11.移除子弹

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

12.添加广告

在这里插入图片描述
在这里插入图片描述

  • 创建精灵
    在这里插入图片描述
  • 创建文件夹
    在这里插入图片描述
  • 创建按钮,进行关闭广告
    在这里插入图片描述
    在这里插入图片描述
  • 设置九空格
    在这里插入图片描述
    在这里插入图片描述
  • 编写脚本,挂到我们的广告图上面
    在这里插入图片描述
    在这里插入图片描述
  • 点击广告关闭,跳转到我们的游戏界面
    在这里插入图片描述


cc.Class({
    extends: cc.Component,

    properties: {
       label_num:cc.Label,
    },

    

     onLoad () {
         this.timeNum=5
         this.label_num.string = this.timeNum
         this.schedule(function(){
            this.timeNum--
            this.label_num.string = this.timeNum
            if(this.timeNum == 0 ){
                this.goToGame()
            }
         },1)
     },
     goToGame:function(){
            cc.director.loadScene("plane")
     },
     update (dt) {},
});


13.创建敌机

  • 创建精灵
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 把脚本挂载到精灵上面
    在这里插入图片描述
    在这里插入图片描述
  • 在game里面声明,敌机,声明对象池
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

14.子弹与敌机碰撞

  • 添加飞机碰撞组件
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 添加子弹碰撞组件
    在这里插入图片描述
    在这里插入图片描述
  • 在项目设置中添加分组,实现组件碰撞
    在这里插入图片描述

cc.Class({
    extends: cc.Component,

    properties: {
        bg_1:cc.Node,
        bg_2:cc.Node,
        gameReady:cc.Node,
        gamePlaying:cc.Node,
        gamePause:cc.Node,
        gameOver:cc.Node,
        hero:cc.Node,
        pre_bullet:cc.Prefab,
        pre_enemy_1:cc.Prefab,
        pre_enemy_2:cc.Prefab,
        pre_enemy_3:cc.Prefab,
        lab_score:cc.Label,
        lab_bestScore:cc.Label,
        bgm:cc.AudioClip,
        soundDieEnemy:cc.AudioClip,
        soundDieHero:cc.AudioClip,
    },

    onLoad () {
        window.game = this

        // 开启碰撞检测系统,未开启时无法检测
        cc.director.getCollisionManager().enabled = true;
        //cc.director.getCollisionManager().enabledDebugDraw = true;

        this.isBgMove = false
        this.bg_1.y = 0
        this.bg_2.y = this.bg_1.y + this.bg_1.height
        this.setTouch()
        this.gameReady.active = true
        this.gamePlaying.active = false
        this.gamePause.active = false
        this.gameOver.active = false

        this.gamePause.zIndex = 2
        this.gameOver.zIndex = 2
        this.bulletTime = 0
        this.enemyTime = 0
        this.bulletPool = new cc.NodePool()
        this.enemyPool_1 = new cc.NodePool()
        this.enemyPool_2 = new cc.NodePool()
        this.enemyPool_3 = new cc.NodePool()

        this.gameType = 0//(0:ready,1:playing,2:pause,3:over)
        this.randomNUm = [60,90,100]
        this.scoreNum = 0
        this.bestScoreNum = cc.sys.localStorage.getItem('bestScore_1')
        if(this.bestScoreNum == null){
            this.bestScoreNum = 0
        }
        this.addScore(0)

        this.gameTime = 0

        cc.audioEngine.play(this.bgm, true, 1);
    },

    setTouch:function(){
        this.node.on('touchstart', function (event) {
            console.log('touchstart')
            if(this.gameType == 0){
                this.gameType = 1
            }
            this.gameReady.active = false
            this.gamePlaying.active = true
            this.isBgMove = true
        }, this)

        this.node.on('touchmove', function (event) {
            //console.log('touchmove')
            var pos_hero = this.hero.getPosition()
            var pos_move = event.getDelta()
            var pos_end = cc.v2(pos_hero.x + pos_move.x,pos_hero.y + pos_move.y)
            if(pos_end.x < -290){
                pos_end.x = -290
            }else if(pos_end.x > 290){
                pos_end.x = 290
            }
            if(pos_end.y < -533){
                pos_end.y = -533
            }else if(pos_end.y > 533){
                pos_end.y = 533
            }
            this.hero.setPosition(pos_end)
        }, this)

        this.node.on('touchend', function (event) {
            console.log('touchend')
        }, this)
    },

    addScore:function(score){
        this.scoreNum = this.scoreNum + score
        this.lab_score.string = this.scoreNum
        if(this.bestScoreNum < this.scoreNum){
            this.bestScoreNum = this.scoreNum
            cc.sys.localStorage.setItem('bestScore_1', this.bestScoreNum)
        }
        this.lab_bestScore.string = this.bestScoreNum
    },

    playSoundEnemyDie:function(){
        cc.audioEngine.play(this.soundDieEnemy, false, 1);
    },

    playSoundHeroDie:function(){
        cc.audioEngine.play(this.soundDieHero, false, 1);
    },

    gameOverOver:function(){
        this.gameOver.active = true
        this.gamePause.active = false
    },

    clickBtn:function(sender,str){
        if(str == 'pause'){
            cc.log('点击了暂停按钮')
            this.gameType = 2
            this.gamePause.active = true
        }else if(str == 'continue'){
            cc.log('点击了继续按钮')
            this.gameType = 1
            this.gamePause.active = false
        }else if(str == 'reStart'){
            cc.log('点击了重新开始按钮')
            this.gameTime = 0
            this.scoreNum = 0
            this.addScore(0)
            this.gameType = 1
            this.gameOver.active = false
            this.gamePause.active = false
            this.removeAllBullet()
            this.removeAllEnemy()
            this.hero.setPosition(cc.v2(0,-350))
            var js = this.hero.getComponent('hero')
            if(js){
                js.init()
            }
        }else if(str == 'backHome'){
            cc.log('点击了返回主页按钮')
            this.gameTime = 0
            this.scoreNum = 0
            this.addScore(0)
            this.gameType = 0
            this.gameOver.active = false
            this.gamePause.active = false
            this.gamePlaying.active = false
            this.gameReady.active = true
            this.isBgMove = false
            this.removeAllBullet()
            this.removeAllEnemy()
            this.hero.setPosition(cc.v2(0,-350))
            var js = this.hero.getComponent('hero')
            if(js){
                js.init()
            }
        }
    },

    setBg:function(){
        this.bg_1.y = this.bg_1.y - 2
        this.bg_2.y = this.bg_2.y - 2
        if(this.bg_1.y <= -this.bg_1.height){
            this.bg_1.y = this.bg_2.y + this.bg_1.height
        }
        if(this.bg_2.y <= -this.bg_1.height){
            this.bg_2.y = this.bg_1.y + this.bg_1.height
        }
    },

    creatBullet:function(){
        let bullet = null;
        if (this.bulletPool.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
            bullet = this.bulletPool.get();
        } else { // 如果没有空闲对象,也就是对象池中备用对象不够时,我们就用 cc.instantiate 重新创建
            bullet = cc.instantiate(this.pre_bullet)
        }
        bullet.parent = this.node
        var pos = this.hero.getPosition()
        bullet.setPosition(cc.v2(pos.x,pos.y + this.hero.height / 2 + 5))
    },

    createnemy:function(enemyType){
        let enemy = null
        var str = ''
        var pos_enemy = cc.v2(0,0)
        if(enemyType == 1){//创建敌机1
            if (this.enemyPool_1.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
                enemy = this.enemyPool_1.get();
            } else { // 如果没有空闲对象,也就是对象池中备用对象不够时,我们就用 cc.instantiate 重新创建
                enemy = cc.instantiate(this.pre_enemy_1)
            }
            str = 'enemy_1'
            pos_enemy.x = -320 + Math.random() * 640
            pos_enemy.y = 666 + Math.random() * 200
        }else if(enemyType == 2){//创建敌机2
            if (this.enemyPool_2.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
                enemy = this.enemyPool_2.get();
            } else { // 如果没有空闲对象,也就是对象池中备用对象不够时,我们就用 cc.instantiate 重新创建
                enemy = cc.instantiate(this.pre_enemy_2)
            }
            str = 'enemy_2'
            pos_enemy.x = -320 + Math.random() * 640
            pos_enemy.y = 666 + Math.random() * 200
        }else if(enemyType == 3){//创建敌机3
            if (this.enemyPool_3.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
                enemy = this.enemyPool_3.get();
            } else { // 如果没有空闲对象,也就是对象池中备用对象不够时,我们就用 cc.instantiate 重新创建
                enemy = cc.instantiate(this.pre_enemy_3)
            }
            str = 'enemy_3'
            pos_enemy.x = -300 + Math.random() * 600
            pos_enemy.y = 740 + Math.random() * 200
        }
       
        enemy.parent = this.node
        var js = enemy.getComponent(str)
        if(js){
            js.init()
        }
        enemy.setPosition(pos_enemy)
    },

    onBulletKilled: function (bullet) {
        // enemy 应该是一个 cc.Node
        this.bulletPool.put(bullet); // 和初始化时的方法一样,将节点放进对象池,这个方法会同时调用节点的 removeFromParent
    },

    onEnemyKilled: function (enemy,enemyType) {
        if(enemyType == 1){
            this.enemyPool_1.put(enemy)
        }else if(enemyType == 2){
            this.enemyPool_2.put(enemy)
        }else if(enemyType == 3){
            this.enemyPool_3.put(enemy)
        }
    },

    removeAllBullet:function(){
        var children = this.node.children
        for (let i = children.length - 1; i >= 0; i--) {
            var js = children[i].getComponent('bullet')
            if(js){
               this.onBulletKilled(children[i]) 
            }
        }
    },

    removeAllEnemy:function(){
        var children = this.node.children
        for (let i = children.length - 1; i >= 0; i--) {
            if(children[i].getComponent('enemy_1')){
               this.onEnemyKilled(children[i],1) 
            }else if(children[i].getComponent('enemy_2')){
                this.onEnemyKilled(children[i],2) 
            }else if(children[i].getComponent('enemy_3')){
                this.onEnemyKilled(children[i],3) 
            }
        }
    },

    update (dt) {
        if(this.isBgMove){
            this.setBg()
        }

        var randomNumEnemy = 5
        if(this.gameType == 1){
            this.gameTime++
            if(this.gameTime % 300 == 0){
                randomNumEnemy = randomNumEnemy + Math.round(this.gameTime / 300)
                if(randomNumEnemy > 20){
                    randomNumEnemy = 20
                }
                this.randomNUm[0] = this.randomNUm[0] - 2
                this.randomNUm[1] = this.randomNUm[1] - 1
                if(this.randomNUm[0] < 40){
                    this.randomNUm[0] = 40
                }
                if(this.randomNUm[1] < 75){
                    this.randomNUm[1] = 75
                }
            }
        }

        this.bulletTime++
        if(this.bulletTime == 8){
            this.bulletTime = 0
            if(this.gameType == 1){
                this.creatBullet()
            }
        }

        this.enemyTime++
        if(this.enemyTime == 120){
            this.enemyTime = 0
            var num_random = Math.floor(Math.random() * randomNumEnemy) + 1
            for (let i = 0; i < num_random; i++) {
                if(this.gameType == 1 || game.gameType == 3){//playing
                    var num = Math.random() * 100
                    if(num < this.randomNUm[0]){
                        this.createnemy(1)
                    }else if(num < this.randomNUm[1]){
                        this.createnemy(2)
                    }else if(num < this.randomNUm[2]){
                        this.createnemy(3)
                    }
                }
            }
           
        }
        
        cc.log(this.node.children.length)
       
    },
});

在这里插入图片描述
在这里插入图片描述

本文地址:https://blog.csdn.net/qq_32370913/article/details/107401037

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网