1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
--[[
Gamestates/Multiplayer/InGame.lua
Multiplayer mode
by piernov
]]--
local GUI = { InGame = require("GUI/InGame")}
local Game = require("Gamestates/Game")
local Protocol = require("Gamestates/Multiplayer/Protocol")
local InGame = {}
function InGame:enter(Local) -- Initialize or reset variables when entering game
Previous = "Gamestates/Multiplayer/Local"
InGame.Keypressed = {{}} -- 2D array for storage of button pressed
InGame.Hints = {} -- Hints displayed for local player
InGame.opponentHints = {} -- Hints displayed for remote player
InGame.state = "playing" -- Default to "playing" but it doesn't mean anything
InGame.localLife = {}
InGame.remoteLife = {}
InGame.host = Local.host
InGame.client = Local.client
InGame.opponentAnswer = Game.genAnswer() -- Generate answer for the opponent
for o = 0, 9 do
table.insert(InGame.remoteLife, { Type = "line", LineWidth = 0.015, Position = { x1 = 0.135, y1 = 0.61+0.02*o, x2 = 0.185, y2 = 0.61+0.02*o}, Colors = {171, 0, 0, 255} }) -- Display life bar content
end
for o = 0, 9 do
table.insert(InGame.localLife, { Type = "line", LineWidth = 0.022, Position = { x1 = 0.535+0.0275*o, y1 = 0.66, x2 = 0.535+0.0275*o, y2 = 0.71}, Colors = {171, 0, 0, 255} }) -- Display life bar content
end
InGame:resize() -- Call the function filling the canvas
InGame.Musiclowlife = love.audio.newSource("Resources/BlueMind midlife.ogg")
InGame.Music = Menu.Music
InGame.Music:setLooping(true)
if Config.Mute == false then
InGame.Music:rewind()
end
end
function InGame:resize() -- Called in :enter() and when the window is resized
InGame.Display = love.graphics.newCanvas(Screen.width, Screen.height) -- Create the canvas containing base interface to avoid drawing it entirely each frame
love.graphics.setCanvas(InGame.Display)
love.graphics.setFont(Fonts[3]) -- Use font with size 3% by default
InGame.Display:clear()
for id, polygon in ipairs(GUI.InGame.Polygons) do
GUI.InGame.drawPolygon(polygon)
end
love.graphics.setCanvas()
end
function InGame:init(host, client)
Game.init()
GUI.InGame.loadInterface()
GUI.InGame.loadMultiplayerInterface()
end
function InGame:draw()
love.graphics.setColor(255, 255, 255, 255)
love.graphics.setBlendMode('premultiplied')
love.graphics.draw(InGame.Display)
love.graphics.setBlendMode('alpha')
for num, line in ipairs(InGame.Hints) do
for k, poly in ipairs(line) do
GUI.InGame.drawPolygon(poly)
end
end
for line, keys in ipairs(InGame.Keypressed) do
for id, num in ipairs(keys) do
GUI.InGame.drawPolygon({ Type = "rectangle", DrawMode = "fill", Position = { x = 0.50+(id-1)*0.075, y = 0.15+(line-1)*0.075-0.025}, Dimension = {width = 0.04, height = 0.04}, Colors = GUI.InGame.Colors[num] })
end
end
for num, poly in ipairs(InGame.localLife) do
GUI.InGame.drawPolygon(poly)
end
for num, poly in ipairs(InGame.remoteLife) do
GUI.InGame.drawPolygon(poly)
end
for id, num in ipairs(InGame.opponentAnswer) do
GUI.InGame.drawPolygon({ Type = "rectangle", DrawMode = "fill", Position = { x = 0.08+(id-1)*0.075+0.005, y = 0.12+0.005}, Dimension = {width = 0.035, height = 0.04}, Colors = GUI.InGame.Colors[num] }) -- Top left boxes content displaying opponent answer
end
-- Display popup for win/loose and found answer
if InGame.state == "found" then
GUI.InGame.displayPopup("Found !")
elseif InGame.state == "not-found" then
GUI.InGame.displayPopup("Not found...")
elseif InGame.state == "win" then
GUI.InGame.displayPopup("You win !")
elseif InGame.state == "loose" then
GUI.InGame.displayPopup("You loose...")
end
-- End
GUI.InGame.drawPolygon({ Type = "print", Text = InGame.client.name, Position = { x = 0.15, y = 0.06}, Colors = {0, 0, 171, 255} }) -- Display remote player's name
GUI.InGame.drawPolygon({ Type = "print", Text = Config.player_name.text, Position = { x = 0.60, y = 0.06}, Colors = {0, 0, 171, 255} }) -- Display local player's name
end
function InGame:update(dt)
local event = InGame.host:service()
while event ~= nil do -- Handle network events
Protocol.parseGlobalEvents(event)
if event.type == "receive" then
command, args = event.data:match("(.*): (.*)") -- Split received message : "<COMMAND>: <ARGS>"
if command == "ANSWER" then
local hints = table.concat(Game.checkKeys({args:match("(%d)(%d)(%d)(%d)")}, InGame.opponentAnswer)) -- Process received answers
if hints == "1111" then -- Only well-placed hints = answer found
event.peer:send("FOUND: TRUE", 0, "reliable")
table.remove(InGame.localLife, 1) -- Loss of 1 life point
if #InGame.localLife < 1 then -- Empty life
InGame.state = "loose"
else
if #InGame.localLife == 2 then
InGame.Music:stop()
InGame.Musiclowlife:setLooping(true)
InGame.Musiclowlife:play()
end
InGame.opponentAnswer = Game.genAnswer() -- Generate a new answer
InGame.opponentHints = {}
end
else
event.peer:send("HINTS: " .. hints, 0, "reliable")
end
elseif command == "FOUND" and args == "TRUE" then
table.remove(InGame.remoteLife, 1) -- Opponent loose 1 life point
if #InGame.remoteLife < 1 then -- Opponent's life is empty, we won
InGame.state = "win"
else
InGame.Keypressed = {{}}
InGame.Hints = {}
InGame.state = "found"
end
elseif command == "FOUND" and args == "FALSE" then
table.remove(InGame.remoteLife, 1) -- Opponent loose 1 life point
InGame.opponentAnswer = Game.genAnswer() -- Generate a new answer
InGame.opponentHints = {}
elseif command == "HINTS" then
table.insert(InGame.Hints, Game.addHints(args, #InGame.Keypressed))
InGame.Keypressed[#InGame.Keypressed+1] = {}
InGame.state = "playing"
if #InGame.Keypressed > 7 then
table.remove(InGame.localLife, 1) -- Loss of 1 life point
InGame.Keypressed = {{}}
InGame.Hints = {}
InGame.state = "not-found"
event.peer:send("FOUND: FALSE", 0, "reliable")
end
end
end
event = InGame.host:service() -- Process next event
end
end
function InGame:mousepressed(x, y, b) -- Handle mouse
if InGame.state == "found" or InGame.state == "not-found" then -- Click anywhere to hide the "found" popup message
InGame.state = "playing"
end
x = x/Screen.width -- relative coordinates
y = y/Screen.height
if 0.875 < y and y < 0.915 and InGame.state ~= "validating" then -- lower part of the screen, and don't do anything if we're waiting for hints from peer
if x > 0.45 then
for i = 0,5 do
if 0.50+i*0.075 < x and x < 0.50+i*0.075+0.04 then
if #InGame.Keypressed > 7 or #InGame.Keypressed[#InGame.Keypressed] >= 4 then -- Line already full
return
else
for k,v in pairs(InGame.Keypressed[#InGame.Keypressed]) do
if v == i+1 then
return -- Disallow multiple identical colors in same line
end
end
table.insert(InGame.Keypressed[#InGame.Keypressed], i+1) -- Click detected on a color-button
end
end
end
elseif 0.25 < x and x < 0.375 and #InGame.Keypressed <= 7 and #InGame.Keypressed[#InGame.Keypressed] == 4 then -- Clik on Ok button
local peer = InGame.host:get_peer(InGame.client.index)
InGame.state = "validating"
peer:send("ANSWER: " .. table.concat(InGame.Keypressed[#InGame.Keypressed]), 0, "reliable")
elseif #InGame.Keypressed <= 7 and 0.075 < x and x < 0.200 and #InGame.Keypressed[#InGame.Keypressed] > 0 then -- Click on reset button
InGame.Keypressed[#InGame.Keypressed] = {}
end
end
end
function InGame:leave()
InGame.Music:stop()
InGame.Musiclowlife:stop()
end
return InGame
|