新增聊天框控件,用于联网场景(未完成)

This commit is contained in:
MrZ626
2021-01-24 00:45:08 +08:00
parent 4643ef6179
commit eb370ba88f
7 changed files with 104 additions and 62 deletions

View File

@@ -4,6 +4,7 @@ local kb=love.keyboard
local int,abs=math.floor,math.abs local int,abs=math.floor,math.abs
local max,min=math.max,math.min local max,min=math.max,math.min
local sub,format=string.sub,string.format local sub,format=string.sub,string.format
local ins=table.insert
local setFont,mStr=setFont,mStr local setFont,mStr=setFont,mStr
local WIDGET={} local WIDGET={}
@@ -797,6 +798,94 @@ function WIDGET.newTextBox(D)--name,x,y,w[,h][,font][,secret][,regex],hide
return _ return _
end end
local chatBox={
type="chatBox",
scrollPos=0,
new=false,
-- texts={},
}
function chatBox:reset()
if not self.texts then
self.texts={}
end
end
function chatBox:push(t)
ins(self.texts,t)
if self.scrollPos==#self.texts-1 then
self.scrollPos=self.scrollPos+1
else
SFX.play("spin_0",.8)
self.new=true
end
end
function chatBox:scroll(n)
if n<0 then
self.scrollPos=max(self.scrollPos+n,min(#self.texts,self.capacity))
else
self.scrollPos=min(self.scrollPos+n,#self.texts)
if self.scrollPos==#self.texts then
self.new=false
end
end
end
function chatBox:clear()
self.texts={}
SFX.play("fall")
end
function chatBox:draw()
local x,y,w,h=self.x,self.y,self.w,self.h
local texts=self.texts
local scroll=self.scrollPos
local cap=self.capacity
--Frame
gc.setLineWidth(4)
gc.setColor(0,0,0,.3)
gc.rectangle("fill",x,y,w,h)
gc.setColor(1,1,1)
gc.rectangle("line",x,y,w,h)
--Texts
setFont(30)
for i=max(scroll-cap+1,1),scroll do
gc.printf(texts[i],x+8,y+h-10-30*(scroll-i+1),w)
end
--Slider
if #texts>cap then
gc.setLineWidth(2)
gc.rectangle("line",x-25,y,20,h)
local len=h*cap/#texts
gc.rectangle("fill",x-22,y+(h-len-6)*(scroll-cap)/(#texts-cap)+3,14,len)
end
--Draw
if self.new and scroll~=#texts then
setFont(40)
gc.setColor(1,TIME()%.4<.2 and 1 or 0,0)
gc.print("v",8,480)
end
end
function chatBox:getInfo()
return format("x=%d,y=%d,w=%d,h=%d",self.x+self.w*.5,self.y+self.h*.5,self.w,self.h)
end
function WIDGET.newChatBox(D)--name,x,y,w[,h][,font],hide
local _={
name= D.name,
x= D.x,
y= D.y,
w= D.w,
h= D.h,
capacity=int((D.h-10)/30),
hide= D.hide,
}
for k,v in next,chatBox do _[k]=v end
setmetatable(_,widgetMetatable)
return _
end
WIDGET.active={}--Table contains all active widgets WIDGET.active={}--Table contains all active widgets
WIDGET.sel=false--Selected widget WIDGET.sel=false--Selected widget

View File

@@ -258,7 +258,6 @@ return{
down="", down="",
}, },
net_chat={ net_chat={
clear="Clear",
send="Send", send="Send",
}, },
setting_game={ setting_game={

View File

@@ -236,7 +236,6 @@ return{
down="", down="",
}, },
net_chat={ net_chat={
-- clear="Clear",
-- send="Send", -- send="Send",
}, },
setting_game={ setting_game={

View File

@@ -257,7 +257,6 @@ return{
down="", down="",
}, },
net_chat={ net_chat={
clear="Limpar",
send="Mandar", send="Mandar",
}, },
setting_game={ setting_game={

View File

@@ -240,7 +240,6 @@ return{
down="", down="",
}, },
net_chat={ net_chat={
-- clear="Clear",
-- send="Send", -- send="Send",
}, },
setting_game={ setting_game={

View File

@@ -261,7 +261,6 @@ return{
down="", down="",
}, },
net_chat={ net_chat={
clear="清空",
send="发送", send="发送",
}, },
setting_game={ setting_game={

View File

@@ -1,18 +1,20 @@
local gc=love.graphics local gc=love.graphics
local ins,rem=table.insert,table.remove local chatBox=WIDGET.newChatBox{name="texts",x=50,y=50,w=1200,h=430}
local max,min=math.max,math.min
local texts={}
local remain--People in chat room local remain--People in chat room
local scrollPos--Scroll up length
local newMessage=false--If there is a new message
local heartBeatTimer local heartBeatTimer
local escapeTimer=0 local escapeTimer=0
local function focusAtTextbox() local function _init()
coroutine.yield() coroutine.yield()
WIDGET.sel=WIDGET.active.text WIDGET.sel=WIDGET.active.text
local texts=chatBox.texts
if #texts==0 then
chatBox:push{COLOR.dG,text.chatStart}
elseif #texts>1 and texts[#texts][1]~=COLOR.dG then
chatBox:push{COLOR.dG,text.chatHistory}
end
chatBox:scroll(1)
end end
local function sendMessage() local function sendMessage()
local W=WIDGET.active.text local W=WIDGET.active.text
@@ -20,14 +22,6 @@ local function sendMessage()
W.value="" W.value=""
end end
end end
local function pushText(t)
ins(texts,t)
end
local function clearHistory()
while #texts>1 do rem(texts)end
scrollPos=1
SFX.play("fall")
end
local scene={} local scene={}
@@ -35,13 +29,7 @@ function scene.sceneInit()
heartBeatTimer=0 heartBeatTimer=0
remain=false remain=false
if #texts==0 then TASK.new(_init)--Widgets are not initialized, so active after 1 frame
pushText{COLOR.dG,text.chatStart}
elseif #texts>1 and texts[#texts][1]~=COLOR.dG then
pushText{COLOR.dG,text.chatHistory}
end
scrollPos=#texts
TASK.new(focusAtTextbox)--Widgets are not initialized, so active after 1 frame
TASK.new(TICK_wsRead) TASK.new(TICK_wsRead)
BG.set("none") BG.set("none")
end end
@@ -56,12 +44,9 @@ function scene.wheelMoved(_,y)
end end
function scene.keyDown(k) function scene.keyDown(k)
if k=="up"then if k=="up"then
scrollPos=max(scrollPos-1,min(#texts,12)) chatBox:scroll(-1)
elseif k=="down"then elseif k=="down"then
scrollPos=min(scrollPos+1,#texts) chatBox:scroll(1)
if scrollPos==#texts then
newMessage=false
end
elseif k=="return"then elseif k=="return"then
sendMessage() sendMessage()
elseif k=="escape"then elseif k=="escape"then
@@ -80,14 +65,14 @@ function scene.socketRead(mes)
local cmd=mes:sub(1,1) local cmd=mes:sub(1,1)
local args=splitStr(mes:sub(2),":") local args=splitStr(mes:sub(2),":")
if cmd=="J"or cmd=="L"then if cmd=="J"or cmd=="L"then
pushText{ chatBox:push{
COLOR.lR,args[1], COLOR.lR,args[1],
COLOR.dY,args[2].." ", COLOR.dY,args[2].." ",
COLOR.Y,text[cmd=="J"and"chatJoin"or"chatLeave"] COLOR.Y,text[cmd=="J"and"chatJoin"or"chatLeave"]
} }
remain=tonumber(args[3]) remain=tonumber(args[3])
elseif cmd=="T"then elseif cmd=="T"then
pushText{ chatBox:push{
COLOR.W,args[1], COLOR.W,args[1],
COLOR.dY,args[2].." ", COLOR.dY,args[2].." ",
COLOR.sky,args[3] COLOR.sky,args[3]
@@ -96,12 +81,6 @@ function scene.socketRead(mes)
LOG.print("Illegal message: "..mes,30,COLOR.green) LOG.print("Illegal message: "..mes,30,COLOR.green)
return return
end end
if scrollPos==#texts-1 then
scrollPos=scrollPos+1
else
SFX.play("spin_0",.8)
newMessage=true
end
end end
function scene.update(dt) function scene.update(dt)
@@ -116,31 +95,10 @@ function scene.draw()
gc.setColor(1,1,1) gc.setColor(1,1,1)
gc.printf(text.chatRemain,800,10,400,"right") gc.printf(text.chatRemain,800,10,400,"right")
gc.print(remain or"?",1205,10) gc.print(remain or"?",1205,10)
setFont(30)
for i=max(scrollPos-11,1),scrollPos do
gc.printf(texts[i],40,416-36*(scrollPos-i),1240)
end
--Slider
if #texts>12 then
gc.setLineWidth(2)
gc.rectangle("line",10,30,20,420)
local len=420*12/#texts
gc.rectangle("fill",13,33+(414-len)*(scrollPos-12)/(#texts-12),14,len)
end
--Draw
if newMessage and scrollPos~=#texts then
setFont(40)
gc.setColor(1,TIME()%.4<.2 and 1 or 0,0)
gc.print("v",8,480)
end
end end
scene.widgetList={ scene.widgetList={
WIDGET.newTextBox{name="text", x=40, y=500,w=980,h=180,font=40}, chatBox,
WIDGET.newButton{name="clear", x=1140, y=440,w=170,h=80,font=40,code=clearHistory,hide=function()return #texts<2 or newMessage end},
WIDGET.newButton{name="send", x=1140, y=540,w=170,h=80,font=40,code=sendMessage}, WIDGET.newButton{name="send", x=1140, y=540,w=170,h=80,font=40,code=sendMessage},
WIDGET.newButton{name="back", x=1140, y=640,w=170,h=80,font=40,code=backScene}, WIDGET.newButton{name="back", x=1140, y=640,w=170,h=80,font=40,code=backScene},
} }