制作一款打飞机游戏27:精灵编辑器UI

继续开发我们的编辑器——Sprit Edit。我们已经创建了这个小编辑器,它可以显示很多精灵(sprites),并且我们可以遍历所有精灵。这真的很棒,我们可以创建新的精灵,这也不错。但是,唉,我们目前还不能编辑单个精灵。这就是我们要做的事情——创建一个用户界面(UI)来编辑单个精灵。

编辑器的设计理念

这次,我的想法是,当你跳转到一个精灵时,我想看到精灵的所有值,并且能够单独编辑每个值。这有点像垂直布局,而不是水平布局,因为水平布局最终会因为空间不足而显得混乱,特别是当数字很长时。而且,我认为重要的是,当你编辑时,你应该能看到你正在编辑的内容,这样才有即时的反馈。

实现过程

首先,我们要在顶部菜单添加一个项目,显示当前正在编辑的精灵的名称。然后,我们要列出当前精灵的所有值。我们需要至少显示八个值,并且要检查是否有nil值。

接下来,我们要为每个值添加一个文本框,并在文本框后显示对应的标签(如X、Y、高度等),以便用户知道每个值代表什么。

遇到的问题与解决

在开发过程中,我遇到了一些问题。例如,当我在不同模式之间切换时,程序有时会崩溃。原因是我在切换模式后没有刷新界面。我通过添加刷新函数解决了这个问题。

另一个问题是,当编辑nil值时,我想在文本框中显示一个空字符串,而不是nil。这需要我在获取数据时做一些额外的检查。

后续计划

现在,我们的编辑器已经可以基本工作了,但还有一些小细节需要调整。例如,我们还需要添加删除精灵的功能,以及处理一些可能导致程序崩溃的边界情况(如设置下一个精灵为当前精灵时导致的无限循环)。

我希望大家能发挥自己的创造力,思考如何设计自己的UI,并尝试实现这些功能。

pico-8 cartridge // http://www.pico-8.com
version 41
__lua__
function _init()--- customize here ---#include shmup_myspr.txtfile="shmup_myspr.txt"arrname="myspr"data=mysprreload(0x0,0x0,0x2000,"cowshmup.p8")----------------------debug={}msg={}_drw=draw_list_upd=update_listmenuitem(1,"export",export)curx=1cury=1scrolly=0scrollx=0poke(0x5f2d, 1)
endfunction _draw()_drw()if #msg>0 thenbgprint(msg[1].txt,64-#msg[1].txt*2,80,14)msg[1].t-=1if msg[1].t<=0 thendeli(msg,1)end  end-- debug --cursor(4,4)color(8)for txt in all(debug) doprint(txt)end
endfunction _update60()dokeys()mscroll=stat(36)_upd()
endfunction dokeys()if stat(30) thenkey=stat(31)if key=="p" thenpoke(0x5f30,1)endelsekey=nilendend
-->8
--draw
function draw_edit()-- backgroundfillp(0b11001100001100111100110000110011)rectfill(0,0,127,127,33)fillp(▒)line(63,0,63,127,13)line(0,63,127,63,13)fillp()draw_menu()-- draw spriteif selspr thenmspr(selspr,63,63)end-- blinking dotif (time()*2)%1<0.5 thenpset(63,63,rnd({8,13,7,15}))end
endfunction draw_list()fillp(0b11001100001100111100110000110011)rectfill(0,0,127,127,33)fillp(▒)line(63,0,63,127,13)line(0,63,127,63,13)fillp()draw_menu()if (time()*2)%1<0.5 thenpset(63,63,rnd({8,13,7,15}))end
endfunction draw_table()cls(2)draw_menu()
endfunction draw_menu()--spr(0,0,0,16,16)if menu thenfor i=1,#menu dofor j=1,#menu[i] dolocal mymnu=menu[i][j]local c=mymnu.c or 13if i==cury and j==curx thenc=7if _upd==upd_type thenc=0endendbgprint(mymnu.w,mymnu.x+scrollx,mymnu.y+scrolly,13)   bgprint(mymnu.txt,mymnu.x+scrollx,mymnu.y+scrolly,c) endendendif _upd==upd_type thenlocal mymnu=menu[cury][curx]local txt_bef=sub(typetxt,1,typecur-1)local txt_cur=sub(typetxt,typecur,typecur)local txt_aft=sub(typetxt,typecur+1)txt_cur=txt_cur=="" and " " or txt_cur if (time()*2)%1<0.5 thentxt_cur="\^i"..txt_cur.."\^-i"endlocal txt=txt_bef..txt_cur..txt_aftbgprint(txt,mymnu.x+scrollx,mymnu.y+scrolly,7)endend-->8
--update
function update_edit()refresh_edit()if btnp(⬆️) thencury-=1endif btnp(⬇️) thencury+=1endcury=(cury-1)%#menu+1cury-=mscrollcury=mid(1,cury,#menu)if cury==1 thencurx=1if btnp(⬅️) thenselspr-=1elseif btnp(➡️) thenselspr+=1endselspr=mid(1,selspr,#data)	elsecurx=2endif btnp(🅾️) then_drw=draw_list_upd=update_listrefresh_list()cury=selsprcurx=1returnendif btnp(❎) thenlocal mymnu=menu[cury][curx]if mymnu.cmd=="editval" then_upd=upd_typelocal s=tostr(data[mymnu.cmdy][mymnu.cmdx])if s==nil thens=""endtypetxt=stypecur=#typetxt+1typecall=enter_editendend
endfunction update_list()refresh_list()if btnp(⬆️) thencury-=1endif btnp(⬇️) thencury+=1endcury=(cury-1)%#menu+1cury-=mscrollcury=mid(1,cury,#menu)curx=1local mymnu=menu[cury][curx]if mymnu.y+scrolly>110 thenscrolly-=4endif mymnu.y+scrolly<10 thenscrolly+=4endscrolly=min(0,scrolly)if mymnu.x+scrollx>110 thenscrollx-=2endif mymnu.x+scrollx<20 thenscrollx+=2endscrollx=min(0,scrollx)if btnp(❎) thenlocal mymnu=menu[cury][curx]if mymnu.cmd=="newline" thenadd(data,{0,0,0,0,0,0})elseif mymnu.cmd=="editspr" thenselspr=mymnu.cmdy_upd=update_edit_drw=draw_editrefresh_edit()cury=1endend
endfunction update_table()refresh_table()if btnp(⬆️) thencury-=1endif btnp(⬇️) thencury+=1endcury=(cury-1)%#menu+1cury-=mscrollcury=mid(1,cury,#menu)if btnp(⬅️) thencurx-=1endif btnp(➡️) thencurx+=1endif cury<#menu thencurx=(curx-2)%(#menu[cury]-1)+2elsecurx=1endlocal mymnu=menu[cury][curx]if mymnu.y+scrolly>110 thenscrolly-=4endif mymnu.y+scrolly<10 thenscrolly+=4endscrolly=min(0,scrolly)if mymnu.x+scrollx>110 thenscrollx-=2endif mymnu.x+scrollx<20 thenscrollx+=2endscrollx=min(0,scrollx)if btnp(❎) thenlocal mymnu=menu[cury][curx]if mymnu.cmd=="edit" then_upd=upd_typetypetxt=tostr(mymnu.txt)typecur=#typetxt+1typecall=enter_tableelseif mymnu.cmd=="newline" thenadd(data,{0})  elseif mymnu.cmd=="newcell" thenadd(data[mymnu.cmdy],0)endend
endfunction upd_type()if key thenif key=="\r" then-- enter   poke(0x5f30,1)typecall()returnelseif key=="\b" then--backspaceif typecur>1 thenif typecur>#typetxt thentypetxt=sub(typetxt,1,#typetxt-1)elselocal txt_bef=sub(typetxt,1,typecur-2)local txt_aft=sub(typetxt,typecur)typetxt=txt_bef..txt_aftendtypecur-=1endelseif typecur>#typetxt thentypetxt..=keyelselocal txt_bef=sub(typetxt,1,typecur-1)local txt_aft=sub(typetxt,typecur)typetxt=txt_bef..key..txt_aftendtypecur+=1endendif btnp(⬅️) thentypecur-=1endif btnp(➡️) thentypecur+=1endtypecur=mid(1,typecur,#typetxt+1)
end
-->8
--toolsfunction bgprint(txt,x,y,c)print("\#0"..txt,x,y,c)
endfunction split2d(s)local arr=split(s,"|",false)for k, v in pairs(arr) doarr[k] = split(v)endreturn arr
endfunction mspr(si,sx,sy)local ms=myspr[si]sspr(ms[1],ms[2],ms[3],ms[4],sx-ms[5],sy-ms[6],ms[3],ms[4],ms[7]==1)if ms[7]==2 thensspr(ms[1],ms[2],ms[3],ms[4],sx-ms[5]+ms[3],sy-ms[6],ms[3],ms[4],true)endif ms[8] thenmspr(ms[8],sx,sy)end
endfunction spacejam(n)local ret=""for i=1,n doret..=" "endreturn ret
end
-->8
--i/o
function export()local s=arrname.."=split2d\""for i=1,#data doif i>1 thens..="|"endfor j=1,#data[i] doif j>1 thens..=","ends..=data[i][j]endends..="\""printh(s,file,true)add(msg,{txt="exported!",t=120})--debug[1]="exported!"
end
-->8
--ui
function refresh_edit()menu={}add(menu,{{txt="< sprite "..selspr.." >",w="",cmd="sprhead",x=2,y=2}})local lab={"  x:","  y:","wid:","hgt:"," ox:"," oy:"," fx:","nxt:"}for i=1,8 dolocal s=tostr(data[selspr][i])if s==nil thens="[nil]"endadd(menu,{{txt=lab[i],w="    ",x=2,y=3+i*7},{txt=s,w=spacejam(#s),cmd="editval",cmdy=selspr,cmdx=i,x=2+16,y=3+i*7}}) endendfunction refresh_list()menu={}for i=1,#data dolocal lne={}local linemax=#data[i]if i==cury thenlinemax+=1  endadd(lne,{txt="spr "..i,w="",cmd="editspr",cmdy=i,x=2,y=-4+6*i})add(menu,lne)endadd(menu,{{txt=" + ",w="   ",cmd="newline",x=2,y=-4+6*(#data+1)+2, }})
endfunction refresh_table()menu={}for i=1,#data dolocal lne={}local linemax=#data[i]if i==cury thenlinemax+=1  endadd(lne,{txt=i,w="   ",cmd="",x=4,y=-4+8*i,c=2  })for j=1,linemax doif j==#data[i]+1 thenadd(lne,{txt="+",w=" ",cmd="newcell",cmdy=i,x=-10+14*(j+1),y=-4+8*i, })elseadd(lne,{txt=data[i][j],cmd="edit",cmdx=j,cmdy=i,x=-10+14*(j+1),y=-4+8*i,w="   "})endendadd(menu,lne)endadd(menu,{{txt=" + ",w="   ",cmd="newline",x=4,y=-4+8*(#data+1), }})
endfunction enter_table()local mymnu=menu[cury][curx]local typeval=tonum(typetxt)if typeval==nil thenif mymnu.cmdx==#data[mymnu.cmdy] and typetxt=="" then--delete celldeli(data[mymnu.cmdy],mymnu.cmdx)if mymnu.cmdx==1 thendeli(data,mymnu.cmdy)end_upd=update_tablereturnend  typeval=0enddata[mymnu.cmdy][mymnu.cmdx]=typeval_upd=update_tablerefresh_table()
endfunction enter_edit()local mymnu=menu[cury][curx]local typeval=tonum(typetxt)if typeval==nil thentypeval=0enddata[mymnu.cmdy][mymnu.cmdx]=typeval_upd=update_editrefresh_edit()
end
__gfx__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__map__
0000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

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

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

相关文章

k8s(9) — zookeeper集群部署(亲和性、污点与容忍测试)

一、部署思路 1、前期设想 zookeeper集群至少需要运行3个pod集群才能够正常运行&#xff0c;考虑到节点会有故障的风险这个3个pod最好分别运行在&#xff13;个不同的节点上(为了实现这一需要用到亲和性和反亲和性概念)&#xff0c;在部署的时候对zookeeper运行的pod打标签加…

WXT+Vue3+sass+antd+vite搭建项目开发chrome插件

WXTVue3sassantdvite搭建项目开发chrome插件 前言一、初始化项目二、项目配置调整三、options页面配置四、集成antd五、集成sass六、环境配置七、代码注入 vue3&#xff1a;https://cn.vuejs.org/ axios&#xff1a;https://www.axios-http.cn/docs/api_intro antd&#xff1a;…

JSAPI2.4——正则表达式

一、语法 const str 一二三四五六七八九十 //判断内容 const reg /二/ //判断条件 console.log(reg.test(str)); //检查 二、test与exec方法的区别 test方法&#xff1a;用于判断是否符合规则的字符串&#xff0c;返回值是布尔值 exec方法&…

燃气用户检修工考试精选题

燃气用户检修工考试精选题&#xff1a; 我国国家标准规定民用天然气中硫化氢含量最高允许浓度是&#xff08; &#xff09;。 A. 20mg/m B. 15mg/m C. 5mg/m D. 50mg/m 答案&#xff1a;A 城市燃气应具有可以察觉的臭味&#xff0c;当无毒燃气泄漏到空气中&#xff0c;达到爆炸…

【前端】1h 搞定 TypeScript 教程_只说重点

不定期更新&#xff0c;建议关注收藏点赞。 目录 简介使用基本类型、类型推断和类型注解接口、类型别名、联合类型类与继承泛型GenericsReact 与 TS 进阶高级类型装饰器Decorators模块系统TypeScript 编译选项 简介 TypeScript&#xff08;简称 TS&#xff09;是一种由微软开发…

MyBatis 参数绑定

一、MyBatis 参数绑定机制 1.1 核心概念 当 Mapper 接口方法接收多个参数时&#xff0c;MyBatis 提供三种参数绑定方式&#xff1a; 默认参数名&#xff1a;arg0、arg1&#xff08;Java 8&#xff09;或 param1、param2Param 注解&#xff1a;显式指定参数名称POJO/DTO 对象…

【解决方案】Linux解决CUDA安装过程中GCC版本不兼容

Linux解决CUDA安装过程中GCC版本不兼容 目录 问题描述 解决方法 安装后配置 问题描述 Linux环境下安装 CUDA 时&#xff0c;运行sudo sh cuda_10.2.89_440.33.01_linux.run命令出现 “Failed to verify gcc version.” 的报错&#xff0c;提示 GCC 版本不兼容&#xff0c;查…

人工智能数学基础(一):人工智能与数学

在人工智能领域&#xff0c;数学是不可或缺的基石。无论是算法的设计、模型的训练还是结果的评估&#xff0c;都离不开数学的支持。接下来&#xff0c;我将带大家深入了解人工智能数学基础&#xff0c;包括微积分、线性代数、概率论、数理统计和最优化理论&#xff0c;并通过 P…

Shell脚本-嵌套循环应用案例

在Shell脚本编程中&#xff0c;嵌套循环是一种强大的工具&#xff0c;可以用于处理复杂的任务和数据结构。通过在一个循环内部再嵌套另一个循环&#xff0c;我们可以实现对多维数组、矩阵操作、文件处理等多种高级功能。本文将通过几个实际的应用案例来展示如何使用嵌套循环解决…

勘破养生伪常识,开启科学养生新篇

​在养生潮流风起云涌的当下&#xff0c;各种养生观点和方法层出不穷。但其中有不少是缺乏科学依据的伪常识&#xff0c;若不加分辨地盲目跟从&#xff0c;不仅难以实现养生目的&#xff0c;还可能损害健康。因此&#xff0c;勘破这些养生伪常识&#xff0c;是迈向科学养生的关…

Nacos-3.0.0适配PostgreSQL数据库

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

机器学习第三篇 模型评估(交叉验证)

Sklearn:可以做数据预处理、分类、回归、聚类&#xff0c;不能做神经网络。原始的工具包文档&#xff1a;scikit-learn: machine learning in Python — scikit-learn 1.6.1 documentation数据集:使用的是MNIST手写数字识别技术&#xff0c;大小为70000&#xff0c;数据类型为7…

如何在 IntelliJ IDEA 中编写 Speak 程序

在当今数字化时代&#xff0c;语音交互技术越来越受到开发者的关注。如果你想在 IntelliJ IDEA&#xff08;一个强大的集成开发环境&#xff09;中编写一个语音交互&#xff08;Speak&#xff09;程序&#xff0c;那么本文将为你提供详细的步骤和指南。 一、环境准备 在开始编…

AI大模型学习十四、白嫖腾讯Cloud Studio AI环境 通过Ollama+Dify+DeepSeek构建生成式 AI 应用-接入DeepSeek大模型

一、说明 需要阅读 AI大模型学习十三、白嫖腾讯Cloud Studio AI环境 通过OllamaDifyDeepSeek构建生成式 AI 应用-安装-CSDN博客https://blog.csdn.net/jiangkp/article/details/147580344?spm1011.2415.3001.5331 我们今天干点啥呢&#xff0c;跟着官网走 模型类型 在 Dify…

《Astro 3.0岛屿架构让内容网站“脱胎换骨”》

内容优先的网站越来越成为主流。无论是新闻资讯、知识博客&#xff0c;还是电商产品展示&#xff0c;用户都希望能快速获取所需内容&#xff0c;这对网站的性能和体验提出了极高要求。而Astro 3.0的岛屿架构&#xff0c;就像是为内容优先网站量身定制的一把神奇钥匙&#xff0c…

在 UniApp 中实现 App 与 H5 页面的跳转及通信

在移动应用开发中&#xff0c;内嵌 H5 页面或与外部网页交互是常见需求。UniApp 作为跨平台框架&#xff0c;提供了灵活的方式实现 App 与 H5 的跳转和双向通信。本文将详细讲解实现方法&#xff0c;并提供可直接复用的代码示例。 文章目录 一、 App 内嵌 H5 页面&#xff08;使…

springboot 实现敏感信息脱敏

记录于2025年4月28号晚上--梧州少帅 1. 定义枚举类&#xff1a; public enum DesensitizeType {NAME, EMAIL } 2. 创建自定义注解&#xff1a; 用于标记需要脱敏的字段及其类型。 Retention(RetentionPolicy.RUNTIME) JacksonAnnotationsInside JsonSerialize(using Desen…

SNMP协议之详解(Detailed Explanation of SNMP Protocol)

SNMP协议之详解 一、前言 SNMP&#xff0c;被形象地喻为网络世界大的工具箱&#xff0c;使他们能的“智慧守护者”&#xff0c;它为网络管理员装备了一套功能强够实现对网络设备状态的实时监控、性能数据的全面收集、远程配置的灵活管理以及故障事件的即时响应。借助SNMP&…

SpeedyAutoLoot

SpeedyAutoLoot自动拾取插件 SpeedyAutoLoot.lua local AutoLoot CreateFrame(Frame)SpeedyAutoLootDB SpeedyAutoLootDB or {} SpeedyAutoLootDB.global SpeedyAutoLootDB.global or {}local BACKPACK_CONTAINER BACKPACK_CONTAINER local LOOT_SLOT_CURRENCY LOOT_SLOT…

xe-upload上传文件插件

1.xe-upload地址&#xff1a;文件选择、文件上传组件&#xff08;图片&#xff0c;视频&#xff0c;文件等&#xff09; - DCloud 插件市场 2.由于开发app要用到上传文件组件&#xff0c;uni.chooseFile在app上不兼容&#xff0c;所以找到了xe-upload&#xff0c;兼容性很强&a…