对于 A* 其实就是需要将整体游戏地图网格化(Grids), 很多人都戏称这种方式为 “刷格子”
网格化之后地图寻路操作其实就像是五子棋连线即可, 其中棋盘上不可获取就是障碍物列表和网格最大值.
一般寻路系统只需要做二维处理即可
对于网格化默认都是以地图左下最初地方设置为 (0,0) 起始点, 后续需要确定整个地图的最大定点值, 这部分代码如下:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314 ...
参考文档: https://docs.godotengine.org/zh-cn/latest/getting_started/first_2d_game/03.coding_the_player.html
对于新手入门来说, 没必要一上来就接触 3D 游戏开发, 如果游戏注重玩法直接采用 2D/2.5D 美术来构建即可.
一般 itch.io 都有不少很不错的游戏资源包, 自带人物角色动作和场景地图, 支付购买资源版权即可
如果想快速搭建自己的游戏底层架构, 采用 2D-Animation + TileMap 是很好的方向.
上面的 Godot 官方参考文档里面只说了基础的人物动画创建, 虽然直接用确实没问题, 但还是要处理上级封装成统一模块
这里采用 Godot 的脚本系统封装 Area2DCharacter.gd, 用于做统一角色抽象类
12345678##################################### 扩展 Area2D 人物类###################################extends Area2Dclass_ ...
相比于帧同步的复杂度和资源耗费, 状态同步的开发要求相对容易(主要实现起来很简单)
这里数据结构是采用 Protobuf 定义, 客户端和服务端数据交互的时候比较统一
假设目前想要设计个 2DRPG 游戏, 那么通用简单的玩家状态 proto 如下:
123456789101112131415161718192021222324252627282930313233343536syntax = "proto3";option java_package = "me.meteorcat.game.protobuf";option java_multiple_files = true;// 二维坐标系message Vector2{ float x = 1; float y = 2;}// 简略版本的玩家状态数据结构message PlayerState{ // 基础信息 int64 id = 1; // 玩家 ID Vector2 position = 2;// 玩家位置 int64 uptime = 3; ...
Pekko 是支持将数据对象作为 ProtobufV2/V3 序列化转发, 而且官方集群数据传输方案实现了这部分功能.
序列化说明: https://pekko.apache.org/docs/pekko/current/serialization.html#serialization-of-pekkos-messages
目前官方有两套 Protobuf 序列化方案支持, 比较推荐采用 pekko-protobuf-v3:
(建议采用)pekko-protobuf-v3_{scala.version}: https://mvnrepository.com/artifact/org.apache.pekko/pekko-protobuf-v3
(不建议采用)pekko-protobuf_{scala.version}: https://mvnrepository.com/artifact/org.apache.pekko/pekko-protobuf
如果没有客户端需求, 一般只有集群转发会引用, 而集群处理默认已经自动引入 protobuf 支持.
而如果客户端需要依 ...
早期 Java 的并没有统一的异步运行时, 所以很多都需要去自行实现处理, 而 Pekko 则是自行设计通用的异步运行时.
Pekko 异步运行时是由 Actor 模型 + 调度器 + 流处理 + 未来式(Future) 构成的完整异步运行体系, 包含有以下组件:
Scheduler/Dispatcher: 任务定时器/调度器, 底层执行核心, 负责线程分配和任务调度, 隔离不同类型的任务
Future/CompletionStage: 异步任务结果包装, 处理异步任务的返回值,避免同步阻塞等待
Stream: 支持运行时的数据流处理, 解决批量数据的异步生产 - 消费问题, 内置背压避免流量失控
Actor: 最上层的任务载体, 用 “消息队列 + 单线程执行” 的模式将并发问题收敛到"消息顺序"而非"锁"
这些组件都是能够独立使用
在 Java8 之后可以依靠 Runnable/Callable/ThreadPool 实现简单的异步运行时, 但是对比 Pekko 纯正 Actor 设计差距很大:
特性
Pekko ...
Pekko 消息交互
其他文章已经揭示过 Pekko 目前主流支持的网络流消息交互:
TCP
UDP
WebSocket
基本上需要的网络流处理, Pekko 都封装完成了, 所以也就不需要依赖第三方来处理这些.
TCP/UDP 文档我看目前没有跟进到最新强类型版本处理, 这里主要还是以 TCP 流处理为主
TCP/UDP 之类依赖只需要基础的 actor 即可, 无需其他多余依赖, 目前官网 TCP 样例如下:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081import java.net.InetSocketAddress;import org.apache.pekko.actor.ActorRef;import org.apache.pekko.actor.ActorSystem;import org.ap ...
Pekko 作为 Actor 底层框架, 其实内部自带了 Http/Https/WebSocket 扩展, 涵盖日常所需要的短连接和长连接场景.
这部分涉及到以下相关内容:
pekko-http
pekko-websocket
这里为什么推荐采用 WebSocket 做长连接服务?
主流支持非常广泛(现代代浏览器、iOS、Android、物联网设备)
抛弃以往的粘包/拆包、心跳检测、消息校验问题, 不用将心力放在数据流的验证上
CDN 厂家现在逐步有 WebSocket 的支持, 可以利用 CDN 的边缘节点就近接入客户端
当然也可以外置 WebSocket 库挂载服务, 只是采用 Actor 集成更加高效方便, 无缝贴合 Actor 处理
另外需要说明的 WebSocket 支持 text(文本流) 和 binary(二进制流) 传输模式, 这里强烈建议采用二进制流传输.
如果采用 text 文本流, 大部分数据库解析的时候都会做默认的 UTF8 编码转化成 String, 之后内部又会转换成 byte[] 交换数据.
高并发的情况下很容易直接生成大量 ...
Pekko Stream 是一套异步、非阻塞、支持背压(Backpressure)的数据流处理框架,
主要用来解决大数据/高并发场景下的资源管控问题, 避免数据加载时候的 OOM 问题.
pekko 需要依赖以下的组件(采用 Maven 来包管理):
12345678910111213141516171819202122232425262728293031323334353637383940414243444546<!-- 所需依赖 --><dependencies> <!-- Pekko Stream 核心依赖 --> <dependency> <groupId>org.apache.pekko</groupId> <artifactId>pekko-stream_${scala.binary.version}</artifactId> <version>${pekko.version} ...
作为长期使用的维护的远程 API 接口, 大部分都是用类似于 /v1/user/login 之类做版本控制管理;
但是实际上其实内部问题也很多, 比如长期运行的路由表堆积问题, 并且基于 Path 匹配导致没办法做到无感知升级.
之后接口设计我更加推崇的是 Header 版本字段控制, 请求时附加以下 Header 字段(以下字段都可以自定义, 最好做成动态配置):
X-Version: 请求的版本字段
X-Sign: 请求的字段签名
X-Authorization: 请求的授权 Token
X-App-Id: 可选配置, 如果采用多应用管理才需要, 一般单应用接口不需要用到
然后后续都是采用统一的请求接口 /user/login 之类, 而内部就是直接通过 Header 相关参数来调配转发到对应版本.
这里还是用 Quarkus 来做接口请求
按照常规的接口配置之后就编写控制器类来做接收请求:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464 ...
之前买 Orange 5Pro 来设计 NAS 的时候顺带买个 Orange 3B, 因为嫌弃性能不够一直没拆封过;
最近跨年整理的时候才发现这块开发板, 想着闲着也是闲着就看看能干点什么.
最后想着搭配手里的8寸便携式显示器直接改造成简单的小型 Steam Machine, 通过连接 XBOX 蓝牙手柄来游玩游戏.
OrangePI 3B 后面简称为 opi3
这套方案的具体配置如下:
RockChip RK3566 瑞芯微四核 64 位 ARM 处理器, 主频最高 1.8GHz
8GB LPDDR4/4X 自带内存
120GB SATA 廉价朗科固态硬盘(这是我额外购买扩展固态硬盘)
支持 Wi-Fi5/蓝牙/HDMI 方案
Armbian 系统(Debian的 iot 方案)
支持 OpenGL ES 1.1/2.0/3.2 | OpenCL 2.0 | Vulkan 1.1(Vulkan是重中之重)
需要注意: 这块开发板默认只启用的 NVME 协议, 直接接入 SATA 协议的固态是没办法识别的.
如果固态是 SATA 协议就需要修改 A ...







