Support for custom menu backgrounds
[poca-love.git] / gameglitch.lua
blob44a2a85ffc9b20d305c315f9adace0db5b093d02
1 --[[
2 Game glitch is a part of POCA - a puzzle game
4 POCA is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This software is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>.
18 require('special')
20 gg = {
22 hijacked_love_functions = {
23 'update', 'draw', 'resize', 'mousepressed', 'keypressed'
27 draw = function() -- hijacked function
28 love.graphics.push()
29 love.graphics.translate(screen.w / 2 - 23 * gg.scale, 0)
30 -- BACKGROUND
31 love.graphics.clear(gg.bgr / 255, gg.bgg / 255, gg.bgb / 255)
32 -- decorations
33 love.graphics.setColor(1,1,1, 1)
34 for a = 0, 9 do
35 if gg.decos[a].show then
36 love.graphics.print(gg.decos[a].look, gg.decos[a].x, gg.decos[a].y)
37 end
38 end
39 -- FOREGROUND
40 -- stars and dots
41 for a = 0, #gg.stars, 4 do
42 love.graphics.setColor(1,1,1, gg.stars[a].alpha) -- alpha 1 if nil
43 for b = 0, 3 do
44 love.graphics.print('*',
45 gg.stars[a + b].x, gg.stars[a + b].y
47 end
48 for b = 0, 2, 2 do
49 love.graphics.print('.',
50 gg.dots[(a + b) / 2].x, gg.dots[(a + b) / 2].y - gg.dotdy
52 end
53 -- lines - visible only after frame 60
54 love.graphics.setColor(1,1,1,
55 (gg.stars[a].alpha or 1) * (math.min(gg.bb, 180) - 60) / 300
57 love.graphics.line(
58 gg.stars[a].x + gg.linedy, gg.stars[a].y + gg.linedy,
59 gg.stars[a + 1].x + gg.linedy, gg.stars[a + 1].y + gg.linedy,
60 gg.stars[a + 3].x + gg.linedy, gg.stars[a + 3].y + gg.linedy,
61 gg.stars[a + 2].x + gg.linedy, gg.stars[a + 2].y + gg.linedy,
62 gg.stars[a].x + gg.linedy, gg.stars[a].y + gg.linedy
65 -- lines connecting 2 steps
66 local step_height = 3 * gg.scale
67 love.graphics.line (
68 gg.stars[a].x + gg.linedy, gg.stars[a].y + gg.linedy,
69 gg.stars[a].x + gg.linedy, gg.stars[a].y + gg.linedy - step_height
71 love.graphics.line (
72 gg.stars[a + 2].x + gg.linedy, gg.stars[a + 2].y + gg.linedy,
73 gg.stars[a + 2].x + gg.linedy, gg.stars[a + 2].y + gg.linedy - step_height
76 end
77 love.graphics.pop()
78 end,
82 resize = function() -- hijacked function
83 resize_common()
84 love.graphics.setFont(screen.defaultfont)
85 end,
88 mousepressed = function(mx, my, button) -- hijacked function
89 -- no interaction intended
90 end,
93 keypressed = function(k) -- hijacked function
94 -- no interaction intended
95 end,
98 init = function(self)
99 end,
102 main = function(self)
103 hijack(self)
104 love.graphics.setFont(screen.defaultfont)
105 -- init
106 self.resize()
107 self.bb = 0 -- main timer
108 self.aa = 0
109 self.lastbb = 320
110 self.bgr = 128
111 self.bgg = 0
112 self.bgb = 128
113 self.speed = 25
114 self.scale = screen.tilesize / 8 -- math.floor(screen.h / 45)
115 self.offsetx = - (self.scale * 23 - screen.w) / 2
116 self.dotdy = screen.fontheight / 3.4
117 self.linedy = screen.fontheight / 2.7
118 self.steps = 15 -- math.floor(screen.h / 30)
119 -- falling decorations in background look like this
120 self.decos = {
121 [0] = { look = "." },
122 [1] = { look = "." },
123 [2] = { look = "." },
124 [3] = { look = ":" },
125 [4] = { look = "." },
126 [5] = { look = "." },
127 [6] = { look = "^" },
128 [7] = { look = "|" },
129 [8] = { look = ":" },
130 [9] = { look = "|" }
132 for a = 0, 9 do
133 self.decos[a].x = math.random(50 * self.scale)
134 self.decos[a].y = math.random(self.steps * 2 * self.scale)
136 -- last 3 decos fall faster, so shift them up
137 for a = 7, 9 do self.decos[a].y = self.decos[a].y /2 end
138 -- stars and dots are used in foreground
139 self.stars, self.dots = {}, {}
140 -- music
141 play_music('stairway', true)
142 gg.music_failed = (not current.music) or (not current.music:isPlaying())
143 -- important, as this is timed with music
144 end,
147 quit = function(self)
148 release(self)
149 love.resize()
150 change_screen('menu_objects')
151 end,
154 update = function(dt) -- hijacked function
155 -- BACKGROUND
156 -- fade bgcolor from purple to blue to black
157 if gg.bb > .15625 * gg.lastbb and gg.bb < .25625 * gg.lastbb then
158 gg.bgr = 128 - (gg.bb - .15625 * gg.lastbb) * 8
159 gg.bgg = 0
160 gg.bgb = 128
161 elseif gg.bb > .3125 * gg.lastbb and gg.bb < .4125 * gg.lastbb then
162 gg.bgr = 0
163 gg.bgg = 0
164 gg.bgb = 128 - (gg.bb - .3125 * gg.lastbb) * 4
166 -- turn decorations on
167 if math.random() > 0.01 then
168 gg.decos[math.random(0, 6)].show = true
170 -- turn decorations off and shift them randomly
171 if math.random() > 0.8 then
172 local a = math.random(0, 6)
173 gg.decos[a].show = false
174 gg.decos[a].x = math.random() * 50 * gg.scale
175 gg.decos[a].y = math.random() * gg.steps * 2 * gg.scale
177 -- turn on and off decrations with characters | : |
178 gg.decos[7].show = (gg.bb >= 53) and (gg.bb < 90)
179 gg.decos[8].show = (gg.bb >= 153) and (gg.bb < 190)
180 gg.decos[9].show = (gg.bb >= 103) and (gg.bb < 149)
181 -- make decorations drop
182 for a = 0, 6 do
183 if gg.decos[a].show then gg.decos[a].y = gg.decos[a].y + 1 end
185 -- make elongated decorations drop faster
186 for a = 7, 9 do
187 if gg.decos[a].show then gg.decos[a].y = gg.decos[a].y + 6 end
190 -- FOREGROUND
191 for step = 0, gg.steps - 1 do
192 -- rotate stars along a flattened circle
193 local as = gg.aa / gg.speed + step / 2
194 gg.stars[0 + step * 4] = {
195 x = math.sin(as - 1/4) * 15 * gg.scale,
196 y = math.cos(as - 1/4) * 2 * gg.scale
198 gg.stars[1 + step * 4] = {
199 x = math.sin(as + 1/4) * 15 * gg.scale,
200 y = math.cos(as + 1/4) * 2 * gg.scale
202 gg.stars[2 + step * 4] = {
203 x = math.sin(as - 1/4) * 5 * gg.scale,
204 y = math.cos(as - 1/4) * 2/3 * gg.scale
206 gg.stars[3 + step * 4] = {
207 x = math.sin(as + 1/4) * 5 * gg.scale,
208 y = math.cos(as + 1/4) * 2/3 * gg.scale
210 -- place dots between some of the stars
211 for a = 0, 1 do
212 gg.dots[a + step * 2] = {
213 x = (gg.stars[a + step * 4].x + gg.stars[a + 2 + step * 4].x) / 2,
214 y = (gg.stars[a + step * 4].y + gg.stars[a + 2 + step * 4].y) / 2,
218 -- stretch and center the whole thing
219 for step = 0, gg.steps - 1 do
220 for a = step * 4, step * 4 + 3 do
221 gg.stars[a].x = gg.stars[a].x + 23 * gg.scale
222 gg.stars[a].y = gg.stars[a].y + 3 * gg.scale * (step +
223 gg.aa * 2 / gg.speed - 1)
225 for a = step * 2, step * 2 + 1 do
226 gg.dots[a].x = gg.dots[a].x + 23 * gg.scale
227 gg.dots[a].y = gg.dots[a].y - 3 + 3 * gg.scale * (step +
228 gg.aa * 2 / gg.speed - 1)
232 -- fade ends
233 for a = 0, gg.steps * 4 - 1 do
234 -- gg.aa goes from 0 to gg.speed / 2
235 if a > gg.steps * 4 - 5 then -- fade last step into bgr bgg bgb
236 gg.stars[a].alpha = 1 - gg.aa / (gg.speed / 2)
237 elseif a < 4 then -- fade first step
238 gg.stars[a].alpha = gg.aa / (gg.speed / 2)
242 -- update timers
243 gg.aa = (gg.aa + 1) % (gg.speed / 2)
244 gg.bb = gg.bb + 1
246 -- exit when done
247 if (settings.music and (not gg.music_failed) and (not current.music:isPlaying())) or gg.bb > gg.lastbb then
248 gg:quit()
251 -- wait
252 love.timer.sleep(.15)
253 end,
256 } -- end of gg