2
\$\begingroup\$

I have a lot of nested for loops is there a better way to organize this code? Also the way I add and remove enemies and lazers seems like a bad implementation. I set the index of the table to nil but then that index doesn't get reused when making more lazers/enemies.

Main

require "..libs.vector"
require "..libs.utility"
require "player"
require "enemy"


players = {}
joysticks = love.joystick.getJoysticks()
enemies = {}

function love.load( ... )
    love.window.setFullscreen(true)
    windowWidth, windowHeight = love.window.getMode()
    for _,v in pairs(joysticks) do
        local vid,pid,pv = v:getDeviceInfo()
        if vid == 1406 and pid == 8201 and pv == 273 then --Do not use wired connection
            break
        end
            table.insert(players,Player(v,windowWidth/2,windowHeight/2,250))    
    end
    table.insert(enemies,Grunt(windowWidth/2,windowHeight/2,players[1]))
    table.insert(enemies,Grunt(windowWidth/2 + 30,windowHeight/2,players[1]))
    table.insert(enemies,Grunt(windowWidth/2 + 60,windowHeight/2,players[1]))
    table.insert(enemies,Grunt(windowWidth/2 + 90,windowHeight/2,players[1]))
    table.insert(enemies,Rocket(windowWidth/2,windowHeight/2,math.pi / 2))
    table.insert(enemies,Rocket(windowWidth/2 + 30,windowHeight/2,math.pi / 2))
    table.insert(enemies,Rocket(windowWidth/2 + 60,windowHeight/2,math.pi / 2))
    table.insert(enemies,Rocket(windowWidth/2 + 90,windowHeight/2,math.pi / 2))
    table.insert(enemies,Rocket(windowWidth/2 + 120,windowHeight/2,math.pi / 4))
    table.insert(enemies,Rocket(windowWidth/2 + 150,windowHeight/2,math.pi / 2))
    table.insert(enemies,Rocket(windowWidth/2 + 180,windowHeight/2,math.pi / 2))
end

function love.update(dt)
    for _,player in pairs(players) do
        player:update(dt)
        for i,lazer in ipairs(player.lazers) do
            for j,enemy in ipairs(enemies) do
                local depth = isCircleCollision(
                lazer.position.x,lazer.position.y,lazer.bounds,
                enemy.position.x,enemy.position.y,enemy.bounds)
                print(depth)
                if depth < 30 then
                    enemy:delete()
                    table.remove(player.lazers,i)
                    table.remove(enemies,j)
                end 
            end
        end
    end
    for k,v in pairs(enemies) do
        v:update(dt)
    end
end
function love.draw()
    for _,v in pairs(players) do
        v:draw()
    end
    for k,v in pairs(enemies) do
        v:draw()
    end
end

Player

require "..libs.class"
require "..libs.utility"
theta = 0
Lazer = Class("Lazer")
Lazer.isLazer = true
Lazer.count = 0
function Lazer:init(x,y,speed,rax,ray)
    self.position = Vector2(x,y)
    self.speed = speed
    self.velocity = Vector2(rax,ray):unit()
    local direction = self.velocity:direction() -- + math.random(-10,10) * math.pi / 180
    local magnitude = self.velocity:magnitude()
    self.velocity = self.velocity:fromPolar(magnitude,direction)
    self.id = Lazer.count
    self.bounds = 5
    Lazer.count = Lazer.count + 1
end
function Lazer:update(dt,player)
    self.position = self.position + self.velocity * self.speed * dt
    if not isPointWithinRect(self.position.x,self.position.y,0,0,windowWidth,windowHeight) then
        for i,v in ipairs(player.lazers) do
            if v.id == self.id then
                table.remove(player.lazers,i)
            end
        end
    end
end
function Lazer:draw()
    -- love.graphics.setColor(self.position.x/windowWidth,self.position.y/windowHeight,0)
    -- love.graphics.setColor(clamp(math.sin(theta),.5,1),clamp(math.cos(theta),.5,1),clamp(math.tan(theta),.5,1))
    love.graphics.setColor(255,255,0)
    love.graphics.circle("line",self.position.x,self.position.y,self.bounds,5)
end
Lazer.locked = true

Player = Class("Player")
Player.isPlayer = true
function Player:init(joystick,x,y,speed)
    self.joystick = joystick
    self.position = Vector2(x,y)
    self.velocity = Vector2(0,0)
    self.speed = speed
    self.acceleration = acceleration
    self.terminal_velocity = terminal_velocity
    self.lazzer_speed = speed + 25
    self.lazers = {}
    self.bounds = 15
    self.lives = 3
    self.timer = 0
    self.source = love.audio.newSource("res/pew.wav","static")
end
function Player:update(dt)
    theta = theta + .05
    self.timer = self.timer + dt
    local lax,lay = self.joystick:getAxes()
    self.velocity.x = lax
    self.velocity.y = lay
    if math.abs(lax) > .1 or math.abs(lay) > .1 then
        self.velocity = self.velocity:unit()
    end
    self.position = self.position + self.velocity * self.speed * dt
    self.position.x = clamp(self.position.x,0 + self.bounds,windowWidth - self.bounds)
    self.position.y = clamp(self.position.y,0 + self.bounds,windowHeight - self.bounds)
    local _,_,rax,ray = self.joystick:getAxes()
    if (math.abs(rax) > .1 or math.abs(ray) > .1) and self.timer > .1 then
        table.insert(self.lazers,Lazer(self.position.x,self.position.y,self.speed + 250,rax,ray))
        love.audio.play(self.source)
        self.timer = 0
    end
    for _,v in pairs(self.lazers) do
        v:update(dt,self)
    end
end
function Player:draw()
    love.graphics.setColor(255,255,255,255)
    love.graphics.circle("line",self.position.x,self.position.y,self.bounds,30)
    for _,v in pairs(self.lazers) do
        v:draw()
    end
end
Player.locked = true

Enemy

require "..libs.class"
require "..libs.vector"

Enemy = Class("Enemy")
Enemy.isEnemy = true
function Enemy:init(x,y,speed,bounds,color)
    self.position = Vector2(x,y)
    self.velocity = Vector2(0,0)
    self.speed = speed
    self.bounds = bounds
    self.color = color or {r=255,g=255,b=255}
    self.source = love.audio.newSource("res/explosion.wav","static")
end
function Enemy:draw()
    love.graphics.setColor(self.color.r,self.color.g,self.color.b)
    love.graphics.circle("line",self.position.x,self.position.y,self.bounds,15)
end
function Enemy:delete()
    love.audio.play(self.source)
    self = nil
end
Enemy.locked = true

Grunt = Class("Grunt",{},Enemy)
Grunt.isGrunt = true
function Grunt:init(x,y,target)
    local speed = 100
    local bounds = 10
    Enemy.init(self,x,y,speed,bounds,{r=0/255,g=255/255,b=255/255})
    self.target = target
end
function Grunt:update(dt)
    local dx = self.target.position.x - self.position.x
    local dy = self.target.position.y - self.position.y
    local direction = math.atan2(dy,dx)
    self.velocity = self.velocity:fromPolar(self.speed,direction)
    self.position = self.position + self.velocity * dt
end
Grunt.locked = true

Rocket = Class("Rocket",{}, Enemy)
Rocket.isRocket = true
function Rocket:init(x,y,direction)
    local speed = 175
    local bounds = 10
    Enemy.init(self,x,y,speed,bounds,{r=255/255,g=165/255,b=0/255})
    self.direction = direction
end
function Rocket:update(dt)
    if self.position.x + self.bounds + 5 > windowWidth or self.position.y + self.bounds + 1 > windowHeight or self.position.x - self.bounds - 1 < 0 or self.position.y - self.bounds - 5 < 0 then
        self.direction = self.direction + math.pi
    end
    self.velocity = self.velocity:fromPolar(self.speed,self.direction)
    self.position = self.position + self.velocity * dt
    self.position.x = clamp(self.position.x,0 + self.bounds,windowWidth - self.bounds)
    self.position.y = clamp(self.position.y,0 + self.bounds,windowHeight - self.bounds)
end
Rocket.locked = true
\$\endgroup\$
  • \$\begingroup\$ Im using the nata library now. Nata is an entity management system. \$\endgroup\$ – dylan Jul 2 at 2:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.