惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
云风的 BLOG
云风的 BLOG
aimingoo的专栏
aimingoo的专栏
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss
F
Full Disclosure
A
About on SuperTechFans
C
Check Point Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
Know Your Adversary
Know Your Adversary
K
Kaspersky official blog
L
LINUX DO - 热门话题
Recorded Future
Recorded Future
C
Cisco Blogs
M
MIT News - Artificial intelligence
T
Tenable Blog
G
GRAHAM CLULEY
月光博客
月光博客
Recent Announcements
Recent Announcements
V
Visual Studio Blog
IT之家
IT之家
T
The Exploit Database - CXSecurity.com
The GitHub Blog
The GitHub Blog
T
Threat Research - Cisco Blogs
D
DataBreaches.Net
P
Privacy International News Feed
P
Proofpoint News Feed
I
Intezer
博客园 - 叶小钗
C
CXSECURITY Database RSS Feed - CXSecurity.com
The Hacker News
The Hacker News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - Franky
SecWiki News
SecWiki News
宝玉的分享
宝玉的分享
P
Palo Alto Networks Blog
Last Week in AI
Last Week in AI
小众软件
小众软件
Hacker News - Newest:
Hacker News - Newest: "LLM"
O
OpenAI News
N
News and Events Feed by Topic
Microsoft Security Blog
Microsoft Security Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
N
News and Events Feed by Topic
The Cloudflare Blog
Spread Privacy
Spread Privacy
酷 壳 – CoolShell
酷 壳 – CoolShell
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
B
Blog RSS Feed

夜行人

回家路上 第一期的直播演示项目 震动检测器 正能量 在线参观CodeLab Neverland 发布 CodeLab Adapter 3.3.1 DynamicTable 之 纸糊方向盘 CodeLab DynamicTable: 一个可实施的技术方案 CodeLab Insight 发布 Alpha 版 情人节 Home Assistant 周报 && IoT 周报 (02) Joplin: 关注隐私的 Evernote 开源替代软件 浏览器的未来与 Web 传感器 Home Assistant 周报 && IoT 周报 (01) 百宝箱(01) 论自由 介绍 WebThings Home Assistant 周报 && iot 周报 (00) 百宝箱(00) 毛姆读书心得 传世之作 周末徒步 CodeLab Adapter ❤️ Jupyter/Python 航班 躲雨 夏令营途中 [译]思想--作为一种技术 The future of coding 美国之行 三门问题的程序模拟 从Python转向Pharo https://blog.just4fun.site/post/iot/iot-open-source-projects/ Python异步编程笔记 https://blog.just4fun.site/post/iot/iot-open-source-hardware-community/ 万物积木化开发者社区 CodeLab ❤️ Blender Scratch3技术分析之云变量 API(第7篇) [译]对管道(Pipes)的偏爱 [译]提出正确的问题比得到正确答案更重要 蓝牙设备与Scratch3.0 创建你的第一个Scratch3.0 Extension Scratch3技术分析之项目内部数据(第6篇) Scratch3技术分析之社区 API(第5篇) Scratch3技术分析之User API(第4篇) Scratch3技术分析之项目主页API(第3篇) Scratch3技术分析之静态资源API(第2篇) Scratch3.0、micro:bit与Windows7 https://blog.just4fun.site/post/iot/zerynth-vs-micropython/ 核聚变、方所与半宅空间 可视化编程为何是个糟糕的主意 codelab.club周末聚会 关于codelab.club '下一件大事'是一个房间 Hungry Robot - Eat everything 编程作为一种思考方式 今日简史 史蒂夫·乔布斯传 罗素自选文集 https://blog.just4fun.site/post/edx/tianjin-scratch-ai/ https://blog.just4fun.site/post/edx/richie-cms-openedx/ 徒步武功山 WebUSB与micro:bit 积木化编程与3D场景 夜宿武功山顶 scratch3-adapter接入优必选Alpha系列机器人 https://blog.just4fun.site/post/edx/video-migration-note/ scratch3-adapter重构笔记 https://blog.just4fun.site/post/edx/edx-community-members/ 两种硬件编程风格的比较 使用micro:bit自制PPT翻页笔 柏拉图对话集 scratch3.0 + micro:bit 七月电影放映计划 非营利组织的管理 Screenly--用树莓派让任何屏幕变为可编程的数字标牌 以最佳实践开始你的Django项目 micro:bit与事件驱动 为Scratch3.0设计的插件系统(上篇) OCR应用一例 近两年读过的一些好书 blockly开发之使用python驱动浏览器中的turtle(2) 牛顿新传 文学理论入门 逻辑的引擎 人生的意义 blockly开发之生成并运行js代码(1) blockly开发之hello world(0) micro:bit使用笔记 神器之Termux https://blog.just4fun.site/post/iot/micropython-notes/ Cozmo what is this Scratch的前世今生 下段旅程 我行在远方 爆裂 途中杂记 https://blog.just4fun.site/post/edx/open-edx-startup/ cozmo系列之入门 - 有性格且可编程的机器人 PaperWeekly开发笔记 创业二三事
MicroBlocks ❤️ Roblox: 操场大小的像素屏
种瓜 · 2023-06-04 · via 夜行人

前言

一个强盗以手枪对着我的胸口,要我倾囊给他,因而我自己从衣袋里掏出了钱包并亲手递给他,在这情况下,说我曾经给予承诺,这既不能改变案情,也不能意味着宽恕强力而转移权利。 – 约翰·洛克《政府论》

这个项目像个枪击游戏, 引用约翰·洛克的这句话来开篇。

我们在 MicroBlocks 分享会 0603 展示了 MicroBlocksRoblox 之间的互操作。 本文是这个演示的配套文档,帮助大家复现演示项目。

具体而言, 我们在 Roblox 中构建一个操场大小的像素屏(16x16), 当角色踩到这个巨型屏幕上的某个像素时, 像素随机变色, 同时,现实世界的对应像素也发生变化。

可以将其视为数字孪生的一个案例。

本文也展示了 AI(LLM) 作为编程助手,不仅可以让我们在不熟悉的领域快速起步, 还提升了整个学习体验。

我之前对游戏开发和 Roblox 都缺乏经验。借助 AI, 新手如我可以很快就构建出了核心功能,通过几句提示词,花上几分钟就构建了可运行的核心功能!

与 AI 一起编程,不只消除了起步的困难(对语法和 API 不熟悉), 还提供了实践项目式学习的途径。我要求 AI 帮助实施我的项目, 然后我阅读并试运行 AI 生成的项目代码,如有出错,就跟它反复沟通。在几分钟里我就进入到项目的核心工作中。

这个学习过程要比我之前的学习有效许多,之前一般先阅读并弄懂文档,然后开始编程。它之所以更有效,可能是因为我无需预先学习大量细节知识。 AI 帮我搭建项目骨架,帮我处理细节问题,我则在更高层面驾驶它。

之后,在反复沟通,解决问题过程中,我被迫关注具体细节,可能还需要通过查阅文档,才能进一步精细化地向 AI 表达我的想法。但此时,文档知识对我而言已经变得有趣(相比于之前学而不用的集邮式学习),因为它是构建我的想法大厦的砖块,知识一旦与学习者发生联系,就不再乏味了。

思路

Roblox 提供了出色的 3D 创作工具, 让我们可以天马行空地构建想象中的世界。在本文例子中,我们在 Roblox 里制造了一个操场大小的像素屏(16x16)。

我们为这个像素屏添加了行为, 使之能够响应用户的操作: 每当用户控制的角色碰到到像素时, 像素立刻随机变色, 并且现实的像素屏(由 MicroBlocks 驱动)也响应变色。

这里涉及到 Roblox 与现实设备的通信,我们使用了 HTTP 协议进行通信。Roblox 提供了 HTTP Client 与外部系统通信(需要的注意的是,它叫 HTTP Service 而不是 HTTP Server, Roblox 只能作为 HTTP client,而无法作为 HTTP Server)。

开始实验

由上边思路可知,演示项目涉及以下两个部分:

  • 在 MicroBlocks 中编程
  • 在 Roblox 中编程

NeoPanel 库

MicroBlocks 最近增加了一个新的库: NeoPanel。 由 Citilab 的 José 贡献给社区。

我在上周六(2023-05-27)的 MicroBlocks 分享会里分享了这个库。

我们使用这个库来驱动现实世界的像素屏。

编程板子使用了 ESP32, 我们需要在板子上运行 HTTP Server(支持 WiFi)。

MicroBlocks 程序

我使用 MicroBlocks 内置的 Browser Control Panel 作为脚手架。

这是修改后的程序 Roblox NeoPanel demo

这个程序比较简单, 它运行了一个 HTTP server。 要运行它,你需要做以下两件事:

  1. 设置像素屏信息: 像素排布、引脚
  2. 配置 wifi 信息

运行之后,你将在 MicroBlocks 里看到板子的 IP 地址。然后在浏览器打开: http://板子的IP地址, 诸如我的板子地址是: http://192.168.1.9

你可以通过这个界面设置屏幕上的像素,每当点击上图的提交, 你讲会把位置(7,7)的像素设置为红色, 实际会触发这个 HTTP 请求: http://192.168.1.9/?R=128&G=0&B=0&X=7&Y=7

由于设置像素只是打开一个 url 链接,所以只要我们在 Roblox 发送这个 HTTP 请求,同样能够设置像素颜色。

在 Roblox 中编程

我先将完整的项目分享在这里: 点击下载。 你可以通过以下方式直接将其加载到 Roblox 中:

运行之前,记的将像素屏的 url 设置为你的真实设备地址。

项目已经包含了以下所有的工作,所以将以下部分视为说明文档即可。

介绍 Roblox

Roblox 提供了世界上最易用的 3D 创作工具, 让任何人都能随时随地创造任何东西。

如果你曾经试图在创造 3D 世界,但备受挫败,Roblox 可能是你的救星。

近期我们(DynaLab)在 Roblox 里做一些与 AI (LLM)相关的探索, 被这个环境的灵活度与易用性所折服, 它在某些方面达到了个人计算期待的软件品质, 具有相当不错的 Liveness 特质。

安装配置

为了在 Roblox 中编程程序, 你首先需要 安装配置 Roblox Studio,可以将 Roblox Studio 看作在 3D 世界编程的 IDE。

提醒: 在国内运行你需要科学上网, Roblox 有一些额外要求,可能需要使用 Clash Pro, 并启用增强模式。

在 Roblox 脚本中发起 HTTP 请求

为了让我们的 Roblox 项目与 MicroBlocks 项目交互,我们决定采用 HTTP 通信,具体而言,我们想让 Roblox 脚本发起 HTTP 请求,把信息传到硬件设备里。

首先需要对 Roblox 项目进行配置, 使之可以发起 HTTP 请求(可参考 HttpService)。 具体而言,打开: FIlE -> Game Settings -> Security , 开启 Allow HTTP Requests:

完成设置之后,你就可以在 Script 里发起 HTTP 请求, 诸如:

1
2
3
local HttpService = game:GetService("HttpService")

HttpService:GetAsync("http://192.168.1.9/?R=128&G=0&B=0&X=7&Y=7")  -- 前边的例子

以上代码完成了最核心的工作: 让 Roblox 与 硬件设备通信。

剩下的工作,都属于 在Rolbox构建 3D 体验 范畴, 如果你之前有 Roblox 经验,不必看剩下的文章,应该都能完成我们的演示项目。

但我之前没什么经验,所以我打算让 ChatGPT 帮我写 Roblox 脚本。

我打算让 ChatGPT 专注于构建"操场大小的像素屏"。网络通信很简单(只有以上两行),我自己添加进入即可。

提示词

我给 ChatGPT 的提示词:

1
2
3
4
5
在 Roblox 创建脚本做以下事情:

1. 创建一个方形面板,名叫 NeoPanelBasePlate。方形面板的尺寸正好容纳其上的所有长方体
2. 方形面板上边均匀排布 16 行 16 列的 光滑黑色长方体, 这些长方体的尺寸如下, 长: 4, 宽: 4, 高:1。 这些长方体之间间隔为 4
3. 这些长方体有如下行为: 当角色碰到某个长方体时,它就随机变色。对每个长方体做防抖处理。

我将以上提示词输入到 GPT-4, 立刻得到了相当不错的脚手架代码。第一次运行就基本完成了 90% 的功能! 一些细微瑕疵在我跟它反馈之后, GPT-4 很快就修复了。

以上提示词是我凭记忆重写的,可能和真实的提示词有出入,最初的对话记录找不到了,因为 OpenAI 账号被封 :-( OpenAI 最近 GPU 不足, Twitter 上不少 Plus 用户抱怨被退钱封号。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
-- 计算需要的板子大小和位置
local blockSize = Vector3.new(4, 1, 4)
local blockGap = 4
local gridLength = 16
local basePlateSize = Vector3.new((blockSize.X + blockGap) * gridLength, 1, (blockSize.Z + blockGap) * gridLength)

-- 创建方形板子
local basePlate = Instance.new("Part")
basePlate.Name = "NeoPanelBasePlate"
basePlate.Size = basePlateSize
basePlate.Position = Vector3.new(basePlateSize.X / 2, 0, basePlateSize.Z / 2)
basePlate.Anchored = true
basePlate.Parent = game.Workspace

-- 创建16行16列的光滑黑色长方体
for i = 1, 16 do
	for j = 1, 16 do
		local block = Instance.new("Part")
		block.Size = blockSize
		block.Position = Vector3.new(i * (blockSize.X + blockGap) - blockSize.X / 2, blockSize.Y / 2, j * (blockSize.Z + blockGap) - blockSize.Z / 2)
		block.BrickColor = BrickColor.new("Black")
		block.Material = Enum.Material.SmoothPlastic
		block.Anchored = true
		block.Parent = basePlate

		-- 创建防抖动机制
		local debounce = false

		-- 添加触摸事件
		local function changeColor(otherPart)
			local humanoid = otherPart.Parent:FindFirstChildWhichIsA("Humanoid")
			-- print(humanoid.PlatformStand, humanoid:GetState())
			if not debounce and humanoid and humanoid.PlatformStand == false and humanoid:GetState() == Enum.HumanoidStateType.Running then
				debounce = true
				-- 更改颜色
				block.BrickColor = BrickColor.Random()
				wait(1) -- 防抖动
				debounce = false
			end
		end

		block.Touched:Connect(changeColor)
	end
end

ServerScriptService 创建 Script, 放入以上脚本。

我们就得到一个相当令人满意的 “操场大小的像素屏” 了, 每个像素都会响应角色的行为。

命名是计算机世界最难的两件事之一(另一件是缓存), 为何不叫 ChatGPT 来做呢? 我让它给这个脚本起一个合适的名字, 它的答复是: ColorChangingBlocksOnJump

加上网络请求

加上网络请求之后, 代码也很简单:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
local HttpService = game:GetService("HttpService")

-- 计算需要的板子大小和位置
local blockSize = Vector3.new(4, 1, 4)
local blockGap = 4
local gridLength = 16
local basePlateSize = Vector3.new((blockSize.X + blockGap) * gridLength, 1, (blockSize.Z + blockGap) * gridLength)

-- 创建方形板子
local basePlate = Instance.new("Part")
basePlate.Name = "NeoPanelBasePlate"
basePlate.Size = basePlateSize
basePlate.Position = Vector3.new(basePlateSize.X / 2, 0, basePlateSize.Z / 2)
basePlate.Anchored = true
-- basePlate.BrickColor = BrickColor.new("Black")
basePlate.Parent = game.Workspace
local NeoPanel_url = "http://192.168.1.9"

-- 创建16行16列的光滑黑色长方体
for i = 1, 16 do
	for j = 1, 16 do
		local block = Instance.new("Part")
		block.Size = blockSize
		block.Position = Vector3.new(i * (blockSize.X + blockGap) - blockSize.X / 2, blockSize.Y / 2, j * (blockSize.Z + blockGap) - blockSize.Z / 2)
		block.BrickColor = BrickColor.new("Black")
		block.Material = Enum.Material.SmoothPlastic
		block.Anchored = true
		block.Parent = basePlate

		-- 创建防抖动机制
		local debounce = false

		-- 添加触摸事件
		local function changeColor(otherPart)
			local humanoid = otherPart.Parent:FindFirstChildWhichIsA("Humanoid")
			-- print(humanoid.PlatformStand, humanoid:GetState())
			if not debounce and humanoid and humanoid.PlatformStand == false and humanoid:GetState() == Enum.HumanoidStateType.Running then
				debounce = true
				-- 更改颜色
				block.BrickColor = BrickColor.Random()

				local r,g,b = math.floor(block.BrickColor.r*255), math.floor(block.BrickColor.g*255), math.floor(block.BrickColor.b*255)
				local url = `{NeoPanel_url}/?R={r}&G={g}&B={b}&X={i}&Y={j}`
				print('url:', url)
				local response = HttpService:GetAsync(url)

				wait(1) -- 防抖动
				debounce = false
			end
		end

		block.Touched:Connect(changeColor)
	end
end

发布到 Roblox 社区?

如果你想将项目发布到 Roblox 社区,被更多人使用,可能需要处理一下网络问题。

Roblox 开发环境(Roblox Studio) 运行在本地,所以可以与局域网的设备通信。 如果你讲项目发布到 Roblox 社区, Roblox 中的 HTTP 请求将无法发到你的本地设备上,

如果你确实需要这样做,需要把硬件设备的 IP 地址也映射到公网, 可以通过 ngrok 来做到这点, 命令类似: ~/ngrok http 192.168.1.9:80 (192.168.1.9 替换为你的设备 IP)

进阶

以上代码没有包含枪击清屏的功能。这是为了降低复杂性, 以上代码最小化了在 IDE 里进行的操作。创建物体都在脚本里实现了, 无需在 IDE 里摆弄 3D 模型。

但不少用户觉得枪击效果非常酷。 这部分分享如何实现。

但我们的演示里,包含了一个靶子: 当我们用枪击中这个靶子时, 虚拟世界和现实世界的像素屏都会清屏。

添加靶子

在项目中添加一个 Part, 它的名字是 Clear。我还给了它一个贴花(Decal)

添加枪支

Roblox 官方为社区制作了一些精致的武器系统

我使用的枪是 submachine gun ,通过搜索找到它,然后将其添加到游戏里。

修改枪支对象(SMG) WeaponsSystem 模块里的 doDamage 函数:

1
2
3
4
5
6
7
8
9
function WeaponsSystem.doDamage(target, amount, damageType, dealer, hitInfo, damageData)
	if target.name == 'Clear' then -- Clear 是靶子对象,它的名字是 Clear
		for i, v in pairs(game.Workspace.NeoPanelBasePlate:GetChildren()) do
			v.BrickColor = BrickColor.new("Black")
		end
		local url = "http://192.168.1.9/clear"  -- 在 MicroBlocks 里编写了 clear 服务
		HttpService:GetAsync(url)
	end
    ...

完成。

参考