So I want to add at start that I haven't used Löve2D/Lua in some time. I haven't kept up with the new changes to Löve2D, so I'm a bit rusty & I'm not fully aware if there are any changes to the forums rules.
So to the question:
I have an OLD project which is my first game that I've made, I first posted about it to this forum in 2013 & I managed to find the old code again (see below).
I wanted to make it playable again to both reminisce but also maybe use it in my portfolio (undecided). So far, I've managed to get it to work, kinda. What I've managed so far is to make the game "draw" as it should & changed the old way of inputting RGB color values from 255's to 1's. I also had some audio files that I added "static" as the 2nd argument (as it's required in the newer version of Löve2D) but this game is missing a key mechanic.
This game is based on the arcade classic "Asteroids" & in this game, instead of shooting lasers, you created a "ship" trail behind you by pressing the space-bar. This is where my problem is, because I've been away from Lua/Löve2D for some time, I don't really now where the issue is & I was hoping to get a fresh pair of eyes on my old project who can point out any issues that this project has.
If there's anything I need to do to make it easier for you to help me, let me know ASAP & i'll see what I can do.
Take care!
P.S. Keywords to look for in this project is: trailPos, isSpacebarPressed, maxTrailSize.
The code which is over 500 lines long
Code: Select all
local isSpacebarPressed
local frameNum
local colorList
local numLives
local maxTrailSize
local isPpressed
local isMpressed
local isRpressed
local SHOW_COLLISION_BOX
local ship
local shiplives
local smallAsteroid
local mediumAsteroid
local largeAsteroid
local menuImage
local gameoverImage
local numAsteroids
local asteroids
local isUpHeld
local isLeftHeld
local isRightHeld
local score
local sfx
local sfx2
local sfx3
local expSound
local trailPos
local state
local maxVelocity
local trailSprite
local highScore = 0
function resetGame()
print("in function resetGame")
isSpacebarPressed = false
frameNum = 1
colorList = {}
numLives = 5
maxTrailSize = 20
isPpressed = false
isMpressed = false
isRpressed = false
-- debug
SHOW_COLLISION_BOX = false
--Ship--
ship = {}
ship.xPos = 400
ship.yPos = 300
ship.theta = 4.71
ship.xVelocity = 0
ship.xAccel = 0.15
ship.w = 32
ship.h = 32
ship.sprite = love.graphics.newImage("ship2.png")
trailSprite = love.graphics.newImage("ship.png")
shipIcon = love.graphics.newImage("shiplives.png")
maxVelocity = 5.25
--Asteroid images--
smallAsteroidImage = love.graphics.newImage("asteroid16.png")
mediumAsteroidImage = love.graphics.newImage("asteroid32.png")
largeAsteroidImage = love.graphics.newImage("asteroid64.png")
menuImage = love.graphics.newImage("menu.png")
gameoverImage = love.graphics.newImage("gameoverMenu.png")
-- asteroid sfx
smallAsteroidSound = love.audio.newSource("pickup.wav", "static")
mediumAsteroidSound = love.audio.newSource("pickup2.wav", "static")
largeAsteroidSound = love.audio.newSource("pickup3.wav", "static")
expSound = love.audio.newSource("deathSfx.wav", "static")
--Asteroids--
numAsteroids = 20
asteroids = {}
--Asteroid spawner--
for i = 1, numAsteroids do
local rand = math.random(1,3)
asteroids[i] = {}
if rand == 1 then
asteroids[i].W = 16
asteroids[i].H = 16
asteroids[i].sprite = smallAsteroidImage
asteroids[i].v = 2.5
asteroids[i].pointValue = 10
asteroids[i].sfx = smallAsteroidSound
elseif rand == 2 then
asteroids[i].W = 32
asteroids[i].H = 32
asteroids[i].sprite = mediumAsteroidImage
asteroids[i].v = 1.3
asteroids[i].pointValue = 50
asteroids[i].sfx = mediumAsteroidSound
else
asteroids[i].W = 64
asteroids[i].H = 64
asteroids[i].sprite = largeAsteroidImage
asteroids[i].v = 1
asteroids[i].pointValue = 100
asteroids[i].sfx = largeAsteroidSound
end
rand = math.random(1,4)
if rand == 1 then
asteroids[i].X = math.random(-400, -64)
asteroids[i].Y = math.random(0, 600)
asteroids[i].theta = -0.785 + (math.random() * 1.57 )
elseif rand == 2 then
asteroids[i].X = math.random(864, 2000)
asteroids[i].Y = math.random(0, 600)
asteroids[i].theta = 2.35 + (math.random() * 1.57 )
elseif rand == 3 then
asteroids[i].X = math.random(0, 800)
asteroids[i].Y = math.random(-400, -64)
asteroids[i].theta = 0.398 + (math.random() * 1.57 )
else
asteroids[i].X = math.random(0, 800)
asteroids[i].Y = math.random(700, 2000)
asteroids[i].theta = 4.71 + (math.random() * 1.57 )
end
end
-- controls
isUpHeld = false
isLeftHeld = false
isRightHeld = false
--other
score = 0
-- pick some random colors
trailPos = {}
for i = 1, maxTrailSize do
local c = {}
c.r = math.random(1)
c.g = math.random(1)
c.b = math.random(1)
colorList[i] = c
end
--Check state
state = "menuState"
end
function love.load()
print( "in function love.load" )
resetGame()
end
function love.draw()
if state == "menuState" then
drawMenu()
elseif state == "gameState" then
drawGame()
elseif state == "gameoverState" then
drawGameover()
end
end
function love.update()
mainFont = love.graphics.newFont("Mojang-Regular.ttf", 20)
love.graphics.setFont(mainFont)
if state == "menuState" then
updateMenu()
elseif state == "gameState" then
updateGame()
elseif state == "gameoverState" then
updateGameover()
end
end
function updateMenu()
if isPpressed then
state = "gameState"
end
end
function updateGameover()
if isRpressed then
resetGame()
state = "gameState"
elseif isMpressed then
resetGame()
state = "menuState"
end
end
function updateGame()
-- stick the pos structure into the *front* of our trail list
if frameNum % 5 == 0 then
-- create a pos structure that represents where the ship is right now
local pos = {}
pos.x = ship.xPos
pos.y = ship.yPos
pos.theta = ship.theta
table.insert(trailPos, 1, pos)
if #trailPos > maxTrailSize then
table.remove(trailPos)
end
if not isSpacebarPressed then
table.remove(trailPos)
end
end
for i = 1, numAsteroids do
-- update position
asteroids[i].X = asteroids[i].X + math.cos(asteroids[i].theta) * asteroids[i].v
asteroids[i].Y = asteroids[i].Y + math.sin(asteroids[i].theta) * asteroids[i].v
-- check for asteroid going offscreen, if so then respawn
if asteroids[i].X > 900 or asteroids[i].Y > 700 or asteroids[i].X < -100 or asteroids[i].Y < -100 then
rand = math.random(1,4)
if rand == 1 then
asteroids[i].X = math.random(-100, -64)
asteroids[i].Y = math.random(0, 600)
asteroids[i].theta = -0.785 + (math.random() * 1.57 )
elseif rand == 2 then
asteroids[i].X = math.random(864, 900)
asteroids[i].Y = math.random(0, 600)
asteroids[i].theta = 2.35 + (math.random() * 1.57 )
elseif rand == 3 then
asteroids[i].X = math.random(0, 800)
asteroids[i].Y = math.random(-100, -64)
asteroids[i].theta = 0.398 + (math.random() * 1.57 )
else
asteroids[i].X = math.random(0, 800)
asteroids[i].Y = math.random(700, 900)
asteroids[i].theta = 4.71 + (math.random() * 1.57 )
end
end
end
for i = 1, numAsteroids do
---VVV SHIP TO ASTEROID COLLISION VVV
-- test each asteroid against our main ship...
if ship.xPos > asteroids[i].X and ship.xPos < asteroids[i].X + asteroids[i].W and ship.yPos > asteroids[i].Y and ship.yPos < asteroids[i].Y + asteroids[i].H then
asteroids[i].X = math.random(-100, -64)
asteroids[i].Y = math.random(0, 600)
asteroids[i].theta = -0.785 + (math.random() * 1.57 )
numLives = numLives - 1
ship.xPos = 400
ship.yPos = 300
trailPos = {}
love.audio.stop(expSound)
love.audio.play(expSound)
if numLives == 0 then
love.audio.stop(expSound)
love.audio.play(expSound)
if score > highScore then
highScore = score
end
state = 'gameoverState'
end
end
-- test each asteroid against every ship in the trail...
for j = 1, #trailPos do
if trailPos[j].x > asteroids[i].X and trailPos[j].x < asteroids[i].X + asteroids[i].W and trailPos[j].y > asteroids[i].Y and trailPos[j].y < asteroids[i].Y + asteroids[i].H then
asteroids[i].X = math.random(-100, -64)
asteroids[i].Y = math.random(0, 600)
asteroids[i].theta = -0.785 + (math.random() * 1.57 )
score = score + asteroids[i].pointValue
love.audio.stop(asteroids[i].sfx)
love.audio.play(asteroids[i].sfx)
end
end
end
-- Asteroid to asteroid collision
-- dont flip things twice!
local hasAlreadyFlipped = {}
for k = 1, numAsteroids do
hasAlreadyFlipped[k] = false
end
for i = 1, numAsteroids do
local curAsteroid = asteroids[i]
for j = 1, numAsteroids do
local isUpperLeftColliding = false
local isUpperRightColliding = false
local isLowerLeftColliding = false
local isLowerRightColliding = false
isUpperLeftColliding = curAsteroid.X > asteroids[j].X and
curAsteroid.X < asteroids[j].X + asteroids[j].W and
curAsteroid.Y > asteroids[j].Y and
curAsteroid.Y < asteroids[j].Y + asteroids[j].H
isUpperRightColliding = curAsteroid.X + curAsteroid.W > asteroids[j].X and
curAsteroid.X + curAsteroid.W < asteroids[j].X + asteroids[j].W and
curAsteroid.Y > asteroids[j].Y and
curAsteroid.Y < asteroids[j].Y + asteroids[j].H
isLowerLeftColliding = curAsteroid.X > asteroids[j].X and
curAsteroid.X < asteroids[j].X + asteroids[j].W and
curAsteroid.Y + curAsteroid.H > asteroids[j].Y and
curAsteroid.Y + curAsteroid.H < asteroids[j].Y + asteroids[j].H
isLowerRightColliding = curAsteroid.X + curAsteroid.W > asteroids[j].X and
curAsteroid.X + curAsteroid.W < asteroids[j].X + asteroids[j].W and
curAsteroid.Y + curAsteroid.H > asteroids[j].Y and
curAsteroid.Y + curAsteroid.H < asteroids[j].Y + asteroids[j].H
local isCurOnscreen = curAsteroid.X > 0 and curAsteroid.X < 800 and curAsteroid.Y > 0 and curAsteroid.Y < 600
local isOtherOnscreen = asteroids[j].X > 0 and asteroids[j].X < 800 and asteroids[j].Y > 0 and asteroids[j].Y < 600
if isCurOnscreen and isOtherOnscreen then
if isUpperLeftColliding or isUpperRightColliding or isLowerLeftColliding or isLowerRightColliding then
if hasAlreadyFlipped[i] == false then
curAsteroid.theta = curAsteroid.theta + math.pi
hasAlreadyFlipped[i] = true
end
if hasAlreadyFlipped[j] == false then
asteroids[j].theta = asteroids[j].theta + math.pi
hasAlreadyFlipped[j] = true
end
end
end
end
end
if isUpHeld == true then
ship.xVelocity = ship.xVelocity + 0.5
else
ship.xVelocity = ship.xVelocity - 0.075
end
if isLeftHeld == true then
ship.theta = ship.theta - 0.1
end
if isRightHeld == true then
ship.theta = ship.theta + 0.1
end
if ship.xVelocity < 0 then
ship.xVelocity = 0
end
if ship.xVelocity > maxVelocity then
ship.xVelocity = maxVelocity
end
ship.xPos = ship.xPos + math.cos(ship.theta) * ship.xVelocity
ship.yPos = ship.yPos + math.sin(ship.theta) * ship.xVelocity
if ship.xPos > 800 then
ship.xPos = 0
end
if ship.xPos < 0 then
ship.xPos = 800
end
if ship.yPos > 600 then
ship.yPos = 0
end
if ship.yPos < 0 then
ship.yPos = 600
end
frameNum = frameNum + 1
end
function drawMenu()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(menuImage, 0, 0)
end
function drawGameover()
love.graphics.setColor(1, 1, 1)
love.graphics.draw(gameoverImage, 0, 0)
love.graphics.setColor((52/255), (89/255), (35/255))
love.graphics.print(score, 150, 240)
--love.graphics.print("best:"..highScore, 100, 340)
end
function drawGame()
love.graphics.setBackgroundColor(115/255, 138/255, 40/255)
for i = 1, numLives do
love.graphics.setColor((52/255), (89/255), (35/255))
love.graphics.draw( shipIcon, 32*i, 64, -math.pi/2 )
end
for i = #trailPos, 1, -1 do
local alpha = 1
love.graphics.setColor( colorList[i].r, colorList[i].g, colorList[i].b, alpha )
love.graphics.draw(trailSprite, trailPos[i].x, trailPos[i].y, trailPos[i].theta, 1, 1, 16, 16 )
end
love.graphics.setColor(1, 1, 1)
for i = 1, numAsteroids do
love.graphics.draw(asteroids[i].sprite, asteroids[i].X, asteroids[i].Y)
if SHOW_COLLISION_BOX then
love.graphics.setColor( math.random(1), math.random(1), math.random(1) )
love.graphics.rectangle( "line", asteroids[i].X, asteroids[i].Y, asteroids[i].W, asteroids[i].H )
love.graphics.setPointSize( 10 )
love.graphics.point( asteroids[i].X + asteroids[i].H, asteroids[i].Y + asteroids[i].H )
love.graphics.print( i, asteroids[i].X, asteroids[i].Y )
love.graphics.setColor( 1, 1, 1 )
end
end
love.graphics.setColor((52/255), (89/255), (35/255))
love.graphics.draw(ship.sprite, ship.xPos, ship.yPos, ship.theta, 1, 1, 16, 16)
if SHOW_COLLISION_BOX then
love.graphics.setColor( math.random(1), math.random(1), math.random(1) )
love.graphics.setPointSize( 3 )
love.graphics.point( ship.xPos, ship.yPos )
love.graphics.setColor( 1, 1, 1 )
end
love.graphics.setColor((52/255), (89/255), (35/255))
love.graphics.print(score, 45, 10, 0, 1, 1)
end
function love.keypressed(key)
if key == 'right' then
ship.theta = ship.theta + 0.1
end
if key == 'left' then
ship.theta = ship.theta - 0.1
end
if key == 'up' then
isUpHeld = true
end
if key == 'left' then
isLeftHeld = true
end
if key == 'right' then
isRightHeld = true
end
if key == 'escape' then
love.event.push( 'quit' )
end
if key == 'c' then
SHOW_COLLISION_BOX = not SHOW_COLLISION_BOX
end
if key == ' ' then
isSpacebarPressed = true
end
if key == 'p' then
isPpressed = true
end
if key == 'm' then
isMpressed = true
end
if key == 'r' then
isRpressed = true
end
end
function love.keyreleased(key)
if key == 'up' then
isUpHeld = false
end
if key == 'left' then
isLeftHeld = false
end
if key == 'right' then
isRightHeld = false
end
if key == ' ' then
isSpacebarPressed = false
end
if key == 'p' then
isPpressed = false
end
if key == 'm' then
isMpressed = false
end
if key == 'r' then
isRpressed = false
end
end