找回密码
 立即注册
查看: 162|回复: 0

HappyClearance开发笔记

[复制链接]
发表于 2024-7-15 18:33 | 显示全部楼层 |阅读模式
一、HappyClearance简介

HappyClearance是类似于消消乐的休闲小游戏,玩法简单,易于上手。
1、游戏演示

2、游戏法则

游戏开始时,会自动生成一排小球,小球的颜色是随机的,一共有6种分歧的颜色。玩家把所有小球的颜色点成一样的之后,进入下一个level,而且前4个level是30s的倒计时,之后的level是40s的倒计时。倒计时结束后,玩家未能把所有小球颜色点成一样的,游戏从头开始。
二、HappyClearance开发规划

1、工程目录规划

创建好游戏工程后,需要规划工程目录,任何一个游戏项目,都需要有完善的目录布局规划,将场景、图片、脚本、音频、动画等资源进行分门别类保留。项目中,笔者把目录布局规划为Audios、Prefabs、Scenes、Scripts、Textures等目录。创建好的目录,如下图所示。



工程目录布局

2、场景规划和搭建

游戏中使用的设计分辩率是720x1280的竖屏模式,在场景中的Canvas根节点设置如下图所示。按照情况来选择适配策略,这里选择的是Fit Height和Fit Width,暗示不管屏幕宽高比如何,都完整显示设计分辩率中的所有内容,并添加一个Widget组件,使其填充满整个屏幕。创建好工程后,引擎默认自动打开一个场景,此中包罗了Canvas节点及其子节点Main Camera。按Ctrl+S组合键,保留整个场景到Scenes目录,并给场景起名为Game。


3、界面设计和框架


三、HappyClearance具体实现

1、添加游戏节点

在Canvas节点下,新建一个空节点,改削节点名称为bg,作为一个容器节点,并添加一个Widget组件使其填充满整个屏幕。
Widget (对齐组件) 是一个很常用的 UI 布局组件。它能使当前节点自动对齐到父物体的任意位置,或者约束尺寸,让你的游戏可以便利地适配分歧的分辩率。
节点层级说明如下:

  • bg:空节点,挂载游戏主控脚本。
  • bg/ctrlArea:Sprite(单色)节点,游戏主区域。
  • bg/hint:Label节点,等级及倒计时提示Label。
  • logo:图片,显示游戏名称。
2、制作预制体

每个自动生成的小球都是一个预制体,创建与改削ball预制体的方式如下:
(1)在Canvas节点下,创建一个Sprite节点,定名为ball,大小设置为(64,64)。
(2)在ball节点的Sprite的Atlas属性中,添加图集资源,并挂载脚本ball.ts。
(3)给ball节点添加UI组件-Button组件,并添加一个点击事件,使其实现点击一下ball,可以自动切换图片。
(4)拖动ball节点到资源打点器的Prefab目录中,并删除场景中的ball节点,这样,就创建了小球的预制体。
(5)在资源打点器中,双击ball节点,可改削预制体。



制作预制体

3、读取图集
图集(Atlas)也称作 Sprite Sheet,是游戏开发中常见的一种美术资源。图集是通过专门的东西将多张图片合并成一张大图,并通过plist等格式的文件索引的资源。可供 Cocos Creator 使用的图集资源由plistpng文件组成。
Cocos Creator中,使用SpriteAltas暗示一个图集。当需要动态改削一个cc.Sprite的spriteFrame属性时,如果是使用数组,遇到图片资源斗劲多时,比如100张图片,那么操作起来就会很麻烦。这时,使用cc.SpriteAtlas就会很便利。
  1. randBall(typeCnt) {
  2.     // 获取图集里的图, 返回的是SpriteFrame数组
  3.     let frames = this.ballAtlas.getSpriteFrames();
  4.     this.sprite = this.node.getComponent(cc.Sprite);
  5.     if (typeCnt > frames.length) {
  6.         typeCnt = frames.length;
  7.     }
  8.     cc.log(typeCnt);
  9.     let randIndex = Math.floor(Math.random() * typeCnt);
  10.     cc.log(”randIndex:” + randIndex);
  11.     //图集里随机的图,改换节点的sprite.spriteFrame
  12.     this.sprite.spriteFrame = frames[randIndex];
  13. }
复制代码
4、window全局变量


5、动态生成小球

游戏中的小球是如何动态生成和销毁的呢?这里使用到了对象池的概念。
对象池就是一组可回收的节点对象,我们通过创建cc.NodePool的实例来初始化一种节点的对象池。凡是当我们有多个 prefab 需要实例化时,应该为每个 prefab 创建一个cc.NodePool实例。当我们需要创建节点时,向对象池申请一个节点,如果对象池里有空闲的可用节点,就会把节点返回给用户,用户通过 node.addChild 将这个新节点插手参加景节点树中。 当我们需要销毁节点时,调用对象池实例的 put(node) 方式,传入需要销毁的节点实例,对象池会自动完成把节点从场景节点树中移除的操作,然后返回给对象池。这样就实现了少数节点的循环操作。—Introduction · Cocos Creator
  1. for (let i = 0; i < ballCnt; i++) {
  2.     let ballNode = null;
  3.     // 如果节点不存在
  4.     if (!this.ballNodeArr[i]) {
  5.             
  6.         if (ballNode == null) {
  7.             ballNode = this.ballPool.get();
  8.             ballNode = cc.instantiate(this.ballPrefab);
  9.             this.ctrlAreaNode.addChild(ballNode);
  10.             this.ballNodeArr.push(ballNode);
  11.         }
  12.     }
  13.     else {
  14.         //如果存在,即已生成,则直接从数组里取出
  15.         ballNode = this.ballNodeArr[i];
  16.     }
  17.     ballNode.getComponent(&#39;ball&#39;).randBall(typeCnt);   
  18. }
复制代码
6、游戏倒计时

游戏倒计时的实现,使用了scheduleOnce。游戏结束3s后,从头开始新的游戏。
下面是 Component 中所有关于计时器的函数:
schedule:开始一个计时器
scheduleOnce:开始一个只执行一次的计时器
unschedule:打消一个计时器
unscheduleAllCallbacks:打消这个组件的所有计时器
  1. update (dt) {
  2.     this.nowTime += dt;
  3.     let resTime = Math.floor(this.time - this.nowTime);
  4.     if (resTime <= 0) {
  5.         this.gameOver = true;
  6.         this.hintLabel.string = &#39;时间到, 游戏结束, 3s后从头开始&#39;;
  7.         this.clearScreen();
  8.         // 3s后从头开始
  9.         this.scheduleOnce(function(){
  10.                
  11.             this.init();
  12.             this.unscheduleAllCallbacks(this);
  13.         },3);
  14.         return;
  15.     }
  16.     else{
  17.         cc.log(&#39;残剩时间:&#39;, resTime);
  18.         this.hintLabel.string = &#39;level : &#39; + this.level + &#39;, time : &#39; + resTime + &#39;s&#39;;
  19.     }
  20. }
复制代码
7、添加布景音乐

添加布景音乐的做法是在脚本中使用AudioEngine的api来控制,具体的示例代码如下。游戏开始时,使用cc.audioEngine.playMusic进行播放。
  1. init() {
  2.     if (this.bgmAudio != null) {
  3.         this.bgmAudioID = cc.audioEngine.playMusic(this.bgmAudio, true);
  4.     }
  5. }
复制代码
未完待续。。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-23 16:25 , Processed in 0.101994 second(s), 28 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表