新增聊天框控件,用于联网场景(未完成)
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -258,7 +258,6 @@ return{
|
|||||||
down="↓",
|
down="↓",
|
||||||
},
|
},
|
||||||
net_chat={
|
net_chat={
|
||||||
clear="Clear",
|
|
||||||
send="Send",
|
send="Send",
|
||||||
},
|
},
|
||||||
setting_game={
|
setting_game={
|
||||||
|
|||||||
@@ -236,7 +236,6 @@ return{
|
|||||||
down="↓",
|
down="↓",
|
||||||
},
|
},
|
||||||
net_chat={
|
net_chat={
|
||||||
-- clear="Clear",
|
|
||||||
-- send="Send",
|
-- send="Send",
|
||||||
},
|
},
|
||||||
setting_game={
|
setting_game={
|
||||||
|
|||||||
@@ -257,7 +257,6 @@ return{
|
|||||||
down="↓",
|
down="↓",
|
||||||
},
|
},
|
||||||
net_chat={
|
net_chat={
|
||||||
clear="Limpar",
|
|
||||||
send="Mandar",
|
send="Mandar",
|
||||||
},
|
},
|
||||||
setting_game={
|
setting_game={
|
||||||
|
|||||||
@@ -240,7 +240,6 @@ return{
|
|||||||
down="↓",
|
down="↓",
|
||||||
},
|
},
|
||||||
net_chat={
|
net_chat={
|
||||||
-- clear="Clear",
|
|
||||||
-- send="Send",
|
-- send="Send",
|
||||||
},
|
},
|
||||||
setting_game={
|
setting_game={
|
||||||
|
|||||||
@@ -261,7 +261,6 @@ return{
|
|||||||
down="↓",
|
down="↓",
|
||||||
},
|
},
|
||||||
net_chat={
|
net_chat={
|
||||||
clear="清空",
|
|
||||||
send="发送",
|
send="发送",
|
||||||
},
|
},
|
||||||
setting_game={
|
setting_game={
|
||||||
|
|||||||
@@ -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},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user