|
@@ -2,7 +2,7 @@
|
|
|
|
|
|
Game logic for Thrust II Reloaded.
|
|
Game logic for Thrust II Reloaded.
|
|
|
|
|
|
-Copyright © 2015-2017 Pedro Gimeno Fortea
|
|
|
|
|
|
+Copyright © 2015-2018 Pedro Gimeno Fortea
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -26,7 +26,8 @@ SOFTWARE.
|
|
|
|
|
|
local game = {}
|
|
local game = {}
|
|
|
|
|
|
-local json = require "3rdparty.dkjson"
|
|
|
|
|
|
+local la,le,lfs,lf,lg,li,lj,lk,lm,lmo,lp,ls,lsys,lth,lt,lw = require'ns'()
|
|
|
|
+local json = require '3rdparty.dkjson'
|
|
|
|
|
|
local garbagetimer = 0
|
|
local garbagetimer = 0
|
|
local collision_canvas, no_collision
|
|
local collision_canvas, no_collision
|
|
@@ -63,6 +64,7 @@ local total_shoot_time = 4
|
|
local latchsnd, orbdangersnd, crashsnd, cablesnd, enemykillsnd
|
|
local latchsnd, orbdangersnd, crashsnd, cablesnd, enemykillsnd
|
|
local getagentsnd, shootsnd, orbpickupsnd, orbdropsnd, thrustsnd, music
|
|
local getagentsnd, shootsnd, orbpickupsnd, orbdropsnd, thrustsnd, music
|
|
|
|
|
|
|
|
+local DIV = love_version >= 11000000 and 255 or 1
|
|
|
|
|
|
function game.load()
|
|
function game.load()
|
|
-- Game viewport
|
|
-- Game viewport
|
|
@@ -107,7 +109,7 @@ function game.load()
|
|
-- in the next rows until completing that height is empty.
|
|
-- in the next rows until completing that height is empty.
|
|
-- E.g. if X is 32x32 (1x1 cells) and Y is 64x64 (2x2 cells):
|
|
-- E.g. if X is 32x32 (1x1 cells) and Y is 64x64 (2x2 cells):
|
|
-- X YY YY X X correct
|
|
-- X YY YY X X correct
|
|
- -- YY YY
|
|
|
|
|
|
+ -- YY YY
|
|
--
|
|
--
|
|
-- X YY YY X X incorrect - don't reuse the empty spaces
|
|
-- X YY YY X X incorrect - don't reuse the empty spaces
|
|
-- X YY YY (our algorithm isn't that clever)
|
|
-- X YY YY (our algorithm isn't that clever)
|
|
@@ -183,9 +185,13 @@ function game.load()
|
|
-- Crash sound
|
|
-- Crash sound
|
|
crashsnd = la.newSource("snd/Grenade-SoundBible.com-1777900486.ogg", "static")
|
|
crashsnd = la.newSource("snd/Grenade-SoundBible.com-1777900486.ogg", "static")
|
|
-- Enemy killed
|
|
-- Enemy killed
|
|
- enemykillsnd = la.newSource("snd/supertank_plazma_fireball_22khz.mp3")
|
|
|
|
- -- Make it a table so we can play two at the same time
|
|
|
|
- enemykillsnd = { enemykillsnd, enemykillsnd:clone() }
|
|
|
|
|
|
+ enemykillsnd = la.newSource("snd/supertank_plazma_fireball_22khz.mp3", "static")
|
|
|
|
+ -- Make a duplicate so we can ply two at the same time
|
|
|
|
+ -- Only 0.9.1+ has Source:clone(); 0.9.0 needs to load a new instance.
|
|
|
|
+ local enemykillsnd2 = enemykillsnd.clone and enemykillsnd:clone()
|
|
|
|
+ or la.newSource("snd/supertank_plazma_fireball_22khz.mp3", "static")
|
|
|
|
+ -- Turn it into a table
|
|
|
|
+ enemykillsnd = { enemykillsnd, enemykillsnd2 }
|
|
-- Cable extend/retract sound
|
|
-- Cable extend/retract sound
|
|
cablesnd = la.newSource("snd/Cable_Sound.wav", "static")
|
|
cablesnd = la.newSource("snd/Cable_Sound.wav", "static")
|
|
-- Music
|
|
-- Music
|
|
@@ -209,6 +215,8 @@ function game.activate()
|
|
music:play()
|
|
music:play()
|
|
end
|
|
end
|
|
thrustvol = 0
|
|
thrustvol = 0
|
|
|
|
+ thrustsnd:setVolume(0)
|
|
|
|
+ thrustsnd:play()
|
|
end
|
|
end
|
|
|
|
|
|
function game.deactivate()
|
|
function game.deactivate()
|
|
@@ -221,6 +229,8 @@ function game.pause(pause)
|
|
if pause then
|
|
if pause then
|
|
orbdangersnd:stop()
|
|
orbdangersnd:stop()
|
|
music:pause()
|
|
music:pause()
|
|
|
|
+ thrustsnd:setVolume(0)
|
|
|
|
+ thrustvol = 0
|
|
else
|
|
else
|
|
if cable.m ~= 0 then
|
|
if cable.m ~= 0 then
|
|
orbdangersnd:play()
|
|
orbdangersnd:play()
|
|
@@ -228,6 +238,11 @@ function game.pause(pause)
|
|
if main.music then
|
|
if main.music then
|
|
music:play()
|
|
music:play()
|
|
end
|
|
end
|
|
|
|
+ thrusting = lk.isDown(keys.thrust)
|
|
|
|
+ if thrusting then
|
|
|
|
+ thrustsnd:setVolume(1)
|
|
|
|
+ thrustvol = 1
|
|
|
|
+ end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
@@ -235,7 +250,7 @@ end
|
|
local function new_or_load_game(load)
|
|
local function new_or_load_game(load)
|
|
-- restore saved game or start new game
|
|
-- restore saved game or start new game
|
|
|
|
|
|
- if load and lfs.isFile("saved.txt") then
|
|
|
|
|
|
+ if load and main.isFile("saved.txt") then
|
|
local f, s = lfs.read("saved.txt")
|
|
local f, s = lfs.read("saved.txt")
|
|
local tmp, err
|
|
local tmp, err
|
|
game.state, tmp, err = json.decode(f, 1, json.null, nil)
|
|
game.state, tmp, err = json.decode(f, 1, json.null, nil)
|
|
@@ -372,11 +387,6 @@ local function update_ship(dt)
|
|
local was_thrusting = thrusting
|
|
local was_thrusting = thrusting
|
|
thrusting = lk.isDown(keys.thrust)
|
|
thrusting = lk.isDown(keys.thrust)
|
|
if thrusting then
|
|
if thrusting then
|
|
- if not was_thrusting then
|
|
|
|
- thrustsnd:seek(love.math.random()*15, "seconds")
|
|
|
|
- end
|
|
|
|
- thrustsnd:setVolume(0.5)
|
|
|
|
- thrustsnd:play()
|
|
|
|
thrustsnd:setVolume(1)
|
|
thrustsnd:setVolume(1)
|
|
thrustvol = 1
|
|
thrustvol = 1
|
|
shipforcex = shipforcex + math.sin(fineangle*math.pi/16) * thrust
|
|
shipforcex = shipforcex + math.sin(fineangle*math.pi/16) * thrust
|
|
@@ -535,13 +545,13 @@ local function collided()
|
|
end
|
|
end
|
|
|
|
|
|
-- Draw ship/orb in multiplicative mode
|
|
-- Draw ship/orb in multiplicative mode
|
|
- if love._version_major == 0 and love._version_minor < 10 then
|
|
|
|
|
|
+ if love_version < 0010000 then
|
|
lg.setBlendMode("multiplicative")
|
|
lg.setBlendMode("multiplicative")
|
|
else
|
|
else
|
|
- lg.setBlendMode("multiply")
|
|
|
|
|
|
+ lg.setBlendMode("multiply", "premultiplied")
|
|
end
|
|
end
|
|
lg.draw(spritecoll, spritequads[i == 0 and ship.angle+1 or orb_sprite], 0, i)
|
|
lg.draw(spritecoll, spritequads[i == 0 and ship.angle+1 or orb_sprite], 0, i)
|
|
- lg.setBlendMode("alpha") -- return blend mode to normal
|
|
|
|
|
|
+ lg.setBlendMode("alpha", "alphamultiply") -- return blend mode to normal
|
|
end
|
|
end
|
|
|
|
|
|
lg.setScissor()
|
|
lg.setScissor()
|
|
@@ -747,6 +757,7 @@ function game.update(dt)
|
|
and cable.y >= tgt.y*32 and cable.y < tgt.y*32+32
|
|
and cable.y >= tgt.y*32 and cable.y < tgt.y*32+32
|
|
then
|
|
then
|
|
orbdropsnd:play()
|
|
orbdropsnd:play()
|
|
|
|
+ counters.score = counters.score + counters.orbtimer * 10
|
|
cable.m = 0
|
|
cable.m = 0
|
|
map[tgt.y*128+tgt.x+1] = tgt.tile
|
|
map[tgt.y*128+tgt.x+1] = tgt.tile
|
|
tgt_index = tgt_index - 1
|
|
tgt_index = tgt_index - 1
|
|
@@ -854,6 +865,7 @@ function game.update(dt)
|
|
y1 = y1*y1
|
|
y1 = y1*y1
|
|
if x1 + y1 < radius2 then
|
|
if x1 + y1 < radius2 then
|
|
-- Killed enemy
|
|
-- Killed enemy
|
|
|
|
+ counters.score = counters.score + counters.agenttime * 10
|
|
enemies[k].f = 1 -- explosion frame
|
|
enemies[k].f = 1 -- explosion frame
|
|
enemies[k].t = 0 -- timer to advance frame
|
|
enemies[k].t = 0 -- timer to advance frame
|
|
game.state.dyingenemies[#game.state.dyingenemies + 1] = enemies[k]
|
|
game.state.dyingenemies[#game.state.dyingenemies + 1] = enemies[k]
|
|
@@ -1087,11 +1099,11 @@ function game.draw()
|
|
local freq = .01/(1.01-orbtime*0.0032)
|
|
local freq = .01/(1.01-orbtime*0.0032)
|
|
if freq > 10 then freq = 10 end
|
|
if freq > 10 then freq = 10 end
|
|
local amp = (1-math.cos(freq*orbtime))*freq*0.5
|
|
local amp = (1-math.cos(freq*orbtime))*freq*0.5
|
|
- lg.setColor(255,255,255, amp^0.7*255)
|
|
|
|
|
|
+ lg.setColor(255/DIV,255/DIV,255/DIV, amp^0.7*(255/DIV))
|
|
orbdangersnd:setVolume(amp^2)
|
|
orbdangersnd:setVolume(amp^2)
|
|
lg.draw(spriteset, spritequads[orb_sprite+1], orbx, orby)
|
|
lg.draw(spriteset, spritequads[orb_sprite+1], orbx, orby)
|
|
- lg.setColor(255,255,255,255)
|
|
|
|
- lg.setBlendMode("alpha")
|
|
|
|
|
|
+ lg.setColor(255/DIV,255/DIV,255/DIV,255/DIV)
|
|
|
|
+ lg.setBlendMode("alpha", "alphamultiply")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
@@ -1106,13 +1118,13 @@ function game.draw()
|
|
|
|
|
|
-- HACK: draw target in multiplicative mode (colorizes other sprites)
|
|
-- HACK: draw target in multiplicative mode (colorizes other sprites)
|
|
if tgt then
|
|
if tgt then
|
|
- if love._version_major == 0 and love._version_minor < 10 then
|
|
|
|
|
|
+ if love_version < 0010000 then
|
|
lg.setBlendMode("multiplicative")
|
|
lg.setBlendMode("multiplicative")
|
|
else
|
|
else
|
|
- lg.setBlendMode("multiply")
|
|
|
|
|
|
+ lg.setBlendMode("multiply", "premultiplied")
|
|
end
|
|
end
|
|
lg.draw(tileset, tilequads[tgt_tile_current], tgt.x*32-vpx, tgt.y*32-vpy)
|
|
lg.draw(tileset, tilequads[tgt_tile_current], tgt.x*32-vpx, tgt.y*32-vpy)
|
|
- lg.setBlendMode("alpha")
|
|
|
|
|
|
+ lg.setBlendMode("alpha", "alphamultiply")
|
|
end
|
|
end
|
|
|
|
|
|
-- draw shooting explosion
|
|
-- draw shooting explosion
|
|
@@ -1124,12 +1136,12 @@ function game.draw()
|
|
red = 255
|
|
red = 255
|
|
green = 255*t^1.5
|
|
green = 255*t^1.5
|
|
blue = 255*t^6
|
|
blue = 255*t^6
|
|
- lg.setColor(red, green, blue, 255*(counters.shoot_timer/total_shoot_time))
|
|
|
|
|
|
+ lg.setColor(red/DIV, green/DIV, blue/DIV, 255/DIV*(counters.shoot_timer/total_shoot_time))
|
|
local drawx = counters.shoot_x - vpx
|
|
local drawx = counters.shoot_x - vpx
|
|
if drawx < -2048 then drawx = drawx + 4096 end
|
|
if drawx < -2048 then drawx = drawx + 4096 end
|
|
if drawx > 2048 then drawx = drawx - 4096 end
|
|
if drawx > 2048 then drawx = drawx - 4096 end
|
|
lg.draw(shotimg, drawx, counters.shoot_y-vpy, 0, shoot_radius/256, shoot_radius/256, 256, 256)
|
|
lg.draw(shotimg, drawx, counters.shoot_y-vpy, 0, shoot_radius/256, shoot_radius/256, 256, 256)
|
|
- lg.setColor(255, 255, 255, 255)
|
|
|
|
|
|
+ lg.setColor(255/DIV, 255/DIV, 255/DIV, 255/DIV)
|
|
end
|
|
end
|
|
|
|
|
|
-- FIXME: draw current agent
|
|
-- FIXME: draw current agent
|
|
@@ -1138,6 +1150,13 @@ function game.draw()
|
|
if v == counters.agent then
|
|
if v == counters.agent then
|
|
lg.draw(tileset, tilequads[k], 0, main.wh-32)
|
|
lg.draw(tileset, tilequads[k], 0, main.wh-32)
|
|
lg.print(counters.agenttime, 35, main.wh-24)
|
|
lg.print(counters.agenttime, 35, main.wh-24)
|
|
|
|
+ local num = 0
|
|
|
|
+ for i = 1, #game.state.enemies do
|
|
|
|
+ if game.state.enemies[i].type == counters.agent then
|
|
|
|
+ num = num + 1
|
|
|
|
+ end
|
|
|
|
+ end
|
|
|
|
+ lg.print(num, 10, main.wh-48)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
@@ -1148,6 +1167,7 @@ function game.draw()
|
|
if counters.orbtimer then
|
|
if counters.orbtimer then
|
|
lg.print(string.format("%03d", counters.orbtimer), 144, main.wh-24)
|
|
lg.print(string.format("%03d", counters.orbtimer), 144, main.wh-24)
|
|
end
|
|
end
|
|
|
|
+ lg.print(string.format("%8d", counters.score), 160, main.wh - 24)
|
|
|
|
|
|
lg.setScissor()
|
|
lg.setScissor()
|
|
|
|
|
|
@@ -1155,25 +1175,23 @@ function game.draw()
|
|
--[[ debug
|
|
--[[ debug
|
|
lg.print(game.DEBUG, 0, 0)
|
|
lg.print(game.DEBUG, 0, 0)
|
|
-- draw collision canvas
|
|
-- draw collision canvas
|
|
- lg.setColor(100,100,100)
|
|
|
|
|
|
+ lg.setColor(100/DIV,100/DIV,100/DIV)
|
|
lg.rectangle("fill", 100, 100, 32, 64)
|
|
lg.rectangle("fill", 100, 100, 32, 64)
|
|
- lg.setColor(255,255,255)
|
|
|
|
|
|
+ lg.setColor(255/DIV,255/DIV,255/DIV)
|
|
lg.draw(collision_canvas, 100, 100)
|
|
lg.draw(collision_canvas, 100, 100)
|
|
]]
|
|
]]
|
|
end
|
|
end
|
|
|
|
|
|
function game.keypressed(k, r)
|
|
function game.keypressed(k, r)
|
|
if r then return end
|
|
if r then return end
|
|
- if k == "pause" and (lk.isDown("lctrl") or lk.isDown("rctrl") or lk.isDown("ctrl")) then
|
|
|
|
- main.activate(screens.menu)
|
|
|
|
- return
|
|
|
|
|
|
+ if k == "escape" then
|
|
|
|
+ return main.dialog("EXIT TO MENU?", main.tomenu)
|
|
end
|
|
end
|
|
if k == "f10" then game.savegame() end
|
|
if k == "f10" then game.savegame() end
|
|
if k == "f3" then
|
|
if k == "f3" then
|
|
new_or_load_game(true)
|
|
new_or_load_game(true)
|
|
screens.getready.fromstart = false
|
|
screens.getready.fromstart = false
|
|
- main.activate(screens.getready)
|
|
|
|
- return
|
|
|
|
|
|
+ return main.activate(screens.getready)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|