From 3ba30a2fb1e344a32acbd86653d1a9f61dc9f1d9 Mon Sep 17 00:00:00 2001 From: Donald Ball Date: Fri, 14 Nov 2025 16:33:24 -0500 Subject: [PATCH 01/10] moving asteroids --- main.lua | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/main.lua b/main.lua index 50c97cc..f19bb1d 100644 --- a/main.lua +++ b/main.lua @@ -13,6 +13,24 @@ function love.load() bullets = {} bulletTimerLimit = 0.5 bulletTimer = bulletTimerLimit + + asteroids = { + { + x = 100, + y = 100, + }, + { + x = arenaWidth - 100, + y = 100, + }, + { + x = arenaWidth / 2, + y = arenaHeight - 100, + } + } + for asteroidIndex, asteroid in ipairs(asteroids) do + asteroid.angle = love.math.random() * (2 * math.pi) + end end function love.update(dt) @@ -58,6 +76,12 @@ function love.update(dt) }) end end + + for asteroidIndex, asteroid in ipairs(asteroids) do + local asteroidSpeed = 20 + asteroid.x = (asteroid.x + math.cos(asteroid.angle) * asteroidSpeed * dt) % arenaWidth + asteroid.y = (asteroid.y + math.cos(asteroid.angle) * asteroidSpeed * dt) % arenaHeight + end end function love.draw() @@ -80,6 +104,11 @@ function love.draw() love.graphics.setColor(0, 1, 0) love.graphics.circle('fill', bullet.x, bullet.y, 5) end + + for asteroidIndex, asteroid in ipairs(asteroids) do + love.graphics.setColor(1, 1, 0) + love.graphics.circle('fill', asteroid.x, asteroid.y, 80) + end end end From 3502dfbdd7aa4abb99c6117f7cc0eac578711d8b Mon Sep 17 00:00:00 2001 From: Donald Ball Date: Fri, 14 Nov 2025 16:41:04 -0500 Subject: [PATCH 02/10] asteroid collision --- main.lua | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/main.lua b/main.lua index f19bb1d..f5fc481 100644 --- a/main.lua +++ b/main.lua @@ -31,6 +31,7 @@ function love.load() for asteroidIndex, asteroid in ipairs(asteroids) do asteroid.angle = love.math.random() * (2 * math.pi) end + asteroidRadius = 80 end function love.update(dt) @@ -77,10 +78,19 @@ function love.update(dt) end end + local function areCirclesIntersecting(aX, aY, aRadius, bX, bY, bRadius) + return (aX - bX) ^ 2 + (aY - bY) ^ 2 <= (aRadius + bRadius) ^ 2 + end + for asteroidIndex, asteroid in ipairs(asteroids) do local asteroidSpeed = 20 asteroid.x = (asteroid.x + math.cos(asteroid.angle) * asteroidSpeed * dt) % arenaWidth - asteroid.y = (asteroid.y + math.cos(asteroid.angle) * asteroidSpeed * dt) % arenaHeight + asteroid.y = (asteroid.y + math.sin(asteroid.angle) * asteroidSpeed * dt) % arenaHeight + + if areCirclesIntersecting(shipX, shipY, shipRadius, asteroid.x, asteroid.y, asteroidRadius) then + love.load() + break + end end end @@ -107,7 +117,7 @@ function love.draw() for asteroidIndex, asteroid in ipairs(asteroids) do love.graphics.setColor(1, 1, 0) - love.graphics.circle('fill', asteroid.x, asteroid.y, 80) + love.graphics.circle('fill', asteroid.x, asteroid.y, asteroidRadius) end end end @@ -118,5 +128,6 @@ function love.draw() 'shipAngle:' .. shipAngle, 'shipX: ' .. shipX, 'shipSpeedX: ' .. shipSpeedX, + 'a1: ' .. asteroids[1].angle }, '\n')) end From c98ab26ac09857893019ed64dca1de7e93bb16f6 Mon Sep 17 00:00:00 2001 From: Donald Ball Date: Fri, 14 Nov 2025 16:50:50 -0500 Subject: [PATCH 03/10] destructible asteroids --- main.lua | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/main.lua b/main.lua index f5fc481..82e1b94 100644 --- a/main.lua +++ b/main.lua @@ -13,6 +13,7 @@ function love.load() bullets = {} bulletTimerLimit = 0.5 bulletTimer = bulletTimerLimit + bulletRadius = 5 asteroids = { { @@ -53,6 +54,10 @@ function love.update(dt) shipX = (shipX + shipSpeedX * dt) % arenaWidth shipY = (shipY + shipSpeedY * dt) % arenaHeight + local function areCirclesIntersecting(aX, aY, aRadius, bX, bY, bRadius) + return (aX - bX) ^ 2 + (aY - bY) ^ 2 <= (aRadius + bRadius) ^ 2 + end + for bulletIndex = #bullets, 1, -1 do local bullet = bullets[bulletIndex] bullet.timeLeft = bullet.timeLeft - dt @@ -63,6 +68,14 @@ function love.update(dt) bullet.x = (bullet.x + math.cos(bullet.angle) * bulletSpeed * dt) % arenaWidth bullet.y = (bullet.y + math.sin(bullet.angle) * bulletSpeed * dt) % arenaHeight end + for asteroidIndex = #asteroids, 1, -1 do + local asteroid = asteroids[asteroidIndex] + if areCirclesIntersecting(bullet.x, bullet.y, bulletRadius, asteroid.x, asteroid.y, asteroidRadius) then + table.remove(bullets, bulletIndex) + table.remove(asteroids, asteroidIndex) + break + end + end end bulletTimer = bulletTimer + dt @@ -78,10 +91,6 @@ function love.update(dt) end end - local function areCirclesIntersecting(aX, aY, aRadius, bX, bY, bRadius) - return (aX - bX) ^ 2 + (aY - bY) ^ 2 <= (aRadius + bRadius) ^ 2 - end - for asteroidIndex, asteroid in ipairs(asteroids) do local asteroidSpeed = 20 asteroid.x = (asteroid.x + math.cos(asteroid.angle) * asteroidSpeed * dt) % arenaWidth @@ -121,13 +130,4 @@ function love.draw() end end end - - love.graphics.origin() - love.graphics.setColor(1, 1, 1) - love.graphics.print(table.concat({ - 'shipAngle:' .. shipAngle, - 'shipX: ' .. shipX, - 'shipSpeedX: ' .. shipSpeedX, - 'a1: ' .. asteroids[1].angle - }, '\n')) end From 78cd6176a884998d88d6856609f25978ebcfcb2d Mon Sep 17 00:00:00 2001 From: Donald Ball Date: Fri, 14 Nov 2025 17:01:03 -0500 Subject: [PATCH 04/10] splitting asteroids --- main.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/main.lua b/main.lua index 82e1b94..63617ae 100644 --- a/main.lua +++ b/main.lua @@ -72,6 +72,18 @@ function love.update(dt) local asteroid = asteroids[asteroidIndex] if areCirclesIntersecting(bullet.x, bullet.y, bulletRadius, asteroid.x, asteroid.y, asteroidRadius) then table.remove(bullets, bulletIndex) + local angle1 = love.math.random() * (2 * math.pi) + local angle2 = (angle1 - math.pi) % (2 * math.pi) + table.insert(asteroids, { + x = asteroid.x, + y = asteroid.y, + angle = angle1, + }) + table.insert(asteroids, { + x = asteroid.x, + y = asteroid.y, + angle = angle2, + }) table.remove(asteroids, asteroidIndex) break end From 73cae82662f93b6b1f929316c5252a7880b8d17f Mon Sep 17 00:00:00 2001 From: Donald Ball Date: Fri, 14 Nov 2025 17:10:40 -0500 Subject: [PATCH 05/10] asteroid stages --- main.lua | 106 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 38 deletions(-) diff --git a/main.lua b/main.lua index 63617ae..29fd96f 100644 --- a/main.lua +++ b/main.lua @@ -3,36 +3,59 @@ local love = require("love") function love.load() arenaWidth = 800 arenaHeight = 600 - shipX = arenaWidth / 2 - shipY = arenaHeight / 2 - shipAngle = 0 - shipSpeedX = 0 - shipSpeedY = 0 shipRadius = 30 - bullets = {} bulletTimerLimit = 0.5 - bulletTimer = bulletTimerLimit bulletRadius = 5 - asteroids = { + asteroidStages = { { - x = 100, - y = 100, + speed = 120, + radius = 15, }, { - x = arenaWidth - 100, - y = 100, + speed = 70, + radius = 30, }, { - x = arenaWidth / 2, - y = arenaHeight - 100, - } + speed = 50, + radius = 50, + }, + { + speed = 20, + radius = 80, + }, } - for asteroidIndex, asteroid in ipairs(asteroids) do - asteroid.angle = love.math.random() * (2 * math.pi) + + function reset() + shipX = arenaWidth / 2 + shipY = arenaHeight / 2 + shipAngle = 0 + shipSpeedX = 0 + shipSpeedY = 0 + bullets = {} + bulletTimer = bulletTimerLimit + asteroids = { + { + x = 100, + y = 100, + }, + { + x = arenaWidth - 100, + y = 100, + }, + { + x = arenaWidth / 2, + y = arenaHeight - 100, + } + } + for asteroidIndex, asteroid in ipairs(asteroids) do + asteroid.angle = love.math.random() * (2 * math.pi) + asteroid.stage = #asteroidStages + end end - asteroidRadius = 80 + + reset() end function love.update(dt) @@ -70,20 +93,24 @@ function love.update(dt) end for asteroidIndex = #asteroids, 1, -1 do local asteroid = asteroids[asteroidIndex] - if areCirclesIntersecting(bullet.x, bullet.y, bulletRadius, asteroid.x, asteroid.y, asteroidRadius) then + if areCirclesIntersecting(bullet.x, bullet.y, bulletRadius, asteroid.x, asteroid.y, asteroidStages[asteroid.stage].radius) then table.remove(bullets, bulletIndex) - local angle1 = love.math.random() * (2 * math.pi) - local angle2 = (angle1 - math.pi) % (2 * math.pi) - table.insert(asteroids, { - x = asteroid.x, - y = asteroid.y, - angle = angle1, - }) - table.insert(asteroids, { - x = asteroid.x, - y = asteroid.y, - angle = angle2, - }) + if asteroid.stage > 1 then + local angle1 = love.math.random() * (2 * math.pi) + local angle2 = (angle1 - math.pi) % (2 * math.pi) + table.insert(asteroids, { + x = asteroid.x, + y = asteroid.y, + angle = angle1, + stage = asteroid.stage - 1, + }) + table.insert(asteroids, { + x = asteroid.x, + y = asteroid.y, + angle = angle2, + stage = asteroid.stage - 1, + }) + end table.remove(asteroids, asteroidIndex) break end @@ -104,15 +131,18 @@ function love.update(dt) end for asteroidIndex, asteroid in ipairs(asteroids) do - local asteroidSpeed = 20 - asteroid.x = (asteroid.x + math.cos(asteroid.angle) * asteroidSpeed * dt) % arenaWidth - asteroid.y = (asteroid.y + math.sin(asteroid.angle) * asteroidSpeed * dt) % arenaHeight + asteroid.x = (asteroid.x + math.cos(asteroid.angle) * asteroidStages[asteroid.stage].speed * dt) % arenaWidth + asteroid.y = (asteroid.y + math.sin(asteroid.angle) * asteroidStages[asteroid.stage].speed * dt) % arenaHeight - if areCirclesIntersecting(shipX, shipY, shipRadius, asteroid.x, asteroid.y, asteroidRadius) then - love.load() + if areCirclesIntersecting(shipX, shipY, shipRadius, asteroid.x, asteroid.y, asteroidStages[asteroid.stage].radius) then + reset() break end end + + if #asteroids == 0 then + reset() + end end function love.draw() @@ -133,12 +163,12 @@ function love.draw() for bulletIndex, bullet in ipairs(bullets) do love.graphics.setColor(0, 1, 0) - love.graphics.circle('fill', bullet.x, bullet.y, 5) + love.graphics.circle('fill', bullet.x, bullet.y, bulletRadius) end for asteroidIndex, asteroid in ipairs(asteroids) do love.graphics.setColor(1, 1, 0) - love.graphics.circle('fill', asteroid.x, asteroid.y, asteroidRadius) + love.graphics.circle('fill', asteroid.x, asteroid.y, asteroidStages[asteroid.stage].radius) end end end From 67b2a620c550ba09e711e92666d2e006b7cc3daf Mon Sep 17 00:00:00 2001 From: Donald Ball Date: Fri, 14 Nov 2025 17:17:45 -0500 Subject: [PATCH 06/10] move asteroids --- main.lua => asteroids/main.lua | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename main.lua => asteroids/main.lua (100%) diff --git a/main.lua b/asteroids/main.lua similarity index 100% rename from main.lua rename to asteroids/main.lua From 46dc6d16f68c3f6bb5f73dfdeb960bb7e7f07152 Mon Sep 17 00:00:00 2001 From: Donald Ball Date: Fri, 14 Nov 2025 21:06:24 -0500 Subject: [PATCH 07/10] coalesce game table --- asteroids/main.lua | 94 +++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/asteroids/main.lua b/asteroids/main.lua index 29fd96f..81d8882 100644 --- a/asteroids/main.lua +++ b/asteroids/main.lua @@ -1,57 +1,55 @@ local love = require("love") -function love.load() - arenaWidth = 800 - arenaHeight = 600 - shipRadius = 30 - - bulletTimerLimit = 0.5 - bulletRadius = 5 - - asteroidStages = { - { - speed = 120, - radius = 15, - }, - { - speed = 70, +local function initGame() + return { + width = 800, + height = 600, + ship = { radius = 30, + bullet = { + timerLimit = 0.5, + radius = 5, + } }, - { - speed = 50, - radius = 50, - }, - { - speed = 20, - radius = 80, + asteroids = { + stages = { + { speed = 120, radius = 15 }, + { speed = 70, radius = 30 }, + { speed = 50, radius = 50 }, + { speed = 20, radius = 80 }, + }, }, } +end +local game = initGame() + +function love.load() function reset() - shipX = arenaWidth / 2 - shipY = arenaHeight / 2 + shipX = game.width / 2 + shipY = game.height / 2 shipAngle = 0 shipSpeedX = 0 shipSpeedY = 0 bullets = {} - bulletTimer = bulletTimerLimit + bulletTimer = game.ship.bullet.timerLimit asteroids = { { x = 100, y = 100, }, { - x = arenaWidth - 100, + x = game.width - 100, y = 100, }, { - x = arenaWidth / 2, - y = arenaHeight - 100, + x = game.width / 2, + y = game.height - 100, } } - for asteroidIndex, asteroid in ipairs(asteroids) do + for _, asteroid in ipairs(asteroids) do asteroid.angle = love.math.random() * (2 * math.pi) - asteroid.stage = #asteroidStages + asteroid.stage = #game.asteroids.stages end end @@ -74,8 +72,8 @@ function love.update(dt) shipSpeedY = shipSpeedY + math.sin(shipAngle) * shipSpeed * dt end - shipX = (shipX + shipSpeedX * dt) % arenaWidth - shipY = (shipY + shipSpeedY * dt) % arenaHeight + shipX = (shipX + shipSpeedX * dt) % game.width + shipY = (shipY + shipSpeedY * dt) % game.height local function areCirclesIntersecting(aX, aY, aRadius, bX, bY, bRadius) return (aX - bX) ^ 2 + (aY - bY) ^ 2 <= (aRadius + bRadius) ^ 2 @@ -88,12 +86,12 @@ function love.update(dt) table.remove(bullets, bulletIndex) else local bulletSpeed = 500 - bullet.x = (bullet.x + math.cos(bullet.angle) * bulletSpeed * dt) % arenaWidth - bullet.y = (bullet.y + math.sin(bullet.angle) * bulletSpeed * dt) % arenaHeight + bullet.x = (bullet.x + math.cos(bullet.angle) * bulletSpeed * dt) % game.width + bullet.y = (bullet.y + math.sin(bullet.angle) * bulletSpeed * dt) % game.height end for asteroidIndex = #asteroids, 1, -1 do local asteroid = asteroids[asteroidIndex] - if areCirclesIntersecting(bullet.x, bullet.y, bulletRadius, asteroid.x, asteroid.y, asteroidStages[asteroid.stage].radius) then + if areCirclesIntersecting(bullet.x, bullet.y, game.ship.bullet.radius, asteroid.x, asteroid.y, game.asteroids.stages[asteroid.stage].radius) then table.remove(bullets, bulletIndex) if asteroid.stage > 1 then local angle1 = love.math.random() * (2 * math.pi) @@ -119,11 +117,11 @@ function love.update(dt) bulletTimer = bulletTimer + dt if love.keyboard.isDown('s') then - if bulletTimer >= bulletTimerLimit then + if bulletTimer >= game.ship.bullet.timerLimit then bulletTimer = 0 table.insert(bullets, { - x = shipX + math.cos(shipAngle) * shipRadius, - y = shipY + math.sin(shipAngle) * shipRadius, + x = shipX + math.cos(shipAngle) * game.ship.radius, + y = shipY + math.sin(shipAngle) * game.ship.radius, angle = shipAngle, timeLeft = 4, }) @@ -131,10 +129,12 @@ function love.update(dt) end for asteroidIndex, asteroid in ipairs(asteroids) do - asteroid.x = (asteroid.x + math.cos(asteroid.angle) * asteroidStages[asteroid.stage].speed * dt) % arenaWidth - asteroid.y = (asteroid.y + math.sin(asteroid.angle) * asteroidStages[asteroid.stage].speed * dt) % arenaHeight + asteroid.x = (asteroid.x + math.cos(asteroid.angle) * game.asteroids.stages[asteroid.stage].speed * dt) % + game.width + asteroid.y = (asteroid.y + math.sin(asteroid.angle) * game.asteroids.stages[asteroid.stage].speed * dt) % + game.height - if areCirclesIntersecting(shipX, shipY, shipRadius, asteroid.x, asteroid.y, asteroidStages[asteroid.stage].radius) then + if areCirclesIntersecting(shipX, shipY, game.ship.radius, asteroid.x, asteroid.y, game.asteroids.stages[asteroid.stage].radius) then reset() break end @@ -149,9 +149,9 @@ function love.draw() for y = -1, 1 do for x = -1, 1 do love.graphics.origin() - love.graphics.translate(x * arenaWidth, y * arenaHeight) + love.graphics.translate(x * game.width, y * game.height) love.graphics.setColor(0, 0, 1) - love.graphics.circle('fill', shipX, shipY, shipRadius) + love.graphics.circle('fill', shipX, shipY, game.ship.radius) local shipCircleDistance = 20 love.graphics.setColor(0, 1, 1) love.graphics.circle( @@ -161,14 +161,14 @@ function love.draw() 5 ) - for bulletIndex, bullet in ipairs(bullets) do + for _, bullet in ipairs(bullets) do love.graphics.setColor(0, 1, 0) - love.graphics.circle('fill', bullet.x, bullet.y, bulletRadius) + love.graphics.circle('fill', bullet.x, bullet.y, game.ship.bullet.radius) end - for asteroidIndex, asteroid in ipairs(asteroids) do + for _, asteroid in ipairs(asteroids) do love.graphics.setColor(1, 1, 0) - love.graphics.circle('fill', asteroid.x, asteroid.y, asteroidStages[asteroid.stage].radius) + love.graphics.circle('fill', asteroid.x, asteroid.y, game.asteroids.stages[asteroid.stage].radius) end end end From 9f78b280cda4277d41d50cadf3d74df173606d72 Mon Sep 17 00:00:00 2001 From: Donald Ball Date: Fri, 14 Nov 2025 21:27:55 -0500 Subject: [PATCH 08/10] coalesce state --- asteroids/main.lua | 129 +++++++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 57 deletions(-) diff --git a/asteroids/main.lua b/asteroids/main.lua index 81d8882..b9fca5e 100644 --- a/asteroids/main.lua +++ b/asteroids/main.lua @@ -24,123 +24,138 @@ end local game = initGame() -function love.load() - function reset() - shipX = game.width / 2 - shipY = game.height / 2 - shipAngle = 0 - shipSpeedX = 0 - shipSpeedY = 0 - bullets = {} - bulletTimer = game.ship.bullet.timerLimit - asteroids = { - { - x = 100, - y = 100, - }, - { - x = game.width - 100, - y = 100, - }, - { - x = game.width / 2, - y = game.height - 100, - } +local function initState() + local asteroids = { + { + x = 100, + y = 100, + }, + { + x = game.width - 100, + y = 100, + }, + { + x = game.width / 2, + y = game.height - 100, } - for _, asteroid in ipairs(asteroids) do - asteroid.angle = love.math.random() * (2 * math.pi) - asteroid.stage = #game.asteroids.stages - end + } + for _, asteroid in ipairs(asteroids) do + asteroid.angle = love.math.random() * (2 * math.pi) + asteroid.stage = #game.asteroids.stages end + return { + ship = { + x = game.width / 2, + y = game.height / 2, + angle = 0, + speed = { + x = 0, + y = 0, + } + }, + -- the time after which the ship can fire another bullet + bulletTimer = game.ship.bullet.timerLimit, + bullets = {}, + asteroids = asteroids, + } +end + +local state = {} + +local function reset() + state = initState() +end + +function love.load() reset() end function love.update(dt) local turnSpeed = 10 if love.keyboard.isDown('right') then - shipAngle = shipAngle + turnSpeed * dt + state.ship.angle = state.ship.angle + turnSpeed * dt end if love.keyboard.isDown('left') then - shipAngle = shipAngle - turnSpeed * dt + state.ship.angle = state.ship.angle - turnSpeed * dt end - shipAngle = shipAngle % (2 * math.pi) + state.ship.angle = state.ship.angle % (2 * math.pi) if love.keyboard.isDown('up') then local shipSpeed = 100 - shipSpeedX = shipSpeedX + math.cos(shipAngle) * shipSpeed * dt - shipSpeedY = shipSpeedY + math.sin(shipAngle) * shipSpeed * dt + state.ship.speed.x = state.ship.speed.x + math.cos(state.ship.angle) * shipSpeed * dt + state.ship.speed.y = state.ship.speed.y + math.sin(state.ship.angle) * shipSpeed * dt end - shipX = (shipX + shipSpeedX * dt) % game.width - shipY = (shipY + shipSpeedY * dt) % game.height + state.ship.x = (state.ship.x + state.ship.speed.x * dt) % game.width + state.ship.y = (state.ship.y + state.ship.speed.y * dt) % game.height local function areCirclesIntersecting(aX, aY, aRadius, bX, bY, bRadius) return (aX - bX) ^ 2 + (aY - bY) ^ 2 <= (aRadius + bRadius) ^ 2 end - for bulletIndex = #bullets, 1, -1 do - local bullet = bullets[bulletIndex] + for bulletIndex = #state.bullets, 1, -1 do + local bullet = state.bullets[bulletIndex] bullet.timeLeft = bullet.timeLeft - dt if bullet.timeLeft <= 0 then - table.remove(bullets, bulletIndex) + table.remove(state.bullets, bulletIndex) else local bulletSpeed = 500 bullet.x = (bullet.x + math.cos(bullet.angle) * bulletSpeed * dt) % game.width bullet.y = (bullet.y + math.sin(bullet.angle) * bulletSpeed * dt) % game.height end - for asteroidIndex = #asteroids, 1, -1 do - local asteroid = asteroids[asteroidIndex] + for asteroidIndex = #state.asteroids, 1, -1 do + local asteroid = state.asteroids[asteroidIndex] if areCirclesIntersecting(bullet.x, bullet.y, game.ship.bullet.radius, asteroid.x, asteroid.y, game.asteroids.stages[asteroid.stage].radius) then - table.remove(bullets, bulletIndex) + table.remove(state.bullets, bulletIndex) if asteroid.stage > 1 then local angle1 = love.math.random() * (2 * math.pi) local angle2 = (angle1 - math.pi) % (2 * math.pi) - table.insert(asteroids, { + table.insert(state.asteroids, { x = asteroid.x, y = asteroid.y, angle = angle1, stage = asteroid.stage - 1, }) - table.insert(asteroids, { + table.insert(state.asteroids, { x = asteroid.x, y = asteroid.y, angle = angle2, stage = asteroid.stage - 1, }) end - table.remove(asteroids, asteroidIndex) + table.remove(state.asteroids, asteroidIndex) break end end end - bulletTimer = bulletTimer + dt + state.bulletTimer = state.bulletTimer + dt if love.keyboard.isDown('s') then - if bulletTimer >= game.ship.bullet.timerLimit then - bulletTimer = 0 - table.insert(bullets, { - x = shipX + math.cos(shipAngle) * game.ship.radius, - y = shipY + math.sin(shipAngle) * game.ship.radius, - angle = shipAngle, + if state.bulletTimer >= game.ship.bullet.timerLimit then + state.bulletTimer = 0 + table.insert(state.bullets, { + x = state.ship.x + math.cos(state.ship.angle) * game.ship.radius, + y = state.ship.y + math.sin(state.ship.angle) * game.ship.radius, + angle = state.ship.angle, timeLeft = 4, }) end end - for asteroidIndex, asteroid in ipairs(asteroids) do + for _, asteroid in ipairs(state.asteroids) do asteroid.x = (asteroid.x + math.cos(asteroid.angle) * game.asteroids.stages[asteroid.stage].speed * dt) % game.width asteroid.y = (asteroid.y + math.sin(asteroid.angle) * game.asteroids.stages[asteroid.stage].speed * dt) % game.height - if areCirclesIntersecting(shipX, shipY, game.ship.radius, asteroid.x, asteroid.y, game.asteroids.stages[asteroid.stage].radius) then + if areCirclesIntersecting(state.ship.x, state.ship.y, game.ship.radius, asteroid.x, asteroid.y, game.asteroids.stages[asteroid.stage].radius) then reset() break end end - if #asteroids == 0 then + if #state.asteroids == 0 then reset() end end @@ -151,22 +166,22 @@ function love.draw() love.graphics.origin() love.graphics.translate(x * game.width, y * game.height) love.graphics.setColor(0, 0, 1) - love.graphics.circle('fill', shipX, shipY, game.ship.radius) + love.graphics.circle('fill', state.ship.x, state.ship.y, game.ship.radius) local shipCircleDistance = 20 love.graphics.setColor(0, 1, 1) love.graphics.circle( 'fill', - shipX + math.cos(shipAngle) * shipCircleDistance, - shipY + math.sin(shipAngle) * shipCircleDistance, + state.ship.x + math.cos(state.ship.angle) * shipCircleDistance, + state.ship.y + math.sin(state.ship.angle) * shipCircleDistance, 5 ) - for _, bullet in ipairs(bullets) do + for _, bullet in ipairs(state.bullets) do love.graphics.setColor(0, 1, 0) love.graphics.circle('fill', bullet.x, bullet.y, game.ship.bullet.radius) end - for _, asteroid in ipairs(asteroids) do + for _, asteroid in ipairs(state.asteroids) do love.graphics.setColor(1, 1, 0) love.graphics.circle('fill', asteroid.x, asteroid.y, game.asteroids.stages[asteroid.stage].radius) end From 89c3b42db2947b92f16c6cc536d0d15885aba717 Mon Sep 17 00:00:00 2001 From: Donald Ball Date: Fri, 14 Nov 2025 21:35:05 -0500 Subject: [PATCH 09/10] coalesce controls --- asteroids/main.lua | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/asteroids/main.lua b/asteroids/main.lua index b9fca5e..65bd3a4 100644 --- a/asteroids/main.lua +++ b/asteroids/main.lua @@ -9,7 +9,7 @@ local function initGame() bullet = { timerLimit = 0.5, radius = 5, - } + }, }, asteroids = { stages = { @@ -19,6 +19,12 @@ local function initGame() { speed = 20, radius = 80 }, }, }, + controls = { + ship = { + turnRate = 10, + thrustRate = 100, + }, + }, } end @@ -72,19 +78,18 @@ function love.load() end function love.update(dt) - local turnSpeed = 10 if love.keyboard.isDown('right') then - state.ship.angle = state.ship.angle + turnSpeed * dt + state.ship.angle = state.ship.angle + game.controls.ship.turnRate * dt end if love.keyboard.isDown('left') then - state.ship.angle = state.ship.angle - turnSpeed * dt + state.ship.angle = state.ship.angle - game.controls.ship.turnRate * dt end state.ship.angle = state.ship.angle % (2 * math.pi) if love.keyboard.isDown('up') then local shipSpeed = 100 - state.ship.speed.x = state.ship.speed.x + math.cos(state.ship.angle) * shipSpeed * dt - state.ship.speed.y = state.ship.speed.y + math.sin(state.ship.angle) * shipSpeed * dt + state.ship.speed.x = state.ship.speed.x + math.cos(state.ship.angle) * game.controls.ship.thrustRate * dt + state.ship.speed.y = state.ship.speed.y + math.sin(state.ship.angle) * game.controls.ship.thrustRate * dt end state.ship.x = (state.ship.x + state.ship.speed.x * dt) % game.width From ae1616299baf03ea850f623fccec0f7d6df46da5 Mon Sep 17 00:00:00 2001 From: Donald Ball Date: Fri, 14 Nov 2025 21:38:46 -0500 Subject: [PATCH 10/10] more game declarations --- asteroids/main.lua | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/asteroids/main.lua b/asteroids/main.lua index 65bd3a4..3003812 100644 --- a/asteroids/main.lua +++ b/asteroids/main.lua @@ -9,6 +9,8 @@ local function initGame() bullet = { timerLimit = 0.5, radius = 5, + speed = 500, + time = 4, }, }, asteroids = { @@ -105,9 +107,8 @@ function love.update(dt) if bullet.timeLeft <= 0 then table.remove(state.bullets, bulletIndex) else - local bulletSpeed = 500 - bullet.x = (bullet.x + math.cos(bullet.angle) * bulletSpeed * dt) % game.width - bullet.y = (bullet.y + math.sin(bullet.angle) * bulletSpeed * dt) % game.height + bullet.x = (bullet.x + math.cos(bullet.angle) * game.ship.bullet.speed * dt) % game.width + bullet.y = (bullet.y + math.sin(bullet.angle) * game.ship.bullet.speed * dt) % game.height end for asteroidIndex = #state.asteroids, 1, -1 do local asteroid = state.asteroids[asteroidIndex] @@ -143,7 +144,7 @@ function love.update(dt) x = state.ship.x + math.cos(state.ship.angle) * game.ship.radius, y = state.ship.y + math.sin(state.ship.angle) * game.ship.radius, angle = state.ship.angle, - timeLeft = 4, + timeLeft = game.ship.bullet.time, }) end end