Created
February 6, 2017 05:48
-
-
Save romgerman/7e5b3b6e75a3a51d832d3af87ed0fd38 to your computer and use it in GitHub Desktop.
Love2d asteroids (pseudo 3d)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local function Vector2(x, y) | |
| local v = { | |
| x = x, | |
| y = y | |
| } | |
| return v; | |
| end | |
| local function Mat2( m11, m12, m21, m22 ) | |
| local m = { | |
| m11 = m11, m12 = m12, | |
| m21 = m21, m22 = m22 | |
| } | |
| return m | |
| end | |
| local function Vec2MulMat2( v, m ) | |
| local r = { | |
| x = m.m11 * v.x + m.m12 * v.y, | |
| y = m.m21 * v.x + m.m22 * v.y | |
| } | |
| return r | |
| end | |
| local function Centroid( poly ) | |
| local x = 0 | |
| local y = 0 | |
| for i,v in ipairs(poly) do | |
| x = x + v.x | |
| y = y + v.y | |
| end | |
| local v = { | |
| x = x / #poly, | |
| y = y / #poly | |
| } | |
| return v | |
| end | |
| local function CalcRectForPoly( p, x, y ) | |
| local rect = { | |
| x = 0, | |
| y = 0, | |
| x2 = 0, | |
| y2 = 0 | |
| } | |
| for i, v in ipairs(p) do | |
| if v.x < rect.x then | |
| rect.x = v.x | |
| end | |
| if v.y < rect.y then | |
| rect.y = v.y | |
| end | |
| if v.x > rect.x2 then | |
| rect.x2 = v.x | |
| end | |
| if v.y > rect.y2 then | |
| rect.y2 = v.y | |
| end | |
| end | |
| rect.x = rect.x + x | |
| rect.y = rect.y + y | |
| rect.x2 = rect.x2 + x | |
| rect.y2 = rect.y2 + y | |
| return rect | |
| end | |
| local function PointInRect( p, r ) | |
| return (p.x > r.x and p.x < r.x2 and p.y > r.y and p.y < r.y2) | |
| end | |
| -- HELPER FUNCTIONS | |
| function lerp(a, b, t) | |
| return a + (b - a) * t | |
| end | |
| function ilerp(a, b, t) | |
| return a - (b + a) * t | |
| end | |
| -- END | |
| -- LOAD RESOURCES | |
| local shootSound = love.audio.newSource("Assets/Sound/shoot1.wav", 'static') | |
| local blowSound = love.audio.newSource("Assets/Sound/blow.wav", 'static') | |
| local ainsSoundData = love.sound.newSoundData("Assets/Sound/asteroid is near the ship.wav") | |
| local ainsSound = love.audio.newSource(ainsSoundData) | |
| -- END | |
| local screenWidth | |
| local screenHeight | |
| local screenWidth2 | |
| local screenHeight2 | |
| local windowWidth | |
| local windowHeight | |
| local windowWidth2 | |
| local windowHeight2 | |
| local warningSoundVol = 0 | |
| function love.load() | |
| screenWidth = love.graphics.getWidth() | |
| screenHeight = love.graphics.getHeight() | |
| screenWidth2 = screenWidth / 2 | |
| screenHeight2 = screenHeight / 2 | |
| windowWidth = screenWidth / 1.2 | |
| windowHeight = screenHeight / 1.5 | |
| windowWidth2 = windowWidth / 2 | |
| windowHeight2 = windowHeight / 2 | |
| love.mouse.setVisible( false ) | |
| ainsSound:setVolume(warningSoundVol) | |
| ainsSound:setLooping(true) | |
| ainsSound:play() | |
| shootSound:setVolume(0.5) | |
| blowSound:setVolume(0.5) | |
| end | |
| local zFar = 100 | |
| local bSpeed = 2 | |
| local bSize = 50 | |
| local shootRate = 60/122 | |
| local spawnRate = 1 | |
| local modX = 0 | |
| local modY = 0 | |
| local BulletList = { } | |
| local function ShootBullet( x, y, sx, sy ) | |
| local bullet = { | |
| ex = x, | |
| ey = y, | |
| x = sx + bSize, | |
| y = sy + bSize, | |
| z = 0, | |
| r = bSize | |
| } | |
| table.insert(BulletList, bullet) | |
| shootSound:play() | |
| end | |
| local function DrawBullet( b ) | |
| love.graphics.circle('fill', b.x, b.y, b.r) | |
| end | |
| local function UpdateBullet( i, b, dt ) | |
| b.ex = lerp(b.ex, b.ex - modX, dt * bSpeed) | |
| b.ey = lerp(b.ey, b.ey - modY, dt * bSpeed) | |
| b.x = lerp(b.x, b.ex - modX, dt * bSpeed) | |
| b.y = lerp(b.y, b.ey - modY, dt * bSpeed) | |
| b.z = lerp(b.z, zFar, dt * bSpeed * 0.5) | |
| if b.r <= 1 then | |
| table.remove(BulletList, i) | |
| else | |
| b.r = lerp(b.r, 0, dt * bSpeed * 1.5) | |
| end | |
| end | |
| local AsteroidList = { } | |
| local function SpawnAsteroid() | |
| local x = love.math.random( 100, screenWidth - 100 ) | |
| local y = love.math.random( 100, screenHeight - 100 ) | |
| local a = { | |
| x = x, | |
| y = y, | |
| z = zFar, | |
| size = 1, | |
| --oldsize = 1, | |
| poly = { | |
| Vector2(0, 0), | |
| Vector2(5, 5), | |
| Vector2(10, 1), | |
| Vector2(13, -10), | |
| Vector2(4, -10), | |
| Vector2(5, -5) | |
| }, | |
| rect = { | |
| x = 0, | |
| y = 0, | |
| x2 = 0, | |
| y2 = 0 | |
| } | |
| } | |
| table.insert(AsteroidList, a) | |
| end | |
| local function DrawAsteroid( a ) | |
| local poly = { } | |
| for i,v in ipairs(a.poly) do | |
| table.insert(poly, v.x + a.x) | |
| table.insert(poly, v.y + a.y) | |
| end | |
| love.graphics.polygon('line', poly) | |
| --[[love.graphics.polygon('line', a.rect.x, a.rect.y, | |
| a.rect.x, a.rect.y2, | |
| a.rect.x2, a.rect.y2, | |
| a.rect.x2, a.rect.y)]] | |
| end | |
| local function UpdateAsteroid( i, a, dt ) | |
| --a.z = lerp(a.z, zFar, dt * 0.0001) | |
| a.z = a.z - dt * 8 | |
| a.size = lerp(a.size, 10, dt * 0.0001) | |
| a.x = a.x - modX * 0.1 | |
| a.y = a.y - modY * 0.1 | |
| if a.z <= 2 then | |
| if (a.x < 0 and a.y < 0) or (a.x > screenWidth and a.y > screenHeight) then | |
| table.remove(AsteroidList, i) | |
| return | |
| end | |
| -- Game over | |
| table.remove(AsteroidList, i) | |
| return | |
| end | |
| local smat = Mat2(a.size, 0, | |
| 0, a.size) | |
| local centroid = Centroid(a.poly) | |
| for i,v in ipairs(a.poly) do | |
| local x = v.x - centroid.x | |
| local y = v.y - centroid.y | |
| local vec = Vec2MulMat2(Vector2(x, y), smat) | |
| a.poly[i].x = vec.x --+ v.x -- modX | |
| a.poly[i].y = vec.y --+ v.y -- modY | |
| end | |
| a.rect = CalcRectForPoly(a.poly, a.x, a.y) | |
| end | |
| local function CheckCollisions() | |
| for i,v in ipairs(AsteroidList) do | |
| for i2,v2 in ipairs(BulletList) do | |
| if PointInRect({x = v2.x, y = v2.y}, v.rect) and v2.z > v.z then | |
| table.remove(AsteroidList, i) | |
| table.remove(BulletList, i2) | |
| blowSound:play() | |
| end | |
| end | |
| end | |
| end | |
| local prevSTime = 0 | |
| local prevATime = 0 | |
| local changeVol = false | |
| function love.update(dt) | |
| local x, y = love.mouse.getPosition() | |
| modX = lerp(modX, x - screenWidth2, dt * 2) | |
| modY = lerp(modY, y - screenHeight2, dt * 2) | |
| if love.mouse.isDown(1) then | |
| if prevSTime >= shootRate then | |
| ShootBullet(x, y, 0, windowHeight2) | |
| ShootBullet(x, y, windowWidth, windowHeight2) | |
| prevSTime = 0 | |
| end | |
| end | |
| if prevATime >= spawnRate then | |
| SpawnAsteroid() | |
| prevATime = 0 | |
| end | |
| -- Collisions | |
| CheckCollisions() | |
| -- Bullets | |
| for k,v in pairs(BulletList) do | |
| UpdateBullet(k, v, dt) | |
| end | |
| -- Asteroids | |
| for k,v in pairs(AsteroidList) do | |
| UpdateAsteroid(k, v, dt) | |
| if v.z < zFar / 2 then | |
| changeVol = true | |
| end | |
| end | |
| if changeVol then | |
| warningSoundVol = lerp(warningSoundVol, 0.5, dt * 0.5) | |
| else | |
| warningSoundVol = 0 | |
| end | |
| ainsSound:setVolume(warningSoundVol) | |
| prevSTime = prevSTime + dt | |
| prevATime = prevATime + dt | |
| end | |
| function love.draw() | |
| -- Asteroids | |
| love.graphics.setColor(200, 200, 255, 255) | |
| love.graphics.setLineWidth( 2 ) | |
| for i,v in ipairs(AsteroidList) do | |
| DrawAsteroid(v) | |
| end | |
| love.graphics.setLineWidth( 1 ) | |
| love.graphics.setColor(255, 50, 50, 255) | |
| -- Bullets | |
| for i,v in ipairs(BulletList) do | |
| DrawBullet(v) | |
| end | |
| love.graphics.setColor(255, 255, 255, 255) | |
| love.graphics.line(0, 0, | |
| screenWidth2 + modX - windowWidth2, screenHeight2 + modY - windowHeight2) | |
| love.graphics.line(0, 0, | |
| screenWidth2 + modX + windowWidth2, screenHeight2 + modY - windowHeight2) | |
| love.graphics.line(screenWidth2, 0, | |
| screenWidth2 + modX, screenHeight2 + modY - windowHeight2) | |
| love.graphics.line(screenWidth, 0, | |
| screenWidth2 + modX + windowWidth2, screenHeight2 + modY - windowHeight2) | |
| love.graphics.line(screenWidth, 0, | |
| screenWidth2 + modX - windowWidth2, screenHeight2 + modY - windowHeight2) | |
| love.graphics.line(screenWidth + 100, screenHeight2, | |
| screenWidth2 + modX + windowWidth2, screenHeight2 + modY) | |
| love.graphics.line(screenWidth2 - windowWidth2 + modX, screenHeight2 - windowHeight2 + modY, | |
| screenWidth2 - windowWidth2 / 2 + modX, screenHeight2 - windowHeight2 / 2 + modY) | |
| love.graphics.line(screenWidth2 + windowWidth2 + modX, screenHeight2 - windowHeight2 + modY, | |
| screenWidth2 + windowWidth2 / 2 + modX, screenHeight2 - windowHeight2 / 2 + modY) | |
| love.graphics.line(screenWidth, screenHeight, | |
| screenWidth2 + modX + windowWidth2, screenHeight2 + modY + windowHeight2) | |
| love.graphics.line(screenWidth2, screenHeight, | |
| screenWidth2 + modX, screenHeight2 + modY + windowHeight2) | |
| love.graphics.line(0, screenHeight, | |
| screenWidth2 + modX + windowWidth2, screenHeight2 + modY + windowHeight2) | |
| love.graphics.line(-100, screenHeight2, | |
| screenWidth2 + modX - windowWidth2, screenHeight2 + modY) | |
| love.graphics.line(0, screenHeight, | |
| screenWidth2 - windowWidth2 + modX, screenHeight2 + windowHeight2 + modY) | |
| love.graphics.line(screenWidth, screenHeight, | |
| screenWidth2 - windowWidth2 + modX, screenHeight2 + windowHeight2 + modY) | |
| love.graphics.line(screenWidth2 - windowWidth2 + modX, screenHeight2 + windowHeight2 + modY, | |
| screenWidth2 - windowWidth2 / 2 + modX, screenHeight2 + windowHeight2 / 2 + modY) | |
| love.graphics.line(screenWidth2 + windowWidth2 + modX, screenHeight2 + windowHeight2 + modY, | |
| screenWidth2 + windowWidth2 / 2 + modX, screenHeight2 + windowHeight2 / 2 + modY) | |
| -- Center window | |
| love.graphics.line(screenWidth2 + modX, screenHeight2 - windowHeight2 + modY, | |
| screenWidth2 + windowWidth2 + modX, screenHeight2 + modY) | |
| love.graphics.line(screenWidth2 + windowWidth2 + modX, screenHeight2 + modY, | |
| screenWidth2 + modX, screenHeight2 + windowHeight2 + modY) | |
| love.graphics.line(screenWidth2 + modX, screenHeight2 + windowHeight2 + modY, | |
| screenWidth2 - windowWidth2 + modX, screenHeight2 + modY) | |
| love.graphics.line(screenWidth2 - windowWidth2 + modX, screenHeight2 + modY, | |
| screenWidth2 + modX, screenHeight2 - windowHeight2 + modY) | |
| love.graphics.setColor(255, 255, 255, 50) | |
| local vertices = { | |
| 0, 0, | |
| screenWidth2, 0, | |
| screenWidth2 + modX, screenHeight2 - windowHeight2 + modY, | |
| screenWidth2 - windowWidth2 + modX, screenHeight2 - windowHeight2 + modY | |
| } | |
| --love.graphics.polygon('fill', vertices) | |
| local vertices = { | |
| screenWidth, 0, | |
| screenWidth2 + windowWidth2 + modX, screenHeight2 - windowHeight2 + modY, | |
| screenWidth2 + modX, screenHeight2 - windowHeight2 + modY, | |
| screenWidth2, 0 | |
| } | |
| --love.graphics.polygon('fill', vertices) | |
| love.graphics.setColor(255, 255, 255, 255) | |
| -- Crosshair | |
| love.graphics.line(screenWidth2 - 10 + modX, screenHeight2 - 5 + modY, | |
| screenWidth2 + 10 + modX, screenHeight2 - 5 + modY) | |
| love.graphics.line(screenWidth2 - 2 + modX, screenHeight2 + modY, | |
| screenWidth2 + 2 + modX, screenHeight2 + modY) | |
| love.graphics.line(screenWidth2 - 5 + modX, screenHeight2 + 5 + modY, | |
| screenWidth2 + 5 + modX, screenHeight2 + 5 + modY) | |
| love.graphics.line(screenWidth2 + modX, screenHeight2 + modY, | |
| screenWidth2 + windowWidth2 + modX, screenHeight2 + modY) | |
| -- FPS | |
| love.graphics.print(tostring(love.timer.getFPS()), 10, 10) | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment