2个小时能不能做一个跳一跳游戏?

引言

Cocos中实现跳一跳游戏效果

大家好,2023年 快要过去了,你们的游戏都做完了吗

昨天 和朋友们聊天的时候聊到,2个小时 能不能做一个跳一跳游戏?

基于好奇和探索 的心理,笔者尝试了一下2个小时 做个效果勉强 可以,但是想要上线还得 大大优化

本文将介绍一下如何在Cocos中实现跳一跳游戏效果

本文源工程可在文末阅读原文获取,小伙伴们自行前往。

1.什么是跳一跳

可能有很多小伙伴不知道跳一跳是什么游戏。简单介绍一下:

跳一跳是一款由微信推出的小游戏,最初是作为微信内置功能之一。

这款游戏的玩法相对简单 ,玩家需要通过点击屏幕控制一个小人 跳跃,跳跃的目标是跳到不同的方块 上,而方块的距离会有所变化。

跳一跳因其简单有趣的玩法 而在一段时间内风靡一时

我们分析一下里面具体的游戏效果

2.跳一跳需求分析

经过简单的分析 ,跳一跳涉及的游戏效果可能如下:

  • 地块的生成,每次跳跃完成之后会自动生成一块地块,距离和方向随机。
  • 长按屏幕蓄力跳跃,根据玩家按压屏幕的时间决定跳跃的距离。
  • 得分,每次成功跳跃(跳到下一块地块,不掉落)可获得1分。
  • 游戏失败的判断,没有跳到地块上,掉落在地板的判断。

下面一起在Cocos中实现跳一跳游戏效果

3.跳一跳游戏效果的实现

1.环境

引擎版本:Cocos Creator 3.8.1

编程语言:TypeScript

2.资源准备

本期 节目效果继续由跳一跳鸡 和笔者的技能范围指示器 效果友情助攻

3.编写代码

首先 创建一个FloorCreator组件,用来动态生成 跳一跳的地块。其中关键的内容如下:

  • 通过instantiate克隆生成地块。
  • 通过nextFloor数组管理地块,循环使用。
  • 通过Math.random()随机地块方向和距离。
  • 通过add3f(0, 1, 0)给地块一个初始高度,做一个生成效果。

代码如下:

typescript 复制代码
import { _decorator, Component, instantiate, Node, v3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('FloorCreator')
export class FloorCreator extends Component {
    @property(Node)
    floorPfb: Node = null;

    curFloor: Node;
    nextFloor: Node[] = [];
    start() {
        this.curFloor = this.floorPfb;
    }

    public createFloor() {
        var dir = Math.random() < 0.5 ? v3(-1, 0, 0) : v3(0, 0, -1);
        var newFloor = this.nextFloor.length > 1 ? this.nextFloor.shift() : instantiate(this.curFloor);
        newFloor.parent = this.curFloor.parent;
        newFloor.position = this.curFloor.position;
        newFloor.position.add(dir.multiplyScalar(Math.random() * 3 + 1.5)).add3f(0, 1, 0);
        newFloor.active = false;
        newFloor.active = true;
        this.nextFloor.push(this.curFloor);
        this.curFloor = newFloor;
        return {
            dir: dir.normalize(),
            floor: newFloor
        };
    }
}

效果如下:

地块的生成 做好之后,我们创建一个JumpAndJump组件,用于控制整个游戏流程。其中包含一些属性:

  • player,主角的引用。
  • floorCreator,地板生成器的引用。
  • skillRangeIndicator,技能范围指示器的引用。
  • scoreLab,分数标签的引用。
  • 其他一些touchSpeed跳跃距离增长速度、jumpTime跳跃时间、jumpHeight跳跃高度等一些配置。
typescript 复制代码
@ccclass('JumpAndJump')
export class JumpAndJump extends Component {
    @property(Node)
    player: Node = null;
    @property(FloorCreator)
    floorCreator: FloorCreator = null;
    @property(SkillRangeIndicator)
    skillRangeIndicator: SkillRangeIndicator = null;
    @property(Label)
    scoreLab: Label = null;
    @property(CCFloat)
    touchSpeed: number = 0.1;
    @property(CCFloat)
    jumpTime: number = 1;
    @property(CCFloat)
    jumpHeight: number = 1;
}

start方法中监听一下触摸事件:

  • Input.EventType.TOUCH_START触摸开始。
  • Input.EventType.TOUCH_END触摸结束。
  • Input.EventType.TOUCH_CANCEL触摸取消。
typescript 复制代码
start() {
    this.createFloor();
    var node = find("Canvas/ui_joystick_panel");
    node.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
    node.on(Input.EventType.TOUCH_END, this.onTouchEnd, this);
    node.on(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
}

触摸开始的处理:

  • 重新计算跳跃距离this.radius
  • 标记触摸开始this.touching
  • 显示范围指示圈。
  • 播放蓄力动画。
typescript 复制代码
onTouchStart() {
    if (this.gameover || this.jumping) return;
    this.radius = 0;
    this.touching = true;
    if (this.showLine)
        this.skillRangeIndicator.showSkillRangeIndicator(this.player.position);
    this.player.getComponent(SkeletalAnimation).crossFade("anim_rig_sky_jump");
}

触摸过程的处理:

  • 根据时间增加跳跃距离。
  • 根据时间放大范围圈。
typescript 复制代码
protected update(dt: number): void {
    if (this.touching) {
        this.radius += this.touchSpeed;
        if (this.showLine)
            this.skillRangeIndicator.setScale(this.radius);
    }
}

效果如下:

触摸完成的处理:

  • 隐藏范围圈。
  • 通过tween动画实现主角跳跃位移。
  • 跳跃过程中取消重力影响useGravity = false
  • 跳跃成功加分并生成下一个地块。
  • 跳跃失败显示重新挑战按钮。
typescript 复制代码
onTouchEnd() {
    if (this.gameover || !this.touching) return;
    this.player.getComponent(RigidBody).useGravity = false;
    this.touching = false;
    this.skillRangeIndicator.hideSkillRangeIndicator();
    this.jumping = true;

    this.player.getComponent(SkeletalAnimation).crossFade("anim_rig_fly");
    tween(this.player).by(this.jumpTime / 2, { worldPosition: this.dir.clone().multiplyScalar(this.radius / 4).add3f(0, this.jumpHeight, 0) })
        .by(this.jumpTime / 2, { worldPosition: this.dir.clone().multiplyScalar(this.radius / 4).subtract3f(0, this.jumpHeight, 0) }).call(() => {
            this.player.getComponent(RigidBody).useGravity = true;
            this.player.getComponent(SkeletalAnimation).crossFade("anim_rig_idle_2");
            this.jumping = false;
            if (!this.isGameOver()) {
                this.setScore(this.score + 1);
                this.createFloor();
            }
            else {
                this.gameover = true;
                find("Canvas/Button").active = true;
                this.player.getComponent(SkeletalAnimation).crossFade("anim_rig_fall_into_water_die");
            }
        }).start();
}

其中跳跃失败的判断:

  • 超出地块中心0.5即判断失败。
typescript 复制代码
isGameOver() {
    return Math.abs(this.player.worldPosition.x - this.floor.worldPosition.x) > 0.5 || Math.abs(this.player.worldPosition.z - this.floor.worldPosition.z) > 0.5;
}

效果如下:

4.效果演示

以上就是2个小时 完成的游戏效果,你要来试试吗?

结语

本文源工程 可通过私信JumpAndJump 或者阅读原文付费获取。

在哪里 可以看到如此清晰的思路,快跟上我的节奏!关注我 ,和我一起了解 游戏行业最新动态,学习游戏开发技巧。

我是"亿元程序员",一位有着8年游戏行业经验的主程。在游戏开发中,希望能给到您帮助, 也希望通过您能帮助到大家。

AD:笔者线上的小游戏《贪吃蛇掌机经典》《重力迷宫球》《填色之旅》大家可以自行点击搜索体验。

实不相瞒,想要个在看 !请把该文章分享给你觉得有需要的其他小伙伴。谢谢!

推荐专栏:

100个Cocos实例

8年主程手把手打造Cocos独立游戏开发框架

和8年游戏主程一起学习设计模式

从零开始开发贪吃蛇小游戏到上线系列

知识付费专栏

相关推荐
熊的猫2 分钟前
webpack 核心模块 — loader & plugins
前端·javascript·chrome·webpack·前端框架·node.js·ecmascript
速盾cdn9 分钟前
速盾:vue的cdn是干嘛的?
服务器·前端·网络
四喜花露水41 分钟前
Vue 自定义icon组件封装SVG图标
前端·javascript·vue.js
前端Hardy1 小时前
HTML&CSS: 实现可爱的冰墩墩
前端·javascript·css·html·css3
web Rookie1 小时前
JS类型检测大全:从零基础到高级应用
开发语言·前端·javascript
Au_ust1 小时前
css:基础
前端·css
帅帅哥的兜兜1 小时前
css基础:底部固定,导航栏浮动在顶部
前端·css·css3
yi碗汤园2 小时前
【一文了解】C#基础-集合
开发语言·前端·unity·c#
就是个名称2 小时前
购物车-多元素组合动画css
前端·css
编程一生2 小时前
回调数据丢了?
运维·服务器·前端