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 分钟前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
索迪迈科技4 分钟前
网络请求库——Axios库深度解析
前端·网络·vue.js·北京百思可瑞教育·百思可瑞教育
gnip12 分钟前
JavaScript二叉树相关概念
前端
attitude.x1 小时前
PyTorch 动态图的灵活性与实用技巧
前端·人工智能·深度学习
β添砖java1 小时前
CSS3核心技术
前端·css·css3
空山新雨(大队长)1 小时前
HTML第八课:HTML4和HTML5的区别
前端·html·html5
猫头虎-前端技术2 小时前
浏览器兼容性问题全解:CSS 前缀、Grid/Flex 布局兼容方案与跨浏览器调试技巧
前端·css·node.js·bootstrap·ecmascript·css3·媒体
阿珊和她的猫2 小时前
探索 CSS 过渡:打造流畅网页交互体验
前端·css
元亓亓亓2 小时前
JavaWeb--day1--HTML&CSS
前端·css·html