基于Cocos Creator开发的打砖块游戏

一、简介

  • Cocos简而言之就是一个开发工具,详见官方网站
  • TypeScript简而言之就是开发语言,是JavaScript的一个超集详解官网

今天我们就来学习如何写一个打砖块的游戏,很简单的一个入门级小游戏。

二、实现过程

2.1 布局部分

首先来一个整体的工程界面:

一看就很简单吧,就几个元素+脚本(之所以分开写是为了便于查错)。

再来一个游戏界面:很简洁有木有?当然啦,美观的工作需要各位小伙伴自行发挥啦。好了,下面进入正题…

首先,创建一个新的“世界”名字叫game。将场景设置为640X960

然后,你在这个世界花了1亿买了一块地皮,当然得有地契“BG”(在Canvas下新增一个空节点将大小改为640X960,或者你自己选择一张背景,拖在Canvas下设置大小就ok了,至于其他的就默认)

好了,有地皮了,你就可以“为所欲为”了。先添加砖块吧:

将砖块拖到Canvas下,然后拖回Texture就成了预制体(很简单有木有)。

至于大小什么的可以用代码控制。

因为是砖块,要和小球碰撞,所以要加上物理碰撞。

知识点

  • cc.RigidBodyType.Static:静态刚体,零质量,零速度,即不会受到重力或速度影响,但是可以设置他的位置来进行移动
  • cc.RigidBodyType.Dynamic:动态刚体,有质量,可以设置速度,会受到重力影响
  • cc.RigidBodyType.Kinematic:运动刚体,零质量,可以设置速度,不会受到重力的影响,但是可以设置速度来进行移动
  • cc.RigidBodyType.Animated:动画刚体,在上面已经提到过,从 Kinematic 衍生的类型,主要用于刚体与动画编辑结合使用

这里我们选择

  • Type:Static(静止),在那等着小球来碰撞。然后给他添加一个包围盒PhysicsBoxCollider
  • PhysicsBoxCollider 类型,摩擦力、弹性系数请自由发挥

再来是我们的主角:

同样的给他一个碰撞组件,Type: Dynamic;然后添加包围盒

下面就是托盘,也是Static

然后添加一个空节点,大小比BG小一些,他的作用其实就是“围墙”,避免小球或托盘飞出场景。同时添加碰撞组件和包围盒。

然后还有个foot_line,这个就是监测小球掉下去游戏结束。

还有个count ,后面再说这个计数。好了,罗里吧嗦的布局就完成了。

2.2 代码部分

我们首先建一个game的游戏脚本,用来初始化一些节点(其实所有的代码都可以放在一个脚本里,但是遇到复制的程序的时候不便于查错,所以该分开写的还是要分开写。

首先呢,我们要加载一些节点变量。写代码的时候带上注释是好习惯哦!

我们来一个创建砖块的方法吧:

我采用的是中规中矩的生成方法,通过i和j控制行和列,然后在设置横向间距即可最后生成的结果为:(其他的样式,只要找到规律生成即可。)

再来我们看onload方法:

第二句先忽略。因为小球和砖块碰撞会产生效果,所以要开启物理碰撞(默认是关闭的)。托盘是根据手指移动的,所以要监听手指的移动:

知识点

我们这里用touch_move,接着需要

//获取点击的坐标并转换成节点坐标系坐标
let eposition = self.node.convertToNodeSpaceAR(event.getLocation());

然后设置托盘的位置即可。托盘是左右移动的,所以还需要控制他不能移出屏幕

//控制不能移除屏幕
let minx = -self.node.width / 2 + this.wall.width / 2;//最小坐标
let maxx = -minx;
if (this.wall.x > maxx) {this.wall.x = maxx;
}
if (this.wall.x < minx) {this.wall.x = minx;
}

场景开始加载的时候我们需要快速的生成好砖块,所以这用了定时器使用计时器

//自动生成砖块
self.schedule(function () { self.createbrick(); }, 0.2, 1);

第一个参数就是回调方法,第二个是时间间隔,每隔多少秒调用一次,第三个是执行次数,默认为0执行一次。

好了,初始代码完了,简单吧(其实还有些新增的东西,如障碍物和多个小球的生成,这个我们就后面再讲)。

然后我把脚本挂在Canvas上,并把相应的节点和组件拖进去。运行可以看到已经生成了砖块了吧。

再来我们看主角:ball,同样的给他创建一个脚本ball并挂在小球上。

这个脚本的作用主要是检测,碰撞检测。关于碰撞标签tag,按顺序给碰撞体添加即可。

onBeginContact(contact:cc.PhysicsContact,selfCollider:cc.PhysicsCollider,otherCollider:cc.PhysicsCollider):void{}

用碰撞的tag来区分与小球(self)碰撞的是哪个碰撞体。如果是托盘,那就给小球一个速度。如果是托盘没接住小球掉下去了,游戏结束我们就要跳转到结束界面(后面讲)。

接着就是砖块了:

这个呢主要就是加分用的。基本是完工了,很简单的有木有。

再来看结束的场景:

创建一个结束的场景Sence,同样的需要一个脚本overcount,脚本里需要处理的是:

  • 接收主场景传过来的分数并做展示,此处我直接把节点给传过来了
  • 重新开始按钮功能

第一个,分数节点,我们创建一个label节点但是因为要是常驻节点所以它和Canvas平级。

然后新建一个脚本挂在此节点上

onLoad () {cc.game.addPersistRootNode(this.node);
}

声明它为常驻节点。

Brick.ts:当小球和砖块碰撞的时候呢,分数+1,并且要销毁砖块。

if (otherCollider.tag == 0) {//球和砖块碰撞let gamecc = cc.director.getScene().getChildByName('count').getComponent(cc.Label);gamecc.string = String(Number(gamecc.string) + 1);this.node.destroy();

拿到分数后,ball.ts:

if(otherCollider.tag==5){//球和foot_line碰撞cc.director.getPhysicsManager().enabled = false;cc.find('Canvas').destroyAllChildren();cc.director.loadScene('over');       
}

如果小球掉下去了(托盘没接到),然后我们将小球的物理状态关掉,清除game场景下的所有节点并跳转到结束场景over。

Over场景中有一个重新开始的按钮overcount.ts:

需要做的就是获取分数并将分数复制给结束界面的Label,然后隐藏此常驻节点。

let gamecount = cc.director.getScene().getChildByName('count').getComponent(cc.Label);
gamecount.node.active = false;
this.overcount.string = gamecount.string;self.again.on(cc.Node.EventType.TOUCH_START, function () {gamecount.string = String(0);cc.director.loadScene('game');}, self)

点击重新开始按钮,那么需要把分数置为0,当然还没完,前面我们是关闭了分数计数节点,现在需要打开Game.ts

onLoad() {let self = this;//开启分数节点cc.director.getScene().getChildByName('count').getComponent(cc.Label).node.active = true;

好了,到这你就可以让你的程序跑起来了。

2.3 新增功能

障碍物

障碍物很简单的,也是通过预制体,然后给它上面挂个label用来当小球碰到障碍物的时候,这个数值自减最后在总分数上加上这个分值。

创建一个bar脚本并挂在此节点上,Bar.ts

脚本的作用呢就是给障碍物一个常量,小球和障碍物每碰撞一次就减1,当小于1 的时候就给总发加上3分。

好了,大概就是这些了,项目其实很简单。多练、多写ヾ(◍°∇°◍)ノ゙

还有添加隐藏的小球,碰撞后生成多个小球!这个请小伙伴自行发挥了…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/60428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8改进 | 利用YOLOv8进行视频划定区域目标统计计数

简介 本项目旨在利用YOLOv8算法来实现视频中划定区域目标的统计计数。YOLOv8是一种目标检测算法,能够实现实时目标检测和定位。视频划定区域目标统计计数是指在一个视频中,对于指定的区域,统计出该区域内出现的目标物体数量。 该项目的工作流程如下:首先,利用YOLOv8算法…

【数据结构】线性表——栈与队列

写在前面 栈和队列的关系与链表和顺序表的关系差不多&#xff0c;不存在谁替代谁&#xff0c;只有双剑合璧才能破敌万千~~&#x1f60e;&#x1f60e; 文章目录 写在前面一、栈1.1栈的概念及结构1.2、栈的实现1.2.1、栈的结构体定义1.2.2、栈的初始化栈1.2.3、入栈1.2.4、出栈…

Django 的 ModelViewSet 中的 get_queryset 方法自定义查询集

场景&#xff1a;每次调用接口&#xff0c;自动更新某个字段 基于Django REST framework class ApiDataTrackingView(ModelViewSet):queryset ApiDataTracking.objects.all()serializer_class ApiDataTrackingSerializersfilterset_class ApiDataTrackingFilterordering_f…

Rust编程与项目实战-特质(Trait)

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust编程与项目实战_夏天又到了的博客-CSDN博客 特质&#xff08;Trait&#xff09;是Rust中的概念&#xff0c;类似于其他语言中的接…

uniapp中使用全局样式文件引入的三种方式

如果你想在 uni-app 中全局引入 SCSS 文件&#xff08;例如 global.scss&#xff09;&#xff0c;可以通过以下步骤进行配置&#xff1a; 方法一&#xff1a;在 main.js 中引入 在 main.js 中引入全局样式&#xff1a; 你可以在 src/main.js 文件中直接引入 SCSS 文件&#xff…

运维之systemd 服务(Systemd Service of Operations and Maintenance)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

Vue — 组件化开发

组件化开发&#xff1a;一个页面可以拆分成一个个组件&#xff1b;每个组件都有自己独立的结构、样式、行为 组件分类&#xff1a;普通组件、根组件 其中根组件包裹着所有普通小组件 普通组件的注册使用&#xff1b;有两种注册方式 局部注册全局注册 局部注册 目标&#xff…

【学习】【HTML】HTML、XML、XHTML

HTML 什么是 HTML&#xff1f; HTML (HyperText Markup Language) 是一种用于创建和展示网页的标准标记语言。它由一系列的元素组成&#xff0c;这些元素通过标签的形式来告诉浏览器如何显示内容。 HTML 的基本结构是什么&#xff1f; <!DOCTYPE html> <html> …

【软考】系统架构设计师-计算机系统基础(2):操作系统

1、操作系统基础 OS的5个核心功能&#xff1a;进程管理、存储管理、设备管理、文件管理、作业管理 OS的3个作用&#xff1a;管理运行的程序和分配各种软硬件资源&#xff1b;提供友善的人机界面&#xff1b;为程序应用的开发和运行提供高效的平台 OS的4个特征&#xff1a;并…

Android ANR分析总结

1、ANR介绍 ANR&#xff08;Application Not Responding&#xff09;指的是应用程序无响应&#xff0c;当Android应用程序在主线程上执行长时间运行的操作或阻塞I/O操作时发生。这可能导致应用程序界面冻结或无法响应用户输入。 1、Service ANR&#xff1a;前台20s&#xff0…

WebRTC视频 01 - 视频采集整体架构

一、前言&#xff1a; 我们从1对1通信说起&#xff0c;假如有一天&#xff0c;你和你情敌使用X信进行1v1通信&#xff0c;想象一下画面是不是一个大画面中有一个小画面&#xff1f;这在布局中就叫做PIP&#xff08;picture in picture&#xff09;&#xff1b;这个随手一点&am…

编译ffmpeg动态库时设置RPATH为$ORIGIN

原本&#xff0c;我这样编译: ./configure \--enable-xxx \--disable-yyy \...为了设置 RPATH, 尝试了在 configure 后面设置&#xff0c;如下几种都无效: --extra-ldsoflags"-Wl,-rpath,$ORIGIN" 没有 RPATH--extra-ldsoflags"-Wl,-rpath,$ORIGIN" 没有…

什么是 DAPP?它能解决什么问题?

在区块链技术日益火热的今天&#xff0c;DAPP 这个概念也逐渐走入人们的视野。但是很多人都听到了DAPP这个词&#xff0c;但是大部分人却还是不清楚什么是 DAPP&#xff1f;它又能解决什么问题呢&#xff1f;接下来这篇文章就带大家了解一下DAPP。 一、什么是 DAPP&#xff1f…

C++ 中的 JSON 序列化和反序列化:结构体与枚举类型的处理

在 C 编程中&#xff0c;处理 JSON 数据是一项常见任务&#xff0c;特别是在需要与其他系统或前端进行数据交换时。nlohmann::json 库是一个功能强大且易于使用的 JSON 库&#xff0c;它允许我们轻松地在 C 中进行 JSON 数据的序列化和反序列化。本文将详细介绍如何使用 nlohma…

ESLint 使用教程(三):12个ESLint 配置项功能与使用方式详解

前言 在现代前端开发中&#xff0c;代码质量与一致性是至关重要的&#xff0c;ESLint 正是为此而生的一款强大工具&#xff0c;本文将带您详细了解 ESLint 的配置文件&#xff0c;并通过通俗易懂的方式讲解其主要配置项及其配置方法。此外&#xff0c;我们还将探讨一些高级配置…

linux可执行文件添加到PATH环境变量的方法

linux可执行文件添加到PATH环境变量的方法 linux命令行下面执行某个命令的时候&#xff0c;首先保证该命令是否存在&#xff0c;若存在&#xff0c;但输入命令的时候若仍提示&#xff1a;command not found 这个时候就的查看PATH环境变量的设置了&#xff0c;当前命令是否存在于…

Android 14 SPRD 下拉菜单中增加自动亮度调节按钮

为了在 Android 14 的下拉菜单中增加自动亮度调节按钮&#xff0c;可以按照以下步骤进行代码修改。 1. 添加图标资源 在 SystemUI 资源文件夹中添加自动亮度图标&#xff1a; 文件路径&#xff1a; frameworks/base/packages/SystemUI/res/drawable/ic_settings_display_wh…

Jenkins应用详解(Detailed Explanation of Jenkins Application)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

【LeetCode】【算法】5. 最长回文子串

LeetCode 5. 最长回文子串 题目描述 给你一个字符串s&#xff0c;找到 s 中最长的回文子串。 思路 思路&#xff1a;中心扩散法 遍历字符串s&#xff0c;对每一个字符用中心扩散法。确定好中点之后向两边扩散&#xff0c;若两边字符相同则len2。若遍历下来len>maxLen则记…

开源数据库 - mysql - mysql-server-8.4(gtid主主同步+ keepalived热切换)部署方案

前置条件 假设主从信息 mysqlhostport主192.168.1.13306从192.168.1.23306vip192.168.1.3 部署流程 导出测试环境表结构与数据 使用mysqldump ./mysqldump -ulzzc -p -S /tmp/mysql3306.sock --single-transaction --database lzzc > databaseLZZCxxxx.sql查看gtid号 …