Compare commits

..

6 Commits

Author SHA1 Message Date
MrZ626
afa69ce9a4 版本推进 2021-11-27 04:24:41 +08:00
MrZ626
3226c0c831 重构字体模块,支持多字体
控制台应用等宽字体
2021-11-27 04:24:40 +08:00
MrZ626
4e759cad4c ultra模式重开时会重新播放bgm 2021-11-27 02:05:48 +08:00
MrZ626
291795928d 更多的设置修改的时候会触发警告 2021-11-26 21:52:10 +08:00
MrZ626
a1315e7f7f 修复一处遗留逻辑hold和序列生成相关的错误 2021-11-26 21:24:34 +08:00
MrZ626
657bc2b4e0 修正加载文件的时候会因为没有应用语言没法弹出消息而报错 2021-11-26 14:15:42 +08:00
13 changed files with 136 additions and 119 deletions

View File

@@ -1,67 +1,60 @@
local gc=love.graphics
local set=gc.setFont
local fontCache={}
local currentFontSize
local fontFiles,fontCache={},{}
local defaultFont,defaultFallBack
local curFont=false--Current using font object
local FONT={}
function FONT.set(s)
if s~=currentFontSize then
if not fontCache[s]then
fontCache[s]=gc.setNewFont(s,'light',gc.getDPIScale()*SCR.k*2)
end
set(fontCache[s])
currentFontSize=s
end
end
function FONT.get(s)
function FONT.setDefault(name)defaultFont=name end
function FONT.setFallback(name)defaultFallBack=name end
function FONT.rawget(s)
if not fontCache[s]then
fontCache[s]=gc.setNewFont(s,'light',gc.getDPIScale()*SCR.k*2)
end
return fontCache[s]
end
function FONT.reset()
for s in next,fontCache do
fontCache[s]=gc.setNewFont(s,'light',gc.getDPIScale()*SCR.k*2)
end
function FONT.rawset(s)
set(fontCache[s]or FONT.rawget(s))
end
function FONT.load(mainFont,secFont)
assert(love.filesystem.getInfo(mainFont),"Font file '"..mainFont.."' not exist!")
mainFont=love.filesystem.newFile(mainFont)
if secFont and love.filesystem.getInfo(secFont)then
secFont=love.filesystem.newFile(secFont)
else
secFont=false
end
function FONT.set(s)
if s~=currentFontSize then
if not fontCache[s]then
fontCache[s]=gc.setNewFont(mainFont,s,'light',gc.getDPIScale()*SCR.k*2)
if secFont then
fontCache[s]:setFallbacks(gc.setNewFont(secFont,s,'light',gc.getDPIScale()*SCR.k*2))
end
end
set(fontCache[s])
currentFontSize=s
end
end
function FONT.get(s)
if not fontCache[s]then
fontCache[s]=gc.setNewFont(mainFont,s,'light',gc.getDPIScale()*SCR.k*2)
if secFont then
fontCache[s]:setFallbacks(gc.setNewFont(secFont,s,'light',gc.getDPIScale()*SCR.k*2))
end
end
return fontCache[s]
end
function FONT.reset()
for s in next,fontCache do
fontCache[s]=gc.setNewFont(mainFont,s,'light',gc.getDPIScale()*SCR.k*2)
if secFont then
fontCache[s]:setFallbacks(gc.setNewFont(secFont,s,'light',gc.getDPIScale()*SCR.k*2))
end
end
function FONT.load(fonts)
for name,path in next,fonts do
assert(love.filesystem.getInfo(path),("Font file $1($2) not exist!"):repD(name,path))
fontFiles[name]=love.filesystem.newFile(path)
fontCache[name]={}
end
FONT.reset()
end
function FONT.get(size,name)
if not name then name=defaultFont end
local f=fontCache[name][size]
if not f then
f=gc.setNewFont(fontFiles[name],size,'light',gc.getDPIScale()*SCR.k*2)
if defaultFallBack and name~=defaultFallBack then
f:setFallbacks(FONT.get(size,defaultFallBack))
end
fontCache[name][size]=f
end
return f
end
function FONT.set(size,name)
if not name then name=defaultFont end
local f=fontCache[name][size]
if f~=curFont then
curFont=f or FONT.get(size,name)
set(curFont)
end
end
function FONT.reset()
for name,cache in next,fontCache do
if type(cache)=='table'then
for size in next,cache do
cache[size]=FONT.get(size,name)
end
else
fontCache[name]=FONT.rawget(name)
end
end
end
return FONT

View File

@@ -95,6 +95,7 @@ do--function GC.DO(L)
setLJ="setLineJoin",
print="print",
rawFT=function(...)FONT.rawset(...)end,
setFT=function(...)FONT.set(...)end,
mText=GC.mStr,
mDraw=GC.draw,

View File

@@ -527,17 +527,17 @@ local wsBottomImage do
wsBottomImage=GC.DO(L)
end
local ws_deadImg=GC.DO{20,20,
{'setFT',20},
{'rawFT',20},
{'setCL',1,.3,.3},
{'mText',"X",11,-1},
}
local ws_connectingImg=GC.DO{20,20,
{'setFT',20},
{'rawFT',20},
{'setLW',3},
{'mText',"C",11,-1},
}
local ws_runningImg=GC.DO{20,20,
{'setFT',20},
{'rawFT',20},
{'setCL',.5,1,0},
{'mText',"R",11,-1},
}

View File

@@ -29,7 +29,7 @@ local clearIcon=GC.DO{40,40,
{'fRect',11,14,18,21},
}
local sureIcon=GC.DO{40,40,
{'setFT',35},
{'rawFT',35},
{'mText',"?",20,0},
}
local smallerThen=GC.DO{20,20,
@@ -82,7 +82,7 @@ function text:draw()
end
end
end
function WIDGET.newText(D)--name,x,y[,fText][,color][,font=30][,align='M'][,hideF][,hide]
function WIDGET.newText(D)--name,x,y[,fText][,color][,font=30][,fType][,align='M'][,hideF][,hide]
local _={
name= D.name or"_",
x= D.x,
@@ -91,6 +91,7 @@ function WIDGET.newText(D)--name,x,y[,fText][,color][,font=30][,align='M'][,hide
fText=D.fText,
color=D.color and(COLOR[D.color]or D.color)or COLOR.Z,
font= D.font or 30,
fType=D.fType,
align=D.align or'M',
hideF=D.hideF,
}
@@ -139,7 +140,7 @@ function button:reset()
end
function button:setObject(obj)
if type(obj)=='string'or type(obj)=='number'then
self.obj=gc.newText(FONT.get(self.font),obj)
self.obj=gc.newText(FONT.get(self.font,self.fType),obj)
elseif obj then
self.obj=obj
end
@@ -209,7 +210,7 @@ function button:draw()
end
end
function button:getInfo()
return("x=%d,y=%d,w=%d,h=%d,font=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font)
return("x=%d,y=%d,w=%d,h=%d,font=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font,self.fType)
end
function button:press(_,_,k)
self.code(k)
@@ -225,7 +226,7 @@ function button:press(_,_,k)
SFX.play('button')
end
end
function WIDGET.newButton(D)--name,x,y,w[,h][,fText][,color][,font=30][,sound=true][,align='M'][,edge=0],code[,hideF][,hide]
function WIDGET.newButton(D)--name,x,y,w[,h][,fText][,color][,font=30][,fType][,sound=true][,align='M'][,edge=0],code[,hideF][,hide]
if not D.h then D.h=D.w end
local _={
name= D.name or"_",
@@ -246,6 +247,7 @@ function WIDGET.newButton(D)--name,x,y,w[,h][,fText][,color][,font=30][,sound=tr
fText=D.fText,
color=D.color and(COLOR[D.color]or D.color)or COLOR.Z,
font= D.font or 30,
fType=D.fType,
align=D.align or'M',
edge= D.edge or 0,
sound=D.sound~=false,
@@ -268,7 +270,7 @@ function key:reset()
end
function key:setObject(obj)
if type(obj)=='string'or type(obj)=='number'then
self.obj=gc.newText(FONT.get(self.font),obj)
self.obj=gc.newText(FONT.get(self.font,self.fType),obj)
elseif obj then
self.obj=obj
end
@@ -331,7 +333,7 @@ function key:draw()
end
end
function key:getInfo()
return("x=%d,y=%d,w=%d,h=%d,font=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font)
return("x=%d,y=%d,w=%d,h=%d,font=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font,self.fType)
end
function key:press(_,_,k)
self.code(k)
@@ -339,7 +341,7 @@ function key:press(_,_,k)
SFX.play('key')
end
end
function WIDGET.newKey(D)--name,x,y,w[,h][,fText][,fShade][,noFrame][,color][,font=30][,sound=true][,align='M'][,edge=0],code[,hideF][,hide]
function WIDGET.newKey(D)--name,x,y,w[,h][,fText][,fShade][,noFrame][,color][,font=30][,fType][,sound=true][,align='M'][,edge=0],code[,hideF][,hide]
if not D.h then D.h=D.w end
local _={
name= D.name or"_",
@@ -362,6 +364,7 @@ function WIDGET.newKey(D)--name,x,y,w[,h][,fText][,fShade][,noFrame][,color][,fo
noFrame=D.noFrame,
color= D.color and(COLOR[D.color]or D.color)or COLOR.Z,
font= D.font or 30,
fType=D.fType,
sound= D.sound~=false,
align= D.align or'M',
edge= D.edge or 0,
@@ -430,7 +433,7 @@ function switch:draw()
gc_draw(obj,x-12-ATV,y,nil,min(self.lim/obj:getWidth(),1),1,obj:getWidth(),obj:getHeight()*.5)
end
function switch:getInfo()
return("x=%d,y=%d,font=%d"):format(self.x,self.y,self.font)
return("x=%d,y=%d,font=%d"):format(self.x,self.y,self.font,self.fType)
end
function switch:press()
self.code()
@@ -438,7 +441,7 @@ function switch:press()
SFX.play('touch')
end
end
function WIDGET.newSwitch(D)--name,x,y[,lim][,fText][,color][,font=30][,sound=true][,disp],code[,hideF][,hide]
function WIDGET.newSwitch(D)--name,x,y[,lim][,fText][,color][,font=30][,fType][,sound=true][,disp],code[,hideF][,hide]
local _={
name= D.name or"_",
@@ -453,6 +456,7 @@ function WIDGET.newSwitch(D)--name,x,y[,lim][,fText][,color][,font=30][,sound=tr
fText=D.fText,
color=D.color and(COLOR[D.color]or D.color)or COLOR.Z,
font= D.font or 30,
fType=D.fType,
sound=D.sound~=false,
disp= D.disp,
code= D.code,
@@ -595,7 +599,7 @@ end
function slider:arrowKey(k)
self:scroll((k=="left"or k=="up")and -1 or 1)
end
function WIDGET.newSlider(D)--name,x,y,w[,lim][,fText][,color][,unit][,smooth][,font=30][,change],disp[,show],code,hide
function WIDGET.newSlider(D)--name,x,y,w[,lim][,fText][,color][,unit][,smooth][,font=30][,fType][,change],disp[,show],code,hide
local _={
name= D.name or"_",
@@ -617,6 +621,7 @@ function WIDGET.newSlider(D)--name,x,y,w[,lim][,fText][,color][,unit][,smooth][,
unit= D.unit or 1,
smooth=false,
font= D.font or 30,
fType=D.fType,
change=D.change,
disp= D.disp,
code= D.code,
@@ -863,7 +868,7 @@ function inputBox:draw()
--Drawable
local f=self.font
FONT.set(f)
FONT.set(f,self.fType)
if self.obj then
mDraw_Y(self.obj,x-12-self.obj:getWidth(),y+h*.5)
end
@@ -906,7 +911,7 @@ function inputBox:keypress(k)
self.value=t
end
end
function WIDGET.newInputBox(D)--name,x,y,w[,h][,font=30][,secret][,regex][,limit],hide
function WIDGET.newInputBox(D)--name,x,y,w[,h][,font=30][,fType][,secret][,regex][,limit],hide
local _={
name= D.name or"_",
@@ -922,6 +927,7 @@ function WIDGET.newInputBox(D)--name,x,y,w[,h][,font=30][,secret][,regex][,limit
},
font= D.font or int(D.h/7-1)*5,
fType=D.fType,
secret=D.secret==true,
regex= D.regex,
limit= D.limit,
@@ -1022,7 +1028,7 @@ function textBox:draw()
gc_rectangle('line',x,y,w,h,3)
--Texts
FONT.set(self.font)
FONT.set(self.font,self.fType)
gc_push('transform')
gc_translate(x,y)
@@ -1054,7 +1060,7 @@ end
function textBox:getInfo()
return("x=%d,y=%d,w=%d,h=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h)
end
function WIDGET.newTextBox(D)--name,x,y,w,h[,font=30][,lineH][,fix],hide
function WIDGET.newTextBox(D)--name,x,y,w,h[,font=30][,fType][,lineH][,fix],hide
local _={
name= D.name or"_",
@@ -1076,6 +1082,7 @@ function WIDGET.newTextBox(D)--name,x,y,w,h[,font=30][,lineH][,fix],hide
h= D.h,
font= D.font or 30,
fType=D.fType,
fix= D.fix,
texts={},
hideF=D.hideF,

View File

@@ -50,7 +50,13 @@ local _LOADTIME_=TIME()
--Load modules
Z=require'Zframework'
FONT.load('parts/fonts/proportional.ttf')
FONT.load{
norm='parts/fonts/proportional.ttf',
mono='parts/fonts/monospaced.ttf',
}
FONT.setDefault('norm')
FONT.setFallback('norm')
SCR.setSize(1280,720)--Initialize Screen size
BGM.setMaxSources(5)
BGM.setChange(function(name)MES.new('music',text.nowPlaying..name,5)end)

View File

@@ -19,6 +19,7 @@ return{
mStr(T,63,268)
end,
task=function(P)
BGM.seek(0)
P.modeData.section=1
while true do
YIELD()

View File

@@ -15,41 +15,46 @@ local playSFX=SFX.play
--System
function loadFile(name,args)
if not args then args=''end
local res,mes=pcall(FILE.load,name,args)
if res then
return mes
else
if mes:find'open error'then
MES.new('error',text.loadError_open:repD(name))
elseif mes:find'unknown mode'then
MES.new('error',text.loadError_errorMode:repD(name,args))
elseif mes:find'no file'then
if not args:sArg'-canSkip'then
MES.new('error',text.loadError_noFile:repD(name))
end
elseif mes then
MES.new('error',text.loadError_other:repD(name,mes))
do--function loadFile(name,args), function saveFile(data,name,args)
local t=setmetatable({},{__index=function()return"'$1' loading failed: $2"end})
function loadFile(name,args)
local text=text or t
if not args then args=''end
local res,mes=pcall(FILE.load,name,args)
if res then
return mes
else
MES.new('error',text.loadError_unknown:repD(name))
if mes:find'open error'then
MES.new('error',text.loadError_open:repD(name,""))
elseif mes:find'unknown mode'then
MES.new('error',text.loadError_errorMode:repD(name,args))
elseif mes:find'no file'then
if not args:sArg'-canSkip'then
MES.new('error',text.loadError_noFile:repD(name,""))
end
elseif mes then
MES.new('error',text.loadError_other:repD(name,mes))
else
MES.new('error',text.loadError_unknown:repD(name,""))
end
end
end
end
function saveFile(data,name,args)
local res,mes=pcall(FILE.save,data,name,args)
if res then
return mes
else
MES.new('error',
mes:find'duplicate'and
text.saveError_duplicate:repD(name)or
mes:find'encode error'and
text.saveError_encode:repD(name)or
mes and
text.saveError_other:repD(name,mes)or
text.saveError_unknown:repD(name)
)
function saveFile(data,name,args)
local text=text or t
local res,mes=pcall(FILE.save,data,name,args)
if res then
return mes
else
MES.new('error',
mes:find'duplicate'and
text.saveError_duplicate:repD(name)or
mes:find'encode error'and
text.saveError_encode:repD(name)or
mes and
text.saveError_other:repD(name,mes)or
text.saveError_unknown:repD(name)
)
end
end
end
function isSafeFile(file,mes)
@@ -865,8 +870,11 @@ end
do--CUS/SETXXX(k)
local CUSTOMENV=CUSTOMENV
local warnList={
'ims','RS','FTLock','frameMul','highCam',
'das','arr','dascut','dropcut','sddas','sdarr',
'ihs','irs','ims','RS',
'FTLock','frameMul','highCam',
'VKSwitch','VKIcon','VKTrack','VKDodge',
'simpMode',
}
function CUSval(k)return function()return CUSTOMENV[k]end end
function ROOMval(k)return function()return ROOMENV[k]end end

View File

@@ -1390,8 +1390,10 @@ function Player:popNext(ifhold)--Pop nextQueue to hand
self:act_hardDrop()
pressing[6]=false
end
else
elseif self.holdQueue[1]then--Force using hold
self:hold()
else--Next queue is empty, force lose
self:lose(true)
end
end

View File

@@ -256,9 +256,6 @@ local seqGenerators={
if seq[1]then
P:getNext(rem(seq))
else
if not(P.cur or P.nextQueue[1]or P.holdQueue[1])then
P:lose(true)
end
break
end
end

View File

@@ -3,8 +3,8 @@ local kb=love.keyboard
local ins,rem=table.insert,table.remove
local C=COLOR
local inputBox=WIDGET.newInputBox{name='input',x=40,y=650,w=1200,h=50}
local outputBox=WIDGET.newTextBox{name='output',x=40,y=30,w=1200,h=610,font=25,lineH=25,fix=true}
local inputBox=WIDGET.newInputBox{name='input',x=40,y=650,w=1200,h=50,fType='mono'}
local outputBox=WIDGET.newTextBox{name='output',x=40,y=30,w=1200,h=610,font=25,fType='mono',lineH=25,fix=true}
local function log(str)outputBox:push(str)end
log{C.lP,"Techmino Console"}

View File

@@ -35,7 +35,7 @@ local loadingThread=coroutine.wrap(function()
YIELD('loadSample')SFX.loadSample{name='lead',path='media/sample/lead',base='A3'}--A3~A5
YIELD('loadSample')SFX.loadSample{name='bell',path='media/sample/bell',base='A4'}--A4~A6
YIELD('loadVoice')VOC.load('media/vocal/'..SETTING.vocPack..'/')
YIELD('loadFont')for i=1,17 do getFont(15+5*i)end
YIELD('loadFont')for i=1,17 do getFont(15+5*i)getFont(15+5*i,'mono')end
YIELD('loadModeIcon')
local modeIcons={}

View File

@@ -5,8 +5,8 @@ return[=[
其他未来内容:
实时统计数据可视化; 教学关脚本语言; 从录像继续
模式系统重做; 重做模组UI; 加速下落; spike相关统计数据
支持更多手柄; 场地格边缘线; 模式数据分析; 高级自定义序列
等级系统; 成就系统; 手势操作; C2连击; 特殊控件(虚拟摇杆等)
等级系统; 场地格边缘线; 模式数据分析; 高级自定义序列
成就系统; 手势操作; C2连击; 特殊控件(虚拟摇杆等)
组队战; 方块位移/旋转动画; 更细节的DAS选项; 拓展主题系统
更自由的攻击系统; 更多消除方式; 可调场地宽度; 新联网游戏场景切换逻辑
task-Z(新AI); 自适应UI; 多方块
@@ -23,18 +23,20 @@ return[=[
改动:
调整游戏大logo为正体字
软降n格的键也可以触发深降
ultra模式计时器改为秒表,容易看清具体时间
ultra模式计时器改为秒表,重开的时候会重播bgm
出块/消行延迟逻辑修正,现在真的是0延迟,不再有一帧等待了(略微影响手感,更滑)
生成位置预览开启后hold的生成位置也可见 #453
TRS的S/Z添加四个踢墙防止在一些地方卡死
优化pc训练模式体验,添加胜利条件,不再无尽
堆积模式添加15帧的窒息延迟 #465
小程序arm加入计时器和重置按钮
修改部分不常用设置时会显示警告
小程序arm加入计时器和重置按钮
控制台使用等宽字体,更有味道(
代码:
bgm模块可限制最大加载数,不容易达到上限导致没声 #447
BGM模块可限制最大加载数,不容易达到上限导致没声 #447
语音模块支持设置轻微随机音调偏移半径(游戏内固定使用1)
较大规模整理玩家相关代码,重构出块延迟消行延迟逻辑
较大规模整理玩家相关代码,重构出块延迟/消行延迟/`当前块`逻辑
重构字体模块,支持多字体
再次封装FILE模块
扩展字符串扩展模块
修复:

View File

@@ -1,5 +1,5 @@
return{
["apkCode"]=409,
["apkCode"]=410,
["code"]=1700,
["string"]="V0.17.0",
["room"]="ver A-2",