3--! hide empty description
5--! state 2 as
"credits"
6--! state 3 as
"game_spawn"
7--! state 4 as
"game_play"
8--! state 5 as
"game_player_dead"
9--! state 6 as
"game_player_win"
10--! state 7 as
"game_over"
30local function draw_logo(
std,
game, height, anim)
32 std.draw.font(
'sans', 32)
33 std.draw.color(
std.color.white)
34 local s1 =
std.draw.text(
'AsteroidsTv')
35 local s2 =
std.draw.text(
'Tv')
36 std.draw.text(
game.width/2 - s1/2, height + anim,
'Asteroids')
37 std.draw.color(
std.color.red)
38 std.draw.text(
game.width/2 + s1/2 - s2, height - anim,
'Tv')
42local function intersect_line_circle(x1, y1, x2, y2, h, k, raio)
43 local m = (y2 - y1) / (x2 - x1)
46 local B = 2 * (m * c - m * k - h)
47 local C = h^2 + k^2 + c^2 - 2 * c * k - raio^2
48 local discriminante = B^2 - 4 * A * C
49 return discriminante >= 0
52local function asteroid_fragments(
game, size, level)
54 if size ==
game.asteroid_small_mini then
return 0, -1, 50 end
55 if size ==
game.asteroid_small_size and level <=3 then
return 0, -1, 15 end
56 if size ==
game.asteroid_mid_size and level <= 3 then
return 2,
game.asteroid_small_size, 10 end
57 if size ==
game.asteroid_large_size and level <= 3 then
return 1,
game.asteroid_mid_size, 5 end
59 if size ==
game.asteroid_small_size and level <= 6 then
return 1,
game.asteroid_mini_size, 20 end
60 if size ==
game.asteroid_mid_size and level <= 6 then
return 2,
game.asteroid_small_size, 15 end
61 if size ==
game.asteroid_large_size and level <= 6 then
return 1,
game.asteroid_mid_size, 10 end
63 if size ==
game.asteroid_small_size and level <= 9 then
return 1,
game.asteroid_mini_size, 25 end
64 if size ==
game.asteroid_mid_size and level <= 9 then
return 3,
game.asteroid_small_size, 20 end
65 if size ==
game.asteroid_large_size and level <= 9 then
return 1,
game.asteroid_mid_size, 15 end
66 -- level 10... all asteroids
67 if size ==
game.asteroid_small_size then
return 1,
game.asteroid_mini_size, 40 end
68 if size ==
game.asteroid_mid_size then
return 3,
game.asteroid_small_size, 30 end
69 if size ==
game.asteroid_large_size then
return 2,
game.asteroid_mid_size, 20 end
73local function asteroid_nest(
std,
game, x, y,
id)
75 while index < #
game.asteroid_size
do
76 if index ~=
id and
game.asteroid_size[index] ~= -1 then
77 local distance =
std.math.dis(x, y,
game.asteroid_pos_x[index],
game.asteroid_pos_y[index])
78 if (distance - 3) <= (
game.asteroid_size[index] / 2) then
87local function asteroids_rain(
std,
game)
90 local n1 = 0.5 *
std.math.min(
game.level/3, 1)
91 local n2 = 1.0 *
std.math.min(
game.level/3, 1)
92 local n3 = 2.0 *
std.math.min(
game.level/3, 1)
93 local n4 = 2.5 *
std.math.min(
game.level/3, 1)
94 local hspeed = {-n1, 0, 0, 0, 0, 0, n1}
95 local vspeed = {-n4, -n3, -n2, n2, n3, n4}
96 local middle_left =
game.width/4
97 local middle_right =
game.width/4 * 3
99 while index <=
game.asteroids_max and index <= 10
do
102 attemps = attemps + 1
103 game.asteroid_size[index] =
game.asteroid_large_size
104 game.asteroid_pos_x[index] =
std.math.random(1,
game.width)
105 game.asteroid_pos_y[index] =
std.math.random(1,
game.height)
106 game.asteroid_spd_x[index] = hspeed[
std.math.random(1, #hspeed)]
107 game.asteroid_spd_y[index] = vspeed[
std.math.random(1, #vspeed)]
109 if game.asteroid_pos_x[index] > middle_left and
game.asteroid_pos_x[index] < middle_right then
113 if asteroid_nest(
std,
game,
game.asteroid_pos_x[index],
game.asteroid_pos_x[index], index) then
117 if attemps > 100 then
125local function asteroid_destroy(
std,
game,
id)
127 local hspeed = {-1, 1}
128 local vspeed = {-2, -1, 1, 2}
129 local asteroids = #
game.asteroid_size
130 local original_size =
game.asteroid_size[id]
131 local fragments, size, score = asteroid_fragments(
game, original_size,
game.level)
133 game.asteroid_size[
id] = -1
135 while index <= fragments and (
game.asteroids_count + index) <= (
game.asteroids_max + 1) do
136 game.asteroid_size[asteroids + index] = size
137 game.asteroid_pos_x[asteroids + index] =
game.asteroid_pos_x[
id]
138 game.asteroid_pos_y[asteroids + index] =
game.asteroid_pos_y[
id]
139 game.asteroid_spd_x[asteroids + index] = hspeed[
std.
math.random(1,
#hspeed)] * std.math.min(game.level/5, 1)
140 game.asteroid_spd_y[asteroids + index] = vspeed[
std.math.random(1, #vspeed)] *
std.math.min(
game.level/5, 1)
152 game.asteroids_count = 0
159 game.highscore =
game.highscore or 0
160 game.asteroids_max =
game.asteroids_max or 60
161 game.graphics_fastest =
game.graphics_fastest or 0
165 game.player_spd_x = 0
166 game.player_spd_y = 0
167 game.player_angle = 0
168 game.player_last_teleport = 0
170 game.laser_enabled =
false
171 game.laser_pos_x1 = 0
172 game.laser_pos_y1 = 0
173 game.laser_pos_x2 = 0
174 game.laser_pos_y2 = 0
175 game.laser_last_fire = 0
176 game.laser_time_fire = 50
177 game.laser_time_recharge = 300
178 game.laser_distance_fire = 300
180 game.asteroid_pos_x = {}
181 game.asteroid_pos_y = {}
182 game.asteroid_spd_x = {}
183 game.asteroid_spd_y = {}
184 game.asteroid_size = {}
186 game.asteroid_large = {27, 0, 27, 15, 15, 12, 0, 30, 18, 39, 9, 48, 15, 60, 30, 66, 48, 66, 57, 57, 60, 51, 66, 42, 66, 33, 54, 12}
187 game.asteroid_mid = {6, 0, 0, 21, 9, 33, 9, 48, 24, 51, 36, 45, 48, 42, 36, 12, 48, 3, 18, 0}
188 game.asteroid_small = {3, 0, 0, 3, 3, 9, 3, 12, 0, 18, 6, 21, 12, 21, 18, 18, 21, 15, 21, 3, 12, 3, 9, 6}
189 game.asteroid_mini = {6, 0, 6, 6, 0, 6, 0, 12, 3, 18, 6, 18, 6, 15, 15, 15, 18, 9, 12, 6, 12, 0}
190 game.spaceship = {-2,3, 0,-2, 2,3}
192 game.asteroid_large_size =
std.math.max(
game.asteroid_large)
193 game.asteroid_mid_size =
std.math.max(
game.asteroid_mid)
194 game.asteroid_small_size =
std.math.max(
game.asteroid_small)
195 game.asteroid_mini_size =
std.math.max(
game.asteroid_mini)
204 if game.state == 1 then
205 local keyv =
std.key.press.down -
std.key.press.up
206 local keyh =
std.key.press.right -
std.key.press.left +
std.key.press.enter +
std.key.press.red
207 if keyv ~= 0 and
game.milis >
game.menu_time + 250 then
208 game.menu =
std.math.clamp(
game.menu + keyv,
game.player_pos_x == (
game.width/2) and 2 or 1, 8)
211 if keyh ~= 0 and
game.milis >
game.menu_time + 100 then
213 if game.menu == 1 then
215 elseif
game.menu == 2 then
219 elseif
game.menu == 3 then
220 game.level =
std.math.clamp2(
game.level + keyh, 1, 99)
221 elseif
game.menu == 4 then
222 game.imortal =
std.math.clamp(
game.imortal + keyh, 0, 1)
223 elseif
game.menu == 5 then
224 game.asteroids_max =
std.math.clamp2(
game.asteroids_max + keyh, 5, 60)
225 elseif
game.menu == 6 then
226 game.graphics_fastest =
std.math.clamp(
game.graphics_fastest + keyh, 0, 1)
228 elseif
game.menu == 7 then
230 elseif
game.menu == 8 then
235 elseif
game.state == 2 then
236 local key =
std.key.press.down +
std.key.press.up +
std.key.press.right +
std.key.press.left +
std.key.press.enter +
std.key.press.red
237 if key ~= 0 and
game.milis >
game.menu_time + 250 then
244 if std.key.press.green == 1 then
248 game.player_angle =
std.math.cycle(
game.player_angle + (
std.key.press.right -
std.key.press.left) * 0.1,
std.math.pi * 2) *
std.math.pi * 2
251 if std.key.press.up == 0 and (
std.math.abs(
game.player_spd_x) +
std.math.abs(
game.player_spd_y)) < 0.45 then
252 game.player_spd_x = 0
253 game.player_spd_y = 0
255 if std.key.press.up == 1 then
258 local max_spd_x =
std.math.abs(
game.speed_max *
std.math.cos(
game.player_angle -
std.math.pi/2))
259 local max_spd_y =
std.math.abs(
game.speed_max *
std.math.sin(
game.player_angle -
std.math.pi/2))
260 game.player_spd_x =
std.math.clamp(
game.player_spd_x, -max_spd_x, max_spd_x)
261 game.player_spd_y =
std.math.clamp(
game.player_spd_y, -max_spd_y, max_spd_y)
263 if game.player_pos_y < 3 then
266 if game.player_pos_x < 3 then
269 if game.player_pos_y >
game.height then
270 game.player_pos_y = 3
272 if game.player_pos_x >
game.width then
273 game.player_pos_x = 3
276 if std.key.press.down == 1 and
game.milis >
game.player_last_teleport + 1000 then
277 game.player_last_teleport =
game.milis
278 game.player_spd_x = 0
279 game.player_spd_y = 0
282 game.player_pos_y =
std.math.random(1,
game.height)
283 until not asteroid_nest(
std,
game,
game.player_pos_x,
game.player_pos_y, -1)
286 if not
game.laser_enabled and
game.state == 4 and (
std.key.press.red == 1 or
std.key.press.enter == 1) then
288 local asteroids = #
game.asteroid_size
289 local sin =
std.math.cos(
game.player_angle -
std.math.pi/2)
290 local cos =
std.math.sin(
game.player_angle -
std.math.pi/2)
291 local laser_fake_x =
game.player_pos_x - (
game.laser_distance_fire * sin * 2)
292 local laser_fake_y =
game.player_pos_y - (
game.laser_distance_fire * cos * 2)
293 game.laser_pos_x2 =
game.player_pos_x + (
game.laser_distance_fire * sin)
294 game.laser_pos_y2 =
game.player_pos_y + (
game.laser_distance_fire * cos)
295 game.laser_pos_x1 =
game.player_pos_x + (12 * sin)
296 game.laser_pos_y1 =
game.player_pos_y + (12 * cos)
298 game.laser_enabled =
true
299 while index <= asteroids
do
300 if game.asteroid_size[index] ~= -1 then
301 local size =
game.asteroid_size[index]/2
302 local x =
game.asteroid_pos_x[index] + size
303 local y =
game.asteroid_pos_y[index] + size
304 local dis_p1 =
std.math.dis(
game.laser_pos_x1,
game.laser_pos_y1, x,y)
305 local dis_p2 =
std.math.dis(
game.laser_pos_x2,
game.laser_pos_y2, x,y)
306 local dis_fake =
std.math.dis(laser_fake_x, laser_fake_y, x,y)
307 local intersect = intersect_line_circle(
game.laser_pos_x1,
game.laser_pos_y1,
game.laser_pos_x2,
game.laser_pos_y2, x, y, size*2)
308 if intersect and dis_p2 < dis_fake and dis_p1 <
game.laser_distance_fire then
315 if game.laser_enabled and
game.milis >
game.laser_last_fire +
game.laser_time_recharge then
316 game.laser_enabled =
false
319 if game.imortal ~= 1 and
game.state == 4 and asteroid_nest(
std,
game,
game.player_pos_x,
game.player_pos_y, -1) then
326 game.asteroids_count = 0
327 while index <= #
game.asteroid_size
do
328 if game.asteroid_size[index] ~= -1 then
329 game.asteroids_count =
game.asteroids_count + 1
330 game.asteroid_pos_x[index] =
game.asteroid_pos_x[index] +
game.asteroid_spd_x[index]
331 game.asteroid_pos_y[index] =
game.asteroid_pos_y[index] +
game.asteroid_spd_y[index]
332 if game.asteroid_pos_y[index] < 1 then
333 game.asteroid_pos_y[index] =
game.height
335 if game.asteroid_pos_x[index] < 1 then
336 game.asteroid_pos_x[index] =
game.width
338 if game.asteroid_pos_y[index] >
game.height then
339 game.asteroid_pos_y[index] = 1
341 if game.asteroid_pos_x[index] >
game.width then
342 game.asteroid_pos_x[index] = 1
348 if game.state == 4 and
game.asteroids_count == 0 then
352 if game.state == 6 and
game.milis >
game.menu_time + 3000 then
358 if game.state == 5 and
game.milis >
game.menu_time + 3000 then
361 if game.lifes == 0 then
370 std.draw.clear(
std.color.black)
372 if game.state == 1 then
374 local h =
game.height/16
375 local graphics =
game.graphics_fastest == 1 and
'rapido' or
'bonito'
376 local s = draw_logo(
std,
game, h*2)
377 std.draw.font(
'sans', 16)
378 std.draw.color(
std.color.white)
379 if game.player_pos_x ~= (
game.width/2) then
380 std.draw.text(
game.width/2 - s, h*6,
'Continuar')
382 std.draw.text(
game.width/2 - s, h*7,
'Novo Jogo')
383 std.draw.text(
game.width/2 - s, h*8,
'Dificuldade')
384 std.draw.text(
game.width/2 - s, h*9,
'Imortalidade')
385 std.draw.text(
game.width/2 - s, h*10,
'Limitador')
386 std.draw.text(
game.width/2 - s, h*11,
'Graficos')
387 std.draw.text(
game.width/2 - s, h*12,
'Creditos')
388 std.draw.text(
game.width/2 - s, h*13,
'Sair')
389 std.draw.line(
game.width/2 - s, (h*(5+
game.menu)) + 24,
game.width/2 + s, (h*(5+
game.menu)) + 24)
390 std.draw.color(
std.color.red)
392 std.draw.text(
game.width/2 + s - s2, h*8,
game.level)
394 std.draw.text(
game.width/2 + s - s2, h*9,
game.imortal)
395 s2=
std.draw.text(
game.asteroids_max)
396 std.draw.text(
game.width/2 + s - s2, h*10,
game.asteroids_max)
397 s2=
std.draw.text(graphics)
398 std.draw.text(
game.width/2 + s - s2, h*11, graphics)
400 elseif
game.state == 2 then
401 local height =
game.height/4
402 local w =
std.draw.text(
'Rodrigo Dornelles')
403 local anim =
std.math.cos(
std.math.cycle(
game.milis, 200) *
std.math.pi*2)
404 draw_logo(
std,
game, height, anim)
405 std.draw.font(
'sans', 16)
406 std.draw.color(
std.color.white)
407 std.draw.text(
game.width/2 - w/2 + (anim*0.5), height*2,
'Rodrigo Dornelles')
411 std.draw.color(
std.color.white)
413 while index <= #
game.asteroid_size
do
414 if game.asteroid_size[index] ~= -1 then
415 if game.graphics_fastest == 1 then
416 local s =
game.asteroid_size[index]
417 std.draw.rect(1,
game.asteroid_pos_x[index] - s/2,
game.asteroid_pos_y[index] - s/2, s, s)
418 elseif
game.asteroid_size[index] ==
game.asteroid_large_size then
419 std.draw.poly(1,
game.asteroid_large,
game.asteroid_pos_x[index],
game.asteroid_pos_y[index])
420 elseif
game.asteroid_size[index] ==
game.asteroid_mid_size then
421 std.draw.poly(1,
game.asteroid_mid,
game.asteroid_pos_x[index],
game.asteroid_pos_y[index])
422 elseif
game.asteroid_size[index] ==
game.asteroid_small_size then
423 std.draw.poly(1,
game.asteroid_small,
game.asteroid_pos_x[index],
game.asteroid_pos_y[index])
425 std.draw.poly(1,
game.asteroid_mini,
game.asteroid_pos_x[index],
game.asteroid_pos_y[index])
431 std.draw.color(
std.color.yellow)
432 if game.state ~= 5 then
433 std.draw.poly(2,
game.spaceship,
game.player_pos_x,
game.player_pos_y, 3,
game.player_angle)
436 if game.laser_enabled and
game.milis <
game.laser_last_fire +
game.laser_time_fire then
437 std.draw.color(
std.color.green)
441 local w =
game.width/16
442 std.draw.color(
std.color.black)
443 std.draw.rect(0, 0, 0,
game.width, 32)
444 std.draw.color(
std.color.white)
445 s=
std.draw.text(8, 8,
'lifes:')
446 std.draw.text(8+s, 8,
game.lifes)
447 s=
std.draw.text(w*2, 8,
'level:')
448 std.draw.text(w*2+s, 8,
game.level)
449 s=
std.draw.text(w*4, 8,
'asteroids:')
450 std.draw.text(w*4+s, 8,
game.asteroids_count)
451 s=
std.draw.text(w*9, 8,
'score:')
452 std.draw.text(w*9+s, 8,
game.score)
453 s=
std.draw.text(w*12, 8,
'highscore:')
454 std.draw.text(w*12+s, 8,
game.highscore)
459 game.asteroid_pos_x = nil
460 game.asteroid_pos_y = nil
461 game.asteroid_spd_x = nil
462 game.asteroid_spd_y = nil
463 game.asteroid_size = nil
464 game.asteroid_large = nil
465 game.asteroid_mid = nil
466 game.asteroid_small = nil
467 game.asteroid_mini = nil
473 author=
'RodrigoDornelles',
474 description=
'similar to the original but with lasers because televisions may have limited hardware.',
478 require =
'math random',
local function resume(self)
local function move(src_in, dist_path, dist_file)
local function require(std, game, application)
local function success(self, handler_func)
local function draw(std, game)
local function init(std, game)
local function exit(std, game)
local function loop(std, game)