B站视频:【Creator3】好玩的编队代码 魔性排列停不下来 附源码及出处
这次带来一个有趣的编队代码,简单的算法得到令人惊叹的编队队形,叹为观止,前几天刷视频的时候看到一个有趣的展示,来自youtube大神:Tarodev的队形计算展示《 Fun with Formations - Game Dev Adventure》
他的是Unity实现的,我用最新发布的Creator 3.3版本制作了一个,视频如下:
参考资料:https://www.youtube.com/watch?v=NEFxWkTRVCc
开发工具 CocosCreator 3.3.0
BGM: Jazzy Frenchy form bensound
Creator3以后的引擎,对于3D方面的计算基本上和Unity很像了,转译C#代码并不难,原版代码在这里:GitHub - Matthew-J-Spencer/Formations: Some simple scripts to create formations in Unity
CocosCreator中的关键代码如下:
/** 编队的基类 */
import { _decorator, Component, Node, Vec3, v3 } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('BaseFormation')
export class BaseFormation extends Component {
@property
noise: number = 0;
@property
Spread: number = 1;
offsetPos:Vec3 = v3();
EvaluatePoints(): Vec3[] {
return null;
}
GetNoise(pos: Vec3): Vec3 {
const noise = this.noise;
const x = pos.x + Math.random() * noise - noise / 2;
const z = pos.z + Math.random() * noise - noise / 2;
pos.x = x;
pos.z = z;
return pos;
}
}
/** 方形编队组件脚本代码 */
import { _decorator, Component, Node, Vec3, v3 } from 'cc';
import { BaseFormation } from './BaseFormation';
const { ccclass, property } = _decorator;
@ccclass('BoxFormation')
export class BoxFormation extends BaseFormation {
@property
unitWidth: number = 5;
@property
unitDepth: number = 5;
@property
hollow: boolean = false;
@property
nthOffset: number = 0;
EvaluatePoints(): Vec3[] {
const ret: Vec3[] = [];
const middleOffset = v3((this.unitWidth - 1) * 0.5, 0, (this.unitDepth - 1) * 0.5);
for (let x = 0; x < this.unitWidth; x++) {
for (let z = 0; z < this.unitDepth; z++) {
if (this.hollow && x != 0 && x != this.unitWidth - 1 && z != 0 && z != this.unitDepth - 1) continue;
let pos = v3(x + (z % 2 == 0 ? 0 : this.nthOffset), 0, z); pos = pos.subtract(middleOffset); pos = this.GetNoise(pos); pos = pos.multiplyScalar(this.Spread);
pos.add(this.offsetPos);
ret.push(pos);
}
}
return ret;
}
}
/** 放射编队组件脚本代码 */
import { _decorator, Component, Node, Vec3, v3 } from 'cc';
import { BaseFormation } from './BaseFormation';
const { ccclass, property } = _decorator;
@ccclass('RadialFormation')
export class RadialFormation extends BaseFormation {
@property
amount: number = 10;
@property
radius: number = 1;
@property
radiusGrowthMultiplier: number = 0;
@property
rotations: number = 1;
@property
rings: number = 1;
@property
ringOffset: number = 1;
@property
nthOffset: number = 1;
EvaluatePoints(): Vec3[] {
const ret: Vec3[] = [];
let amountPerRing = this.amount / this.rings;
let ringOffset = 0;
for (var i = 0; i < this.rings; i++) {
for (var j = 0; j < amountPerRing; j++) {
let angle = j * Math.PI * (2 * this.rotations) / amountPerRing + (i % 2 != 0 ? this.nthOffset : 0); let radius = this.radius + ringOffset + j * this.radiusGrowthMultiplier;
let x = Math.cos(angle) * radius;
let z = Math.sin(angle) * radius; let pos = new Vec3(x, 0, z); pos = this.GetNoise(pos); pos = pos.multiplyScalar(this.Spread); pos.add(this.offsetPos);
ret.push(pos);
}
ringOffset += this.ringOffset;
}
return ret;
}
}
以上便是CocosCreator3版本的核心计算代码了,可以自行贴在编队节点上,人物控制应该是由特定的渲染代码完成。
编队展示处理代码
/**
* 编队渲染展示的代码,挂在到你想展示的节点容器上,配合对应的Formation组件
* 请自行构建Actor角色组件用于处理人物逻辑,实现removeSelf和moveTo
* 在合适的时机处理编队的刷新,比如编队参数变化、队伍移动的时候
*/
import { _decorator, Component, Node, Prefab, instantiate, director } from 'cc';
import { Actor } from '../actors/Actor';
import { BaseFormation } from '../formations/BaseFormation';
const { ccclass, property } = _decorator; @ccclass('FormationShow')
export class FormationShow extends Component {
@property(Prefab)
actor: Prefab = null;
start() {
this.FormationUpdate();
}
FormationUpdate(prop?: string, value?: number) {
const formation = this.getComponent(BaseFormation);
if (formation) {
if (prop) {
const old = formation[prop];
formation[prop] = value;
if (old == formation[prop]) {
return;
}
}
const points = formation.EvaluatePoints();
for (let i = this.node.children.length - 1; i >= points.length; i--) {
this.node.children[i].getComponent(Actor).removeSelf();
}
const len = this.node.children.length;
for (let i = 0; i < points.length; i++) {
if (i < points.length && i >= len) {
let actor = null;
if (len > 0) {
actor = this.node.children[len - 1];
} else {
actor = this.actor;
}
const a = instantiate(actor);
this.node.addChild(a);
}
this.node.children[i].getComponent(Actor).moveTo(points[i]);
}
}
}
}
结语
视频中的源码工程已经发布到Cocos的官方商店,有需要的自取
https://store.cocos.com/app/detail/3210
B站视频:【Creator3】好玩的编队代码 魔性排列停不下来 附源码及出处的更多相关文章
- Android 音视频深入 十七 FFmpeg 获取RTMP流保存为flv (附源码下载)
项目地址https://github.com/979451341/RtmpSave 这个项目主要代码我是从雷神那弄过来的,不愧是雷神,我就配个环境搞个界面就可以用代码了. 这一次说的是将RTMP流媒体 ...
- 13行代码实现:Python实时视频采集(附源码)
一.前言 本文是<人脸识别完整项目实战>系列博文第3部分:程序设计篇(Python版),第1节<Python实时视频采集程序设计>,本章内容系统介绍:基于Python+open ...
- C#代码反编译 得到项目可运行源码
C#代码反编译 得到项目可运行源码 摘自:http://www.cnblogs.com/know/archive/2011/03/15/1985026.html 谈到"C#代码反编译&quo ...
- 基于Python接口自动化测试框架+数据与代码分离(进阶篇)附源码
引言 在上一篇<基于Python接口自动化测试框架(初级篇)附源码>讲过了接口自动化测试框架的搭建,最核心的模块功能就是测试数据库初始化,再来看看之前的框架结构: 可以看出testcase ...
- SpringBoot2.x整合Prometheus+Grafana【附源码+视频】
图文并茂,新手入门教程,建议收藏 SpringBoot2.x整合Prometheus+Grafana[附源码+视频] 附源码+视频 目录 工程简介 简介 Prometheus grafana Spri ...
- Android 高仿 频道管理----网易、今日头条、腾讯视频 (可以拖动的GridView)附源码DEMO
距离上次发布(android高仿系列)今日头条 --新闻阅读器 (二) 相关的内容已经半个月了,最近利用空闲时间,把今日头条客户端完善了下.完善的功能一个一个全部实现后,就放整个源码.开发的进度就是按 ...
- 仿爱奇艺视频,腾讯视频,搜狐视频首页推荐位轮播图(二)之SuperIndicator源码分析
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼:http://blog.csdn.net/hejjunlin/article/details/52510431 背景:仿爱奇艺视频,腾讯视频 ...
- Android 音视频深入 二十 FFmpeg视频压缩(附源码下载)
项目源码https://github.com/979451341/FFmpegCompress 这个视频压缩是通过类似在mac终端上输入FFmpeg命令来完成,意思是我们需要在Android上达到能够 ...
- Android 音视频深入 十八 FFmpeg播放视频,有声音(附源码下载)
项目地址https://github.com/979451341/AudioVideoStudyCodeTwo/tree/master/FFmpegv%E6%92%AD%E6%94%BE%E8%A7% ...
随机推荐
- 关于通用Mapper new Example使用记录
关于通用MapperExample使用记录 环境准备 需要集成 mybatis 的 generator 插件,方便自动生成 实体类和 mapper 类,还可以生成xml,不过一般我们都不用 xml b ...
- vscode 1.32.x按下鼠标左键无法拖曳选择,而旧一点的版本1.30.2可以
最近升级vscode后,无法通过鼠标左键选择文本,恢复到旧版本1.30.2就可以了. 另外:1.32.x和1.31.1都不正常 进一步测试发现:在中文输入法下(无论中英输入模式),都有问题:切换到纯英 ...
- golang GC 垃圾回收机制
垃圾回收(Garbage Collection,简称GC)是编程语言中提供的自动的内存管理机制,自动释放不需要的对象,让出存储器资源,无需程序员手动执行. Golang中的垃圾回收主要应用三色标记法, ...
- JS_DOM操作之常用事件
1 - onload 事件:加载完成后立即执行 <!DOCTYPE html> <html lang="en"> <head> <meta ...
- 第九章 Net 5.0 快速开发框架 YC.Boilerplate --定时服务 Quartz.net
在线文档:http://doc.yc-l.com/#/README 在线演示地址:http://yc.yc-l.com/#/login 源码github:https://github.com/linb ...
- WEB漏洞——XXE
XXE漏洞又称XML外部实体注入(XML External Entity) 介绍XXE漏洞前先说一下什么是XML XML语言 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据定义数据类 ...
- js判断是在移动端还是在pc端
function chatQQ3(){ if(/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) { //移动端打开 ...
- Filter案例之敏感词过滤和代理模式
一.需求分析 二 .代理模式 1.概念 2.代码实现 代理对象可以强转为真实对象,即对应的接口类: 3.通过代理增强方法 其中,方法对象invoke真实对象,反射原理: 三.过滤敏感词汇案例代码实现 ...
- Linux从头学12:读完这篇【特权级】文章,你就比别人更“精通”操作系统!
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...
- Haproxy搭建web集群
目录: 一.常见的web集群调度器 二.Haproxy应用分析 三.Haproxy调度算法原理 四.Haproxy特性 五.Haproxy搭建 Web 群集 一.常见的web集群调度器 目前常见的we ...