迁移后更改
This commit is contained in:
30
.history/README_20251112115747.md
Normal file
30
.history/README_20251112115747.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
## 介绍
|
||||||
|
|
||||||
|
此仓库克隆自https://github.com/AAAB60/computer-craft-programs/tree/main
|
||||||
|
|
||||||
|
对其进行修改,以共liulikeji程序使用
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 以下为原本介绍
|
||||||
|
一个基于像素打印的utf8打印程序
|
||||||
|
|
||||||
|
> $\color{red} \bf 注意:$
|
||||||
|
> CC 编译器会把utf8字符读作 '?',
|
||||||
|
> `print("你好世界")` 与 `print("????")` 的效果相同, 可以`"rb"`模式读取文件以设置输入
|
||||||
|
|
||||||
|
|
||||||
|
## 如何制作Font
|
||||||
|
- 字体文件返回一个table,键值为utf8编码,值为和对应字体的bitmap。
|
||||||
|
- bitmap为一个包含等长string的table,string中的char属于computer craft定义的2*3像素点阵(如需使用右下角像素,将char的码值减128表示反转backgroundColor 和 textColor)
|
||||||
|
- 单个字体文件中可以有不同尺寸的bitmap,且**需要**有'H'(ascII:72)的bitmap表示该文件中最大bitmap高度
|
||||||
|
- 会以FontFamily出现的最大bitmap高度为基准,最终输出下对齐的文本
|
||||||
|
- FontFamily中**需要**'-'(ascII:45)的bitmap以供自动换行时可能的切断单词使用
|
||||||
|
|
||||||
|
## 技术细节
|
||||||
|
|
||||||
|
- `require`一个fusion-pixel-12px字体,大约消耗**10.5MB**内存
|
||||||
|
- `require`一个fusion-pixel-8px字体,大约消耗**6MB**内存
|
||||||
|
- 8px字符实际占用3格高的字符数, 12px字符实际占用4格高
|
||||||
|
- 字体来自 <a href="https://github.com/TakWolf/fusion-pixel-font/releases"> fusion-pixel-font </a>
|
||||||
36
README.md
36
README.md
@@ -1,6 +1,30 @@
|
|||||||
all codes have a demostration video on my **bilibili** cannel
|
## 介绍
|
||||||
## catalyst
|
|
||||||
- for mod pack: **create:above and beyond**
|
此仓库克隆自https://github.com/AAAB60/computer-craft-programs/tree/main
|
||||||
- automatically test and form the catalyst formula
|
|
||||||
- finnal output numbers represent the magnet in the corresponding slot of the crate
|
对其进行修改,以共liulikeji程序使用
|
||||||
- using four different containers to simplify`peripheral.find`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 以下为原本介绍
|
||||||
|
一个基于像素打印的utf8打印程序
|
||||||
|
|
||||||
|
> $\color{red} \bf 注意:$
|
||||||
|
> CC 编译器会把utf8字符读作 '?',
|
||||||
|
> `print("你好世界")` 与 `print("????")` 的效果相同, 可以`"rb"`模式读取文件以设置输入
|
||||||
|
|
||||||
|
|
||||||
|
## 如何制作Font
|
||||||
|
- 字体文件返回一个table,键值为utf8编码,值为和对应字体的bitmap。
|
||||||
|
- bitmap为一个包含等长string的table,string中的char属于computer craft定义的2*3像素点阵(如需使用右下角像素,将char的码值减128表示反转backgroundColor 和 textColor)
|
||||||
|
- 单个字体文件中可以有不同尺寸的bitmap,且**需要**有'H'(ascII:72)的bitmap表示该文件中最大bitmap高度
|
||||||
|
- 会以FontFamily出现的最大bitmap高度为基准,最终输出下对齐的文本
|
||||||
|
- FontFamily中**需要**'-'(ascII:45)的bitmap以供自动换行时可能的切断单词使用
|
||||||
|
|
||||||
|
## 技术细节
|
||||||
|
|
||||||
|
- `require`一个fusion-pixel-12px字体,大约消耗**10.5MB**内存
|
||||||
|
- `require`一个fusion-pixel-8px字体,大约消耗**6MB**内存
|
||||||
|
- 8px字符实际占用3格高的字符数, 12px字符实际占用4格高
|
||||||
|
- 字体来自 <a href="https://github.com/TakWolf/fusion-pixel-font/releases"> fusion-pixel-font </a>
|
||||||
|
|||||||
352
catalyst.lua
352
catalyst.lua
@@ -1,352 +0,0 @@
|
|||||||
mags = peripheral.find("create:adjustable_crate")
|
|
||||||
bottler = peripheral.find("minecraft:trapped_chest")
|
|
||||||
shovel = peripheral.find("minecraft:barrel")
|
|
||||||
loader = peripheral.find("minecraft:chest")
|
|
||||||
unloader = peripheral.find("minecraft:hopper")
|
|
||||||
analyser = peripheral.find("thermal:machine_centrifuge")
|
|
||||||
table1 = {["Andesite Reagent"]=1,["Diorite Reagent"]=2,["Granite Reagent"]=3,["Stone Reagent"]=4,["Basalt Reagent"]=5,["Gabbro Reagent"]=6,
|
|
||||||
["Crimson Reagent"]=1,["Orange Reagent"]=2,["Goldenrod Reagent"]=3,["Olive Reagent"]=4,["Azure Reagent"]=5,["Fuchsia Reagent"]=6,
|
|
||||||
["Blazing Reagent"]=1,["Slime Reagent"]=2,["Nether Reagent"]=3,["Obsidian Reagent"]=4,["Gunpowder Reagent"]=5,["Aquatic Reagent"]=6,
|
|
||||||
["Arcane Reagent"]=1,["Apatite Reagent"]=2,["Sulfuric Reagent"]=3,["Nitric Reagent"]=4,["Certus Quartz Reagent"]=5,["Nether Quartz Reagent"]=6,
|
|
||||||
["Zinc Reagent"]=1,["Copper Reagent"]=2,["Iron Reagent"]=3,["Nickel Reagent"]=4,["Lead Reagent"]=5,["Gold Reagent"]=6,
|
|
||||||
["Cinnabar Reagent"]=1,["Lapis Lazuli Reagent"]=2,["Sapphire Reagent"]=3,["Emerald Reagent"]=4,["Ruby Reagent"]=5,["Diamond Reagent"]=6}
|
|
||||||
function tableCopy(b)
|
|
||||||
local a = {}
|
|
||||||
for i ,j in pairs(b) do
|
|
||||||
if type(j) == "table" then
|
|
||||||
local jundge = nil
|
|
||||||
for m,n in pairs(j) do --{} ~= {}
|
|
||||||
jundge = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
if jundge then
|
|
||||||
a[i] = tableCopy(j)
|
|
||||||
else a[i] = {}
|
|
||||||
end
|
|
||||||
else
|
|
||||||
a[i] = j
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return a
|
|
||||||
end
|
|
||||||
function tableCompare(a,b)
|
|
||||||
local jundge = true
|
|
||||||
for i = 1,#a do
|
|
||||||
if type(a[i]) == "table" then
|
|
||||||
if #a[i] ~= 0 and not tableCompare(a[i],b[i]) then
|
|
||||||
jundge = false
|
|
||||||
break
|
|
||||||
elseif #a == 0 and #b[i] ~= 0 then
|
|
||||||
jundge = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
elseif a[i] ~= b[i] then
|
|
||||||
jundge = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return jundge
|
|
||||||
end
|
|
||||||
function tableCompare1(a,b)
|
|
||||||
local jundge = false
|
|
||||||
for i = 1,#a do
|
|
||||||
if tableCompare(a[i],b) then
|
|
||||||
jundge = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return jundge
|
|
||||||
end
|
|
||||||
local function push(container,receive,count,toslot,nameDisplay)--(dirt,dirt/"minecraft:chest_0")
|
|
||||||
local num,receiveName = 0,""
|
|
||||||
if type(receive) == "string" then
|
|
||||||
receiveName = receive
|
|
||||||
else
|
|
||||||
receiveName = peripheral.getName(receive)
|
|
||||||
end
|
|
||||||
--negelect modle
|
|
||||||
if nameDisplay == nil then
|
|
||||||
if count ~= nil then
|
|
||||||
for i,j in pairs(container.list()) do
|
|
||||||
num = num + j["count"]
|
|
||||||
container.pushItems(receiveName,i,count - num + j["count"],toslot)
|
|
||||||
if num >= count then break end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
for i,j in pairs(container.list()) do
|
|
||||||
container.pushItems(receiveName,i,nil,toslot)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if count ~= nil then
|
|
||||||
for i,j in pairs(container.list()) do
|
|
||||||
if container.getItemDetail(i).displayName == nameDisplay then
|
|
||||||
num = num + j["count"]
|
|
||||||
container.pushItems(receiveName,i,count - num + j["count"],toslot)
|
|
||||||
if num >= count then break end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
for i,j in pairs(container.list()) do
|
|
||||||
if container.getItemDetail(i).displayName == nameDisplay then
|
|
||||||
container.pushItems(receiveName,i,nil,toslot)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local function push1(container,outPutRules)--{{"Dirt","minecraft:chest_1",[num],toslot},{"Dirt","cobblesStone"}}
|
|
||||||
for i,j in pairs(container.list()) do
|
|
||||||
local displayName1,receiveName = container.getItemDetail(i).displayName,""
|
|
||||||
for m,n in pairs(outPutRules) do
|
|
||||||
if type(n[2]) == "string" then
|
|
||||||
receiveName = n[2]
|
|
||||||
else
|
|
||||||
receiveName = peripheral.getName(n[2])
|
|
||||||
end
|
|
||||||
if displayName1 == n[1] then
|
|
||||||
container.pushItems(receiveName,i,n[3],n[4])
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function hop(num)
|
|
||||||
local time = {0.1,0.5,0.9,1.3,1.7}
|
|
||||||
redstone.setOutput("top",true)--0.1,0.5,1,1.5,2
|
|
||||||
sleep(time[num])
|
|
||||||
redstone.setOutput("top",false)
|
|
||||||
end
|
|
||||||
function input(numbers,c)--({1,1,3,5},rc/gc)
|
|
||||||
for o = 1, 4 do
|
|
||||||
for i = 1, 4 - o do
|
|
||||||
shovel.pushItems(peripheral.getName(loader),i,1,i)
|
|
||||||
end
|
|
||||||
mags.pushItems(peripheral.getName(loader),numbers[5-o],1,5-o)
|
|
||||||
hop(4 - o)
|
|
||||||
sleep(0.4)
|
|
||||||
end
|
|
||||||
if c == "rc" then
|
|
||||||
mags.pushItems(peripheral.getName(loader),7,1,5)
|
|
||||||
elseif c == "gc" then
|
|
||||||
mags.pushItems(peripheral.getName(loader),8,1,5)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function stop()
|
|
||||||
sleep(10)
|
|
||||||
for i = 1 ,6 do
|
|
||||||
if mags.list()[i]["count"] <= 6 then
|
|
||||||
stop()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function step(simulateAnswer1,numbers1,c) --return mutiple results
|
|
||||||
local b,numbers,simulateAnswer = {0,0,0}
|
|
||||||
numbers = tableCopy(numbers1)
|
|
||||||
simulateAnswer = tableCopy(simulateAnswer1)
|
|
||||||
local jundge = nil
|
|
||||||
for i = 1, 4 do
|
|
||||||
if simulateAnswer[i] == numbers[i] then
|
|
||||||
b[3] = b[3] + 1
|
|
||||||
simulateAnswer[i] = nil
|
|
||||||
numbers[i] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for i = 1 ,4 do
|
|
||||||
if simulateAnswer[i] then
|
|
||||||
for j = 1 ,4 do
|
|
||||||
if simulateAnswer[i] == numbers[j] then
|
|
||||||
b[2] = b[2] + 1
|
|
||||||
simulateAnswer[i] = 7
|
|
||||||
numbers[j] = 7
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
b[1] = 4 - b[2] - b[3]
|
|
||||||
local d = {b}
|
|
||||||
local count = 1
|
|
||||||
if c == "gc" then
|
|
||||||
for i =1,4 do
|
|
||||||
if not simulateAnswer[i] then
|
|
||||||
d[count] = tableCopy(b)
|
|
||||||
d[count][4] = simulateAnswer1[i]
|
|
||||||
count = count + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif c == "rc" then
|
|
||||||
for i = 1,4 do
|
|
||||||
if simulateAnswer[i] == 7 then
|
|
||||||
d[count] = tableCopy(b)
|
|
||||||
d[count][4] = simulateAnswer1[i]
|
|
||||||
count = count + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return d
|
|
||||||
end
|
|
||||||
local function answerFilter(log,answers1)
|
|
||||||
local answers,count,jundge,answers2 = {},1,true,{}
|
|
||||||
if not answers1 then
|
|
||||||
for i1 = 1,6 do
|
|
||||||
for i2 = 1,6 do
|
|
||||||
for i3 = 1,6 do
|
|
||||||
for i4 = 1,6 do
|
|
||||||
answers[count] = {i1,i2,i3,i4}
|
|
||||||
count = count+1
|
|
||||||
end end end end
|
|
||||||
answers2 = tableCopy(answerFilter(log,answers))
|
|
||||||
else
|
|
||||||
answers = tableCopy(answers1)
|
|
||||||
for i,j in pairs(answers) do
|
|
||||||
for i6 = 1,#log do
|
|
||||||
if log[i6]["stepNumber"] and not tableCompare1(step(j,log[i6]["stepNumber"],"rc"),log[i6]["result"]) then
|
|
||||||
jundge = nil
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if jundge then
|
|
||||||
answers2[count] = j
|
|
||||||
count = count+1
|
|
||||||
else jundge = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return answers2
|
|
||||||
end
|
|
||||||
function translate(table)
|
|
||||||
local b = {0,0,0}
|
|
||||||
--output table b{[ash],[minecraft:redstone],[minecraft:glowstone_dust],[catalysed number]}
|
|
||||||
if analyser.list()[2]["name"] == "darkerdepths:ash" then
|
|
||||||
b[1] = analyser.list()[2]["count"]
|
|
||||||
if analyser.list()[3] then
|
|
||||||
if analyser.list()[3]["name"] == "minecraft:redstone" then
|
|
||||||
b[2] = analyser.list()[3]["count"]
|
|
||||||
if analyser.list()[4] then
|
|
||||||
b[3] = analyser.list()[4]["count"]
|
|
||||||
else b[3] = 0
|
|
||||||
end
|
|
||||||
elseif analyser.list()[3]["name"] == "minecraft:glowstone_dust" then
|
|
||||||
b[2] = 0
|
|
||||||
b[3] = analyser.list()[3]["count"]
|
|
||||||
else
|
|
||||||
print("analyser_trash")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif analyser.list()[2]["name"] == "minecraft:redstone" then
|
|
||||||
b[1] = 0
|
|
||||||
b[2] = analyser.list()[2]["count"]
|
|
||||||
if analyser.list()[3] then
|
|
||||||
b[3] = analyser.list()[3]["count"]
|
|
||||||
end
|
|
||||||
else
|
|
||||||
print("analyser_trash")
|
|
||||||
end
|
|
||||||
if shovel.list()[5] then
|
|
||||||
b[4] = table[shovel.getItemDetail(5).displayName]
|
|
||||||
end
|
|
||||||
return b
|
|
||||||
end
|
|
||||||
function suggestedInfoValue(a)
|
|
||||||
if a == 1 then print("error a == 1") end
|
|
||||||
local b = {2,6,12,20,30}
|
|
||||||
if a <= 6 then
|
|
||||||
return b[a-1]
|
|
||||||
elseif a <= 16 then
|
|
||||||
return 0.8809*a^2 - 1.158*a + 1
|
|
||||||
else
|
|
||||||
return 0.7435*a^2 + 3.3087*a + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function stepInstruct(log1,answers1)
|
|
||||||
local log = tableCopy(log1)
|
|
||||||
local answers,infoValue,count = nil,0,#log+1
|
|
||||||
if answers1 then
|
|
||||||
answers = tableCopy(answers1)
|
|
||||||
end
|
|
||||||
answers = answerFilter(log,answers)
|
|
||||||
if #answers == 1 then
|
|
||||||
return {answers[1],answers}
|
|
||||||
end
|
|
||||||
local sInfoV = suggestedInfoValue(#answers)
|
|
||||||
for k =1,80 do
|
|
||||||
log[count] = {["stepNumber"] = {math.random(1,6),math.random(1,6),math.random(1,6),math.random(1,6)}}
|
|
||||||
for i,j in pairs(answers) do
|
|
||||||
local temporary = step(j,log[count]["stepNumber"],"rc")
|
|
||||||
for m,n in pairs(temporary) do
|
|
||||||
log[count]["result"] = tableCopy(j)
|
|
||||||
infoValue = infoValue + (#answers - #answerFilter(log,answers))/#temporary
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if infoValue >= sInfoV then
|
|
||||||
return {log[count]["stepNumber"],answers}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printTable("sInfo "..tostring(sInfoV).." too bigger than "..tostring(infoValue))
|
|
||||||
print("#answers = "..tostring(#answers))
|
|
||||||
error("please restart the program",0)
|
|
||||||
end
|
|
||||||
function printTable(a)
|
|
||||||
if type(a) == "string" then
|
|
||||||
io.write(a)
|
|
||||||
elseif type(a) == "number" then
|
|
||||||
io.write(tostring(a))
|
|
||||||
elseif type(a) == "table" then
|
|
||||||
local count,jundge = 1,nil
|
|
||||||
io.write("{")
|
|
||||||
for i,j in pairs(a) do
|
|
||||||
if jundge then
|
|
||||||
io.write(",")
|
|
||||||
else
|
|
||||||
jundge = true
|
|
||||||
end
|
|
||||||
if i == count then
|
|
||||||
count = count + 1
|
|
||||||
elseif type(i) == "string" then
|
|
||||||
io.write( '["'..i..'"]=')
|
|
||||||
else io.write( '['..i..']=') end
|
|
||||||
printTable(j)
|
|
||||||
end
|
|
||||||
io.write("}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function main()
|
|
||||||
local table = {}
|
|
||||||
for i=1,6 do
|
|
||||||
table[mags.getItemDetail(i).displayName] = i
|
|
||||||
end
|
|
||||||
local log,count,answers = {{["stepNumber"] = {1,2,3,4}}},0,nil
|
|
||||||
--local read = io.read()
|
|
||||||
if true then
|
|
||||||
repeat
|
|
||||||
count = count + 1
|
|
||||||
print("the number "..count.." round")
|
|
||||||
input(log[count]["stepNumber"],"rc")
|
|
||||||
redstone.setOutput("right",true)
|
|
||||||
sleep(0.2)
|
|
||||||
redstone.setOutput("right",false)
|
|
||||||
sleep(5)
|
|
||||||
hop(3)
|
|
||||||
sleep(0.5)
|
|
||||||
shovel.pushItems(peripheral.getName(analyser),4,1)
|
|
||||||
repeat sleep(1) until analyser.list()[2]
|
|
||||||
log[count]["result"] = translate(table)
|
|
||||||
for i = 2 ,4 do
|
|
||||||
analyser.pushItems(peripheral.getName(bottler),i,64)
|
|
||||||
end
|
|
||||||
shovel.pushItems(peripheral.getName(mags),5,1)
|
|
||||||
local temporary = stepInstruct(log,answers)
|
|
||||||
answers = tableCopy(temporary[2])
|
|
||||||
log[count+1] = {["stepNumber"] = tableCopy(temporary[1])}
|
|
||||||
if #answers == 1 then
|
|
||||||
print("finish")
|
|
||||||
printTable(answers[1])
|
|
||||||
print(" ")
|
|
||||||
break
|
|
||||||
end
|
|
||||||
until nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
main()
|
|
||||||
209
utf8ptrint.lua
Normal file
209
utf8ptrint.lua
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
--这是一个简单的打印字符的程序,他使用下方url的字体进行显示
|
||||||
|
--因为字体文件超过cc存储大小所以使用网络加载字体
|
||||||
|
|
||||||
|
--通过printUtf8("字符",文字颜色,背景颜色)来达到类似 print的效果
|
||||||
|
--示例:printUtf8("你好世界! Hello Word!",colors.white,colors.lightGray)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- 从网络加载字库
|
||||||
|
local function loadRemoteFont(url)
|
||||||
|
local response = http.get(url)
|
||||||
|
if not response then
|
||||||
|
error("无法连接到字体服务器")
|
||||||
|
end
|
||||||
|
|
||||||
|
if response.getResponseCode() ~= 200 then
|
||||||
|
error("字体服务器返回错误: " .. response.getResponseCode())
|
||||||
|
end
|
||||||
|
|
||||||
|
local content = response.readAll()
|
||||||
|
response.close()
|
||||||
|
|
||||||
|
-- 使用沙箱环境安全加载字体
|
||||||
|
local sandbox = {}
|
||||||
|
local chunk, err = load(content, "=remoteFont", "t", sandbox)
|
||||||
|
if not chunk then
|
||||||
|
error("加载字体失败: " .. err)
|
||||||
|
end
|
||||||
|
|
||||||
|
local success, result = pcall(chunk)
|
||||||
|
if not success then
|
||||||
|
error("执行字体脚本失败: " .. result)
|
||||||
|
end
|
||||||
|
|
||||||
|
return sandbox.font or sandbox[1] or result
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 字体URL
|
||||||
|
local fontUrl = "https://git.liulikeji.cn/xingluo/ComputerCraft-Utf8/raw/branch/main/fonts/fusion-pixel-8px-proportional-zh_hans.lua"
|
||||||
|
local font = loadRemoteFont(fontUrl)
|
||||||
|
|
||||||
|
-- 显示单个字符的函数
|
||||||
|
local function displayChar(charMap, x, y, textColor, backgroundColor)
|
||||||
|
-- 保存原始终端颜色设置
|
||||||
|
local origTextColor = term.getTextColor()
|
||||||
|
local origBackgroundColor = term.getBackgroundColor()
|
||||||
|
|
||||||
|
-- 设置新颜色
|
||||||
|
term.setTextColor(textColor)
|
||||||
|
term.setBackgroundColor(backgroundColor)
|
||||||
|
|
||||||
|
-- 遍历字符位图的每一行
|
||||||
|
for row = 1, #charMap do
|
||||||
|
term.setCursorPos(x, y + row - 1)
|
||||||
|
local line = charMap[row]
|
||||||
|
|
||||||
|
-- 遍历行中的每个像素
|
||||||
|
for col = 1, #line do
|
||||||
|
local byte = string.byte(line, col)
|
||||||
|
|
||||||
|
-- 处理像素颜色
|
||||||
|
if byte < 128 then
|
||||||
|
-- 背景色像素:反转颜色设置
|
||||||
|
term.setTextColor(backgroundColor)
|
||||||
|
term.setBackgroundColor(textColor)
|
||||||
|
term.write(string.char(byte + 128)) -- 转换为可打印字符
|
||||||
|
else
|
||||||
|
-- 前景色像素:正常颜色设置
|
||||||
|
term.setTextColor(textColor)
|
||||||
|
term.setBackgroundColor(backgroundColor)
|
||||||
|
term.write(string.char(byte))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 恢复原始颜色设置
|
||||||
|
term.setTextColor(origTextColor)
|
||||||
|
term.setBackgroundColor(origBackgroundColor)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 显示UTF-8字符串的函数
|
||||||
|
local function displayUtf8String(str, font, x, y, textColor, backgroundColor)
|
||||||
|
-- UTF-8解码器(简化版)
|
||||||
|
local function utf8codes(str)
|
||||||
|
local i = 1
|
||||||
|
return function()
|
||||||
|
if i > #str then return end
|
||||||
|
|
||||||
|
local b1 = string.byte(str, i)
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
-- 单字节字符 (ASCII)
|
||||||
|
if b1 < 0x80 then
|
||||||
|
return b1
|
||||||
|
-- 双字节字符
|
||||||
|
elseif b1 >= 0xC0 and b1 < 0xE0 then
|
||||||
|
local b2 = string.byte(str, i) or 0
|
||||||
|
i = i + 1
|
||||||
|
return (b1 - 0xC0) * 64 + (b2 - 0x80)
|
||||||
|
-- 三字节字符(中文)
|
||||||
|
elseif b1 >= 0xE0 and b1 < 0xF0 then
|
||||||
|
local b2 = string.byte(str, i) or 0
|
||||||
|
i = i + 1
|
||||||
|
local b3 = string.byte(str, i) or 0
|
||||||
|
i = i + 1
|
||||||
|
return (b1 - 0xE0) * 4096 + (b2 - 0x80) * 64 + (b3 - 0x80)
|
||||||
|
else
|
||||||
|
-- 不支持的编码,返回空格
|
||||||
|
return 32
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local cursorX = x
|
||||||
|
|
||||||
|
-- 遍历字符串中的所有字符
|
||||||
|
for code in utf8codes(str) do
|
||||||
|
-- 获取字符位图
|
||||||
|
local charMap = font[code]
|
||||||
|
if not charMap then
|
||||||
|
-- 如果字库中没有该字符,使用空格代替
|
||||||
|
charMap = font[32] or {{"\x80"}} -- 空格字符
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 显示字符
|
||||||
|
displayChar(charMap, cursorX, y, textColor, backgroundColor)
|
||||||
|
|
||||||
|
-- 移动到下一个字符位置
|
||||||
|
cursorX = cursorX + #charMap[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local cursorX, cursorY = 1, 1
|
||||||
|
local fontHeight = #font[32] -- 获取字体高度(使用空格字符)
|
||||||
|
|
||||||
|
-- 自定义打印函数(带自动换行和滚动)
|
||||||
|
local function printUtf8(str, textColor, backgroundColor)
|
||||||
|
local width, screenHeight = term.getSize() -- 获取终端尺寸
|
||||||
|
|
||||||
|
-- UTF-8解码器
|
||||||
|
local function utf8codes(str)
|
||||||
|
local i = 1
|
||||||
|
return function()
|
||||||
|
if i > #str then return end
|
||||||
|
|
||||||
|
local b1 = string.byte(str, i)
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
if b1 < 0x80 then
|
||||||
|
return b1
|
||||||
|
elseif b1 >= 0xC0 and b1 < 0xE0 then
|
||||||
|
local b2 = string.byte(str, i) or 0
|
||||||
|
i = i + 1
|
||||||
|
return (b1 - 0xC0) * 64 + (b2 - 0x80)
|
||||||
|
elseif b1 >= 0xE0 and b1 < 0xF0 then
|
||||||
|
local b2 = string.byte(str, i) or 0
|
||||||
|
i = i + 1
|
||||||
|
local b3 = string.byte(str, i) or 0
|
||||||
|
i = i + 1
|
||||||
|
return (b1 - 0xE0) * 4096 + (b2 - 0x80) * 64 + (b3 - 0x80)
|
||||||
|
else
|
||||||
|
return 32 -- 不支持的字符显示为空格
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 处理字符串中的每个字符
|
||||||
|
for code in utf8codes(str) do
|
||||||
|
-- 处理换行符
|
||||||
|
if code == 10 then -- \n 的 ASCII
|
||||||
|
cursorX = 1
|
||||||
|
cursorY = cursorY + fontHeight
|
||||||
|
else
|
||||||
|
local charMap = font[code] or font[32]
|
||||||
|
local charWidth = #charMap[1]
|
||||||
|
|
||||||
|
-- 检查是否需要换行
|
||||||
|
if cursorX + charWidth - 1 > width then
|
||||||
|
cursorX = 1
|
||||||
|
cursorY = cursorY + fontHeight
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 检查是否需要滚动屏幕
|
||||||
|
if cursorY + fontHeight - 1 > screenHeight then
|
||||||
|
term.scroll(fontHeight)
|
||||||
|
cursorY = cursorY - fontHeight
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 显示字符
|
||||||
|
displayChar(charMap, cursorX, cursorY, textColor, backgroundColor)
|
||||||
|
cursorX = cursorX + charWidth
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 自动换行(处理完字符串后)
|
||||||
|
cursorX = 1
|
||||||
|
-- 光标应该位于下一行的顶部,而不是底部
|
||||||
|
cursorY = cursorY + fontHeight
|
||||||
|
|
||||||
|
-- 检查滚动(换行后)
|
||||||
|
if cursorY > screenHeight then
|
||||||
|
term.scroll(fontHeight)
|
||||||
|
cursorY = screenHeight - fontHeight + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return printUtf8
|
||||||
|
|
||||||
Reference in New Issue
Block a user