开心吧

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

HappyClearance开发笔记

[复制链接]

1

主题

3

帖子

4

积分

新手上路

Rank: 1

积分
4
发表于 2023-4-9 19:41:40 | 显示全部楼层 |阅读模式
一、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就会很方便。
randBall(typeCnt) {

    // 获取图集里的图, 返回的是SpriteFrame数组
    let frames = this.ballAtlas.getSpriteFrames();
    this.sprite = this.node.getComponent(cc.Sprite);

    if (typeCnt > frames.length) {

        typeCnt = frames.length;
    }

    cc.log(typeCnt);

    let randIndex = Math.floor(Math.random() * typeCnt);

    cc.log("randIndex:" + randIndex);

    //图集里随机的图,更换节点的sprite.spriteFrame
    this.sprite.spriteFrame = frames[randIndex];
}
4、window全局变量


5、动态生成小球

游戏中的小球是如何动态生成和销毁的呢?这里使用到了对象池的概念。
对象池就是一组可回收的节点对象,我们通过创建cc.NodePool的实例来初始化一种节点的对象池。通常当我们有多个 prefab 需要实例化时,应该为每个 prefab 创建一个cc.NodePool实例。当我们需要创建节点时,向对象池申请一个节点,如果对象池里有空闲的可用节点,就会把节点返回给用户,用户通过 node.addChild 将这个新节点加入到场景节点树中。 当我们需要销毁节点时,调用对象池实例的 put(node) 方法,传入需要销毁的节点实例,对象池会自动完成把节点从场景节点树中移除的操作,然后返回给对象池。这样就实现了少数节点的循环利用。—Introduction · Cocos Creator

for (let i = 0; i < ballCnt; i++) {

    let ballNode = null;

    // 如果节点不存在
    if (!this.ballNodeArr) {
            
        if (ballNode == null) {

            ballNode = this.ballPool.get();

            ballNode = cc.instantiate(this.ballPrefab);
            this.ctrlAreaNode.addChild(ballNode);
            this.ballNodeArr.push(ballNode);
        }
    }
    else {

        //如果存在,即已生成,则直接从数组里取出
        ballNode = this.ballNodeArr;
    }

    ballNode.getComponent('ball').randBall(typeCnt);   
}
6、游戏倒计时

游戏倒计时的实现,使用了scheduleOnce。游戏结束3s后,重新开始新的游戏。
下面是 Component 中所有关于计时器的函数:
schedule:开始一个计时器
scheduleOnce:开始一个只执行一次的计时器
unschedule:取消一个计时器
unscheduleAllCallbacks:取消这个组件的所有计时器
update (dt) {

    this.nowTime += dt;

    let resTime = Math.floor(this.time - this.nowTime);

    if (resTime <= 0) {

        this.gameOver = true;
        this.hintLabel.string = '时间到, 游戏结束, 3s后重新开始';

        this.clearScreen();

        // 3s后重新开始
        this.scheduleOnce(function(){
               
            this.init();
            this.unscheduleAllCallbacks(this);
        },3);

        return;
    }
    else{
        cc.log('剩余时间:', resTime);
        this.hintLabel.string = 'level : ' + this.level + ', time : ' + resTime + 's';
    }
}
7、添加背景音乐

添加背景音乐的做法是在脚本中使用AudioEngine的api来控制,具体的示例代码如下。游戏开始时,使用cc.audioEngine.playMusic进行播放。
init() {

    if (this.bgmAudio != null) {

        this.bgmAudioID = cc.audioEngine.playMusic(this.bgmAudio, true);
    }
}
未完待续。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|开心吧

Powered by Discuz! X3.4 © 2001-2012 Comsenz Inc.

GMT+8, 2025-4-7 11:38 , Processed in 0.498964 second(s), 23 queries .

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