2016-10-18 13:05:26 +02:00
|
|
|
-- LOAD
|
2016-10-17 23:41:41 +02:00
|
|
|
function love.load()
|
2016-10-18 13:05:26 +02:00
|
|
|
-- Configuration
|
2016-10-17 09:55:00 +02:00
|
|
|
math.randomseed(os.time())
|
2016-11-03 00:05:36 +01:00
|
|
|
width, height = love.window.getDesktopDimensions( display )
|
|
|
|
window = { width = width , height = height }
|
2016-10-18 23:46:06 +02:00
|
|
|
fullscreen = false
|
2016-11-03 00:05:36 +01:00
|
|
|
love.window.setMode(window.width, window.height, {resizable=true})
|
2016-10-27 22:41:44 +02:00
|
|
|
font_main = love.graphics.newFont('assets/font/main.ttf', 80) -- Font
|
|
|
|
love.graphics.setFont(font_main)
|
|
|
|
text_restart = { text = 'You die' }
|
|
|
|
text_restart.size = font_main:getWidth(text_restart.text)
|
2016-10-18 23:46:06 +02:00
|
|
|
text_good = { text = 'Good' }
|
2016-10-27 22:41:44 +02:00
|
|
|
text_good.size = font_main:getWidth(text_good.text)
|
2016-10-18 13:05:26 +02:00
|
|
|
camera = { x = 0, y = 0, width = window.width, height = window.height }
|
2016-10-18 23:46:06 +02:00
|
|
|
debug = false
|
2016-10-17 23:41:41 +02:00
|
|
|
play = true
|
|
|
|
win = false
|
2016-10-27 22:41:44 +02:00
|
|
|
level = { num = 1, x = 50, y = 50, max = 20 }
|
|
|
|
love.window.setFullscreen(fullscreen, 'exclusive')
|
2016-10-17 23:41:41 +02:00
|
|
|
love.window.setTitle('Alunizaje')
|
2016-10-27 22:41:44 +02:00
|
|
|
background = { x = 0, y = 0, img = love.graphics.newImage('assets/img/background.png') }
|
2016-11-03 00:05:36 +01:00
|
|
|
canvas = { width = width, height = 2880 }
|
2016-10-18 13:05:26 +02:00
|
|
|
gravity = 2
|
|
|
|
moon_margin = 100
|
|
|
|
-- Physics
|
|
|
|
love.physics.setMeter(64) -- Height earth in meters
|
|
|
|
world = love.physics.newWorld(0, gravity * 64, true) -- Make earth
|
|
|
|
-- Ship
|
2016-10-18 23:46:06 +02:00
|
|
|
ship = { x = canvas.width / 2, y = 0 , power = 1000 , size_collition = 28, polygons_collition = 8 }
|
2016-10-18 13:19:22 +02:00
|
|
|
ship.img = love.graphics.newImage('assets/img/ship.png')
|
2016-10-18 23:46:06 +02:00
|
|
|
ship.body = love.physics.newBody(world, (canvas.width / 2) - (ship.img:getWidth() / 2) , ship.y, 'dynamic')
|
2016-10-18 13:05:26 +02:00
|
|
|
ship.shape = love.physics.newCircleShape(20)
|
|
|
|
ship.fixture = love.physics.newFixture(ship.body, ship.shape, 1)
|
|
|
|
ship.fixture:setRestitution(0.9)
|
2016-10-27 22:41:44 +02:00
|
|
|
-- Fire
|
|
|
|
fire = {}
|
|
|
|
fire.img = love.graphics.newImage('assets/sprite/fire.png')
|
|
|
|
fire.num_frames = 4
|
|
|
|
fire.pos_frame = 0
|
|
|
|
fire.visible = false
|
|
|
|
fire.distance_ship = 10
|
|
|
|
fire.frame_width = fire.img:getWidth() / fire.num_frames
|
|
|
|
fire.frames = {
|
|
|
|
love.graphics.newQuad(fire.frame_width * 0, 0, fire.frame_width, fire.frame_width, fire.img:getWidth(), fire.img:getHeight()),
|
|
|
|
love.graphics.newQuad(fire.frame_width * 1, 0, fire.frame_width, fire.frame_width, fire.img:getWidth(), fire.img:getHeight()),
|
|
|
|
love.graphics.newQuad(fire.frame_width * 2, 0, fire.frame_width, fire.frame_width, fire.img:getWidth(), fire.img:getHeight()),
|
|
|
|
love.graphics.newQuad(fire.frame_width * 3, 0, fire.frame_width, fire.frame_width, fire.img:getWidth(), fire.img:getHeight())
|
|
|
|
}
|
|
|
|
-- Explosion
|
|
|
|
explosion = {}
|
|
|
|
explosion.img = love.graphics.newImage('assets/sprite/explosion.png')
|
|
|
|
explosion.num_frames = 11
|
|
|
|
explosion.pos_frame = 1
|
|
|
|
explosion.active = false
|
|
|
|
explosion.finish = false
|
|
|
|
explosion.time = 0
|
|
|
|
explosion.speed = 0.05
|
|
|
|
explosion.frame_width = explosion.img:getWidth() / explosion.num_frames
|
|
|
|
explosion.frame_height = explosion.img:getHeight()
|
|
|
|
explosion.frames = {
|
|
|
|
love.graphics.newQuad(explosion.frame_width * 0, 0, explosion.frame_width, explosion.frame_height, explosion.img:getWidth(), explosion.img:getHeight()),
|
|
|
|
love.graphics.newQuad(explosion.frame_width * 1, 0, explosion.frame_width, explosion.frame_height, explosion.img:getWidth(), explosion.img:getHeight()),
|
|
|
|
love.graphics.newQuad(explosion.frame_width * 2, 0, explosion.frame_width, explosion.frame_height, explosion.img:getWidth(), explosion.img:getHeight()),
|
|
|
|
love.graphics.newQuad(explosion.frame_width * 3, 0, explosion.frame_width, explosion.frame_height, explosion.img:getWidth(), explosion.img:getHeight()),
|
|
|
|
love.graphics.newQuad(explosion.frame_width * 4, 0, explosion.frame_width, explosion.frame_height, explosion.img:getWidth(), explosion.img:getHeight()),
|
|
|
|
love.graphics.newQuad(explosion.frame_width * 5, 0, explosion.frame_width, explosion.frame_height, explosion.img:getWidth(), explosion.img:getHeight()),
|
|
|
|
love.graphics.newQuad(explosion.frame_width * 6, 0, explosion.frame_width, explosion.frame_height, explosion.img:getWidth(), explosion.img:getHeight()),
|
|
|
|
love.graphics.newQuad(explosion.frame_width * 7, 0, explosion.frame_width, explosion.frame_height, explosion.img:getWidth(), explosion.img:getHeight()),
|
|
|
|
love.graphics.newQuad(explosion.frame_width * 8, 0, explosion.frame_width, explosion.frame_height, explosion.img:getWidth(), explosion.img:getHeight()),
|
|
|
|
love.graphics.newQuad(explosion.frame_width * 9, 0, explosion.frame_width, explosion.frame_height, explosion.img:getWidth(), explosion.img:getHeight()),
|
|
|
|
love.graphics.newQuad(explosion.frame_width * 10, 0, explosion.frame_width, explosion.frame_height, explosion.img:getWidth(), explosion.img:getHeight())
|
|
|
|
}
|
2016-10-18 13:05:26 +02:00
|
|
|
-- Generates initial asteroids
|
2016-10-18 16:56:32 +02:00
|
|
|
asteroids_collision = 40
|
|
|
|
asteroids_collision_polygon = 8
|
2016-10-18 13:05:26 +02:00
|
|
|
max_speed_asteroids = 5
|
2016-10-17 09:55:00 +02:00
|
|
|
img_asteroide = {
|
2016-10-18 13:05:26 +02:00
|
|
|
love.graphics.newImage('assets/img/asteroid1.png'),
|
2016-10-27 22:41:44 +02:00
|
|
|
love.graphics.newImage('assets/img/asteroid2.png'),
|
|
|
|
love.graphics.newImage('assets/img/asteroid3.png')
|
2016-10-17 09:55:00 +02:00
|
|
|
}
|
2016-10-27 22:41:44 +02:00
|
|
|
-- Audios
|
|
|
|
sounds = {}
|
|
|
|
sounds.die = love.audio.newSource('assets/audio/sound/die.wav', 'static')
|
|
|
|
sounds.explosion = love.audio.newSource('assets/audio/sound/explosion_bit.wav', 'static')
|
|
|
|
sounds.ambient_1 = love.audio.newSource('assets/audio/sound/ambient_1.wav')
|
|
|
|
sounds.complete = love.audio.newSource('assets/audio/sound/complete.wav')
|
|
|
|
sounds.fire = love.audio.newSource('assets/audio/sound/fire.wav', 'static')
|
|
|
|
sounds.ambient_1:setLooping(true)
|
|
|
|
sounds.ambient_1:play()
|
|
|
|
|
2016-10-18 23:46:06 +02:00
|
|
|
restart(level.num)
|
2016-10-17 09:55:00 +02:00
|
|
|
end
|
|
|
|
|
2016-10-18 13:05:26 +02:00
|
|
|
-- UPDATE
|
2016-10-17 09:55:00 +02:00
|
|
|
function love.update(dt)
|
2016-10-27 22:41:44 +02:00
|
|
|
-- Sprite
|
|
|
|
if not explosion.finish and explosion.active then -- Explosion
|
|
|
|
explosion.time = explosion.time + dt
|
|
|
|
if explosion.time > explosion.speed then
|
|
|
|
explosion.pos_frame = explosion.pos_frame + 1
|
|
|
|
explosion.time = 0
|
|
|
|
end
|
|
|
|
if explosion.pos_frame > explosion.num_frames then
|
|
|
|
sleep(1)
|
|
|
|
restart(level.num)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
-- Restart
|
|
|
|
if not explosion.active and not play then
|
|
|
|
sleep(3)
|
|
|
|
restart(level.num)
|
|
|
|
end
|
2016-10-17 23:41:41 +02:00
|
|
|
if play then
|
2016-10-18 13:05:26 +02:00
|
|
|
-- Phytics world
|
2016-10-17 23:41:41 +02:00
|
|
|
world:update(dt)
|
2016-10-27 22:41:44 +02:00
|
|
|
-- Sprite
|
|
|
|
fire.visible = false
|
|
|
|
if fire.pos_frame < fire.num_frames then -- Fire
|
|
|
|
fire.pos_frame = fire.pos_frame + 1
|
|
|
|
else
|
|
|
|
fire.pos_frame = 1
|
|
|
|
end
|
2016-10-18 13:05:26 +02:00
|
|
|
-- Controls
|
2016-11-04 00:02:10 +01:00
|
|
|
-- Keyboard
|
2016-10-18 13:05:26 +02:00
|
|
|
if love.keyboard.isDown('escape') or love.keyboard.isDown('q') then
|
2016-10-17 23:41:41 +02:00
|
|
|
love.event.push('quit')
|
|
|
|
end
|
2016-10-18 23:46:06 +02:00
|
|
|
if love.keyboard.isDown('right') then
|
2016-11-04 00:02:10 +01:00
|
|
|
ship.body:applyForce(ship.power, 0)
|
|
|
|
fire.visible = true
|
|
|
|
sounds.fire:play()
|
|
|
|
elseif love.keyboard.isDown('left') then
|
|
|
|
ship.body:applyForce(-ship.power, 0)
|
|
|
|
fire.visible = true
|
|
|
|
sounds.fire:play()
|
|
|
|
end
|
2016-10-18 23:46:06 +02:00
|
|
|
if love.keyboard.isDown('up') then
|
2016-11-04 00:02:10 +01:00
|
|
|
ship.body:applyForce(0, -ship.power)
|
|
|
|
fire.visible = true
|
|
|
|
sounds.fire:play()
|
|
|
|
end
|
|
|
|
-- Mouse
|
|
|
|
if love.mouse.isDown(1) then
|
|
|
|
local x, y = love.mouse.getPosition()
|
|
|
|
-- Up
|
|
|
|
if x > width / 3 and x < width - (width / 3) and y < height / 3 then
|
|
|
|
ship.body:applyForce(0, -ship.power)
|
|
|
|
fire.visible = true
|
|
|
|
sounds.fire:play()
|
|
|
|
end
|
|
|
|
-- Left
|
|
|
|
if x < width / 3 then
|
|
|
|
ship.body:applyForce(-ship.power, 0)
|
|
|
|
fire.visible = true
|
|
|
|
sounds.fire:play()
|
|
|
|
elseif x > width - (width / 3) then
|
|
|
|
ship.body:applyForce(ship.power, 0)
|
|
|
|
fire.visible = true
|
|
|
|
sounds.fire:play()
|
|
|
|
end
|
|
|
|
end
|
2016-10-18 13:05:26 +02:00
|
|
|
-- Rotate asteroids
|
|
|
|
for key, value in pairs(asteroids) do
|
|
|
|
value.angle = asteroids[key].angle + (dt * math.pi / 10)
|
|
|
|
value.x = asteroids[key].x - asteroids[key].speed
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
2016-10-18 13:05:26 +02:00
|
|
|
-- Destroy asteroids
|
|
|
|
for key, value in pairs(asteroids) do
|
|
|
|
if value.x + asteroids[key].img:getWidth() < 0 then
|
|
|
|
table.remove(asteroids, key)
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
2016-10-17 09:55:00 +02:00
|
|
|
end
|
2016-10-18 13:05:26 +02:00
|
|
|
-- Create asteroids
|
|
|
|
if table_length(asteroids) < num_asteroids then
|
2016-10-18 16:56:32 +02:00
|
|
|
local temp_img = img_asteroide[math.random(1, table_length(img_asteroide))]
|
2016-10-18 13:05:26 +02:00
|
|
|
asteroids[table_length(asteroids) + 1] = {
|
|
|
|
x = canvas.width + temp_img:getWidth(),
|
2016-11-03 00:05:36 +01:00
|
|
|
y = math.random(window.height / 2, canvas.height - temp_img:getHeight()),
|
2016-10-18 13:05:26 +02:00
|
|
|
speed = math.random(1, max_speed_asteroids),
|
2016-10-17 23:41:41 +02:00
|
|
|
img = temp_img,
|
|
|
|
angle = math.random(0, 90)}
|
|
|
|
end
|
|
|
|
|
2016-10-18 13:05:26 +02:00
|
|
|
-- Camera
|
|
|
|
camera.y = 0
|
2016-10-18 23:46:06 +02:00
|
|
|
if camera.height / 3 <= ship.body:getY() then -- Top
|
|
|
|
camera.y = -ship.body:getY() + (camera.height / 3)
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
2016-10-18 23:46:06 +02:00
|
|
|
if canvas.height - ((camera.height / 3) * 2) < ship.body:getY() then -- Down
|
2016-10-18 13:05:26 +02:00
|
|
|
camera.y = -canvas.height + camera.height
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
|
|
|
|
2016-10-18 13:05:26 +02:00
|
|
|
-- Collision
|
|
|
|
if ship.body:getY() <= 0 then -- Top game
|
|
|
|
x, y = ship.body:getLinearVelocity()
|
|
|
|
ship.body:setLinearVelocity(x, -y)
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
2016-10-18 13:05:26 +02:00
|
|
|
if ship.body:getX() + ship.img:getWidth() > canvas.width then -- Right game
|
|
|
|
x, y = ship.body:getLinearVelocity()
|
|
|
|
ship.body:setLinearVelocity(-x, y)
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
2016-10-18 13:05:26 +02:00
|
|
|
if ship.body:getX() < 0 then -- Left game
|
|
|
|
x, y = ship.body:getLinearVelocity()
|
|
|
|
ship.body:setLinearVelocity(-x, y)
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
2016-10-18 13:05:26 +02:00
|
|
|
if ship.body:getY() + ship.img:getHeight() + moon_margin >= canvas.height then -- Down game
|
|
|
|
ship.body:setLinearVelocity(0, 0)
|
2016-10-17 23:41:41 +02:00
|
|
|
win = true
|
|
|
|
play = false
|
2016-10-18 23:46:06 +02:00
|
|
|
level.num = level.num + 1
|
2016-10-27 22:41:44 +02:00
|
|
|
sounds.complete:play()
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
|
|
|
|
2016-10-18 13:05:26 +02:00
|
|
|
for key, value in pairs(asteroids) do -- Asteroids
|
2016-10-18 16:56:32 +02:00
|
|
|
local asteroid_temp = {
|
|
|
|
x = asteroids[key].x,
|
|
|
|
y = asteroids[key].y,
|
|
|
|
radius = asteroids_collision
|
|
|
|
}
|
|
|
|
local ship_temp = {
|
|
|
|
x = ship.body:getX() + (ship.img:getWidth() / 2),
|
|
|
|
y = ship.body:getY() + (ship.img:getHeight() / 2),
|
|
|
|
radius = ship.size_collition
|
|
|
|
}
|
|
|
|
if checkCircleCollision(asteroid_temp, ship_temp) then
|
2016-10-17 23:41:41 +02:00
|
|
|
play = false
|
2016-10-27 22:41:44 +02:00
|
|
|
sounds.die:play()
|
|
|
|
sounds.explosion:play()
|
|
|
|
explosion.active = true
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
|
|
|
end
|
2016-10-17 09:55:00 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-10-18 13:05:26 +02:00
|
|
|
-- DRAW
|
2016-10-17 09:55:00 +02:00
|
|
|
function love.draw()
|
2016-10-18 13:05:26 +02:00
|
|
|
-- Camera
|
|
|
|
love.graphics.translate(0, camera.y)
|
|
|
|
-- Background
|
2016-11-03 00:05:36 +01:00
|
|
|
love.graphics.draw(background.img, background.x, background.y, 0, 2, 1)
|
2016-10-27 22:41:44 +02:00
|
|
|
-- Ship
|
|
|
|
if not explosion.active then
|
|
|
|
love.graphics.draw(ship.img, ship.body:getX(), ship.body:getY())
|
|
|
|
if debug then
|
|
|
|
love.graphics.circle('line', ship.body:getX() + (ship.img:getWidth() / 2), ship.body:getY() + (ship.img:getHeight() / 2), ship.size_collition, ship.polygons_collition)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
-- Fire
|
|
|
|
if fire.visible and not explosion.active then
|
|
|
|
love.graphics.draw(fire.img, fire.frames[fire.pos_frame], ship.body:getX(), ship.body:getY() + ship.img:getHeight() + fire.distance_ship)
|
|
|
|
end
|
2016-10-18 13:05:26 +02:00
|
|
|
-- Asteroids
|
|
|
|
for key, value in pairs(asteroids) do
|
2016-10-17 09:55:00 +02:00
|
|
|
love.graphics.draw(value.img, value.x, value.y, value.angle, 1, 1, value.img:getWidth() / 2, value.img:getHeight() / 2)
|
2016-10-17 23:41:41 +02:00
|
|
|
if debug then
|
2016-10-18 23:46:06 +02:00
|
|
|
love.graphics.circle('line', value.x, value.y, asteroids_collision, ship.polygons_collition)
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
2016-10-17 09:55:00 +02:00
|
|
|
end
|
2016-10-27 22:41:44 +02:00
|
|
|
-- Explosion
|
|
|
|
if explosion.active then
|
|
|
|
love.graphics.draw(explosion.img, explosion.frames[explosion.pos_frame], ship.body:getX(), ship.body:getY() + ship.img:getHeight() / 2)
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
2016-10-18 13:05:26 +02:00
|
|
|
-- Texts
|
|
|
|
if not play and not win then -- Game over
|
2016-10-18 23:46:06 +02:00
|
|
|
love.graphics.print(text_restart.text, (camera.width / 2) - (text_restart.size / 2), -camera.y + (camera.height / 2))
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
2016-10-18 13:05:26 +02:00
|
|
|
if not play and win then -- Win
|
2016-10-18 23:46:06 +02:00
|
|
|
love.graphics.print(text_good, (camera.width / 2) - (text_good.size / 2), -camera.y + (camera.height / 2))
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|
2016-10-18 13:19:22 +02:00
|
|
|
love.graphics.print('Level ' .. level.num, level.x, level.y + -camera.y)
|
2016-10-18 13:05:26 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
--------------------------------- Functions
|
|
|
|
-- Get Table length
|
|
|
|
function table_length(T)
|
|
|
|
local count = 0
|
|
|
|
for _ in pairs(T) do count = count + 1 end
|
|
|
|
return count
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Pause system n seconds
|
|
|
|
local clock = os.clock
|
|
|
|
function sleep(n) -- seconds
|
|
|
|
local t0 = clock()
|
|
|
|
while clock() - t0 <= n do end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Collision detection function.
|
2016-10-18 16:56:32 +02:00
|
|
|
function checkCircleCollision(circle1, circle2)
|
|
|
|
local distance = math.sqrt((circle1.x - circle2.x) ^ 2 + (circle1.y - circle2.y) ^ 2)
|
|
|
|
return distance <= circle1.radius + circle2.radius
|
2016-10-18 23:46:06 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
function restart(level_arg)
|
|
|
|
num_asteroids = level_arg * 5
|
2016-10-27 22:41:44 +02:00
|
|
|
explosion.pos_frame = 1
|
|
|
|
explosion.active = false
|
2016-10-18 23:46:06 +02:00
|
|
|
-- Generate asteroids
|
|
|
|
asteroids = {}
|
|
|
|
for i=1, num_asteroids do
|
|
|
|
local temp_img = img_asteroide[math.random(1, table_length(img_asteroide))]
|
|
|
|
asteroids[i] = {
|
|
|
|
x = math.random(0, canvas.width - temp_img:getWidth()),
|
|
|
|
y = math.random(200, canvas.height - temp_img:getHeight()),
|
|
|
|
speed = math.random(1, max_speed_asteroids),
|
|
|
|
img = temp_img,
|
|
|
|
angle = math.random(0, 90)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
-- Set ship position
|
|
|
|
ship.body = love.physics.newBody(world, (canvas.width / 2) - (ship.img:getWidth() / 2) , ship.y, 'dynamic')
|
|
|
|
win = false
|
|
|
|
play = true
|
2016-10-27 22:41:44 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
-- Controls
|
|
|
|
function love.keyreleased(key)
|
|
|
|
sounds.fire:stop()
|
2016-11-04 00:02:10 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
function love.mousereleased(key)
|
|
|
|
sounds.fire:stop()
|
2016-10-17 23:41:41 +02:00
|
|
|
end
|