CocosCreator入门之《摘星星》-完全学习记录

Posted forrestcui94

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CocosCreator入门之《摘星星》-完全学习记录相关的知识,希望对你有一定的参考价值。

 

星星模块涉及内容:

  • 使用对象池
  • 使用进度条
  • 文字的简单显/隐/变

完成态预览:

技术图片

技术图片

技术图片

写在前面: 原来的坐标随机逻辑,测试100次还是10万次,前后两颗星星近乎重叠的概率都是10%,也就是每得十分、就有一次莫名其妙吃了一颗甚至几颗星星的负体验。

为突出目标,仅附上在完成主角模块(点击开始,主角能跳、动,屏幕有边界)基础上的新增内容,并不能直接运行

  1 // Game.js
    const Player = require(‘Player‘); 2 3 cc.Class({ 4 extends: cc.Component, 5 6 properties: { 7 minStarDuration: 0, 8 maxStarDuration: 0, 9 starPrefab: { 10 default: null, 11 type: cc.Prefab 12 }, 13 progressBarOfStar: { 14 default: null, 15 type: cc.ProgressBar 16 }, 17 scoreAudio: { 18 default: null, 19 type: cc.AudioClip 20 }, 21 nameAndScore: cc.Label, 22 instructionGoal: cc.Label, 23 controlHint: cc.Label, 24 isMobile: { 25 default: ‘‘, 26 multiline: true 27 }, 28 isPC: { 29 default: ‘‘, 30 multiline: true 31 }, 32 }, 33 34 onLoad () { 35 this.enabled = false; 36 this.controlHint.string = cc.sys.isMobile ? this.isMobile : this.isPC; 37 // 保存当前星星,失败时放不到对象池,手动销毁 38 this.currentStar = null; 39 // 保存当前星星X坐标与下个X坐标作比较,防止前后两颗星星距离过近造成负体验 40 this.currentStarX = 0; 41 this.starPool = new cc.NodePool(‘StarPrefab‘); 42 this.starDuration = 0; 43 /** 44 * 初始化进度值,1.0为从满倒带,0.0为从空到满 45 * progress(进度值)只能是0-1之间的浮点数 46 * 组件默认progress就是1,不设置也可,但误触了属性检查器的progress会出错 47 */ 48 this.progressBarOfStar.progress = 1.0; 49 }, 50 51 start() { 52 this.score = 0; 53 this.starTimer = 0; 54 }, 55 56 onStartBtnClicked() { 57 this.nameAndScore.string = ‘Score: 0‘; 58 // 隐藏(active)是node下面的属性,这里声明Label就要调其下的node 59 this.instructionGoal.node.active = false; 60 this.controlHint.node.active = false; 61 this.score = 0; 62 this.spawnNewStar(); 63 }, 64 65 spawnNewStar() { 66 let newStar = this.starPool.get(); 67 68 if (!newStar) { 69 newStar = cc.instantiate(this.starPrefab); 70 } 71 72 this.node.addChild(newStar); 73 newStar.setPosition(this.randStarPosition()); 74 // 初始化必须在加入主节点之后,先有节点再初始化它 75 newStar.getComponent(‘StarPrefab‘).init(this); 76 this.setStarLife(); 77 this.currentStar = newStar; 78 this.progressBarOfStar.progress = 1.0; 79 }, 80 81 /** 82 * @param {cc.Prefab} star star节点 83 */ 84 despawnStar(star) { 85 this.starPool.put(star); 86 this.spawnNewStar(); 87 }, 88 89 /** 90 * @returns {cc.Vec2} 随机坐标 91 */ 92 randStarPosition() { 93 let randX = 0; 94 // 子节点最大、最小坐标绝对值是父节点宽度的一半 95 let absMaxX = this.node.width / 2; 96 97 // 新X坐标与旧X坐标至少间隔2颗星星的宽度,否则继续随机 98 do { 99 randX = (Math.random() - 0.5) * 2 * absMaxX; 100 } while (Math.abs(randX - this.currentStarX) < 120) 101 102 // 收集半径是60,不加配数可能星星一半穿帮地面,加太多可能碰不到星星,故加50 103 let randY = this.groundY + Math.random() * this.player.getComponent(‘Player‘).jumpHeight + 50; 104 this.currentStarX = randX; 105 106 return cc.v2(randX, randY); 107 }, 108 109 setStarLife() { 110 this.starTimer = 0; 111 this.starDuration = this.minStarDuration + Math.random() * (this.maxStarDuration - this.minStarDuration); 112 }, 113 114 getStarRatio() { 115 return 1 - this.starTimer / this.starDuration; 116 }, 117 118 gainScore() { 119 this.score += 1; 120 this.nameAndScore.string = ‘Score: ‘ + this.score; 121 cc.audioEngine.playEffect(this.scoreAudio, false); 122 }, 123 124 _updateProgressBar() { 125 this.progressBarOfStar.progress = this.getStarRatio(); 126 }, 127 128 update(dt) { 129 this._updateProgressBar(); 130 131 if (this.starTimer > this.starDuration) { 132 this.gameOver(); 133 return; 134 } 135 136 this.starTimer += dt; 137 }, 138 139 gameOver() { 140 this.enabled = false; 141 this.btnNode.x = 0; 142 this.controlHint.node.active = true; 143 this.instructionGoal.node.active = true; 144 this.currentStar.destroy(); 145 this.player.stopMove(); 146 this.saySomeThing(); 147 }, 148 149 saySomeThing() { 150 let score = this.score; 151 let string = this.instructionGoal.string; 152 153 if (score <= 10) { 154 string = ‘Are you kidding me?‘; 155 } else if (score > 10 && score <= 30) { 156 string = ‘Good job, One more try!‘; 157 } else if (score > 30) { 158 string = ‘Great job!‘ 159 } 160 161 this.instructionGoal.string = string; 162 } 163 });
 1 // StarPrefab.js
 2 
 3 cc.Class({
 4   extends: cc.Component,
 5 
 6   properties: {
 7     pickRadius: 0,
 8   },
 9 
10   init(game) {
11     this.enabled = true;
12     this.game = game;
13     this.node.opacity = 255;
14   },
15 
16   onLoad() {
17     // onLoad是节点初始化时调用,对象池是对象复用,故只在第一颗星星调用。
18     // cc.log(‘Star_onLoad()‘);
19     this.enabled = false;
20   },
21 
22   getStarPosition() {
23     return this.node.position;
24   },
25 
26   getPlayerDistance() {
27     let Player = this.game.player;
28     let playerPosition = Player.getCenterPos();
29     let starPosition = this.getStarPosition();
30 
31     return starPosition.sub(playerPosition).mag();
32   },
33 
34   onPicked() {
35     let Game = this.game;
36     Game.gainScore();
37     Game.despawnStar(this.node);
38   },
39 
40   update(dt) {
41     if (this.getPlayerDistance() < this.pickRadius) {
42       this.onPicked();
43       // 此情况就是单纯的将控制权转交给主调函数继续执行
44       return;
45     }
46 
47     let opacityRatio = this.game.getStarRatio();
48     let minOpacity = 50;
49     this.node.opacity = minOpacity + (255 - minOpacity) * opacityRatio;
50   }
51 });

这次没什么插曲,除了拼写错误引发的Bug。但还是想说:

1. 对象池概念初探——https://forum.cocos.org/t/cocoscreator/67879

2. 进度条组件上手——新建一个示例项目,搜progressBar。

复刻这两个练习项目,直到不觉得盲人摸象。

以上是关于CocosCreator入门之《摘星星》-完全学习记录的主要内容,如果未能解决你的问题,请参考以下文章

cocos creator 基础1,小白自学日常。

Cocos Creator开发游戏消灭星星——星星消除

编程猫开发《摘星星小怪物》游戏

编程猫开发《摘星星小怪物》游戏

Arduino 入门之小星星

CocosCreator + JavaScript游戏开发