I'm creating a sort of Galaga clone for my final project, and I've hit a major road block, I can't figure out to make multiple enemies spawn in my game. At the moment, I just want to be able to spawn a bunch of enemies just for the sake of seeing how it works. Eventually, I want to program it so that a certain amount of enemies spawn depending on what wave the player is on...
I'm not too sure exactly where or even how to implement an enemy table, I just know I have to...
Here's my main.lua file
Code: Select all
push = require 'push'
WINDOW_WIDTH = 1280
WINDOW_HEIGHT = 720
VIRTUAL_WIDTH = 1280
VIRTUAL_HEIGHT = 720
function love.load()
Object = require "Classic"
require 'player'
require 'enemy'
require 'bullet'
player = Player()
enemy = Enemy()
listofBullets = {}
love.graphics.setDefaultFilter('nearest', 'nearest')
title = love.graphics.newFont('fonts/Stars Fighters.ttf', 45)
start = love.graphics.newFont('fonts/robo.ttf', 30)
menu = love.graphics.newFont('fonts/robo.ttf', 40)
push:setupScreen(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT, {
fullscreen = false,
vsync = true,
resize = true
})
love.window.setTitle('Titania')
background = love.graphics.newImage('graphics/space.png')
gameState = 'start'
game_paused = false
end
function love.resize(w, h)
push:resize(w, h)
end
function love.update(dt)
if game_paused == false then
player:update(dt)
for i,v in ipairs(listofBullets) do
v:update(dt)
v:checkCollision(enemy)
if v.dead then
table.remove(listofBullets, i)
end
end
end
if gameState == 'play' then
enemy:update(dt)
end
end
function love.keypressed(key)
if key == 'escape' then
love.event.quit()
end
if key == 'enter' or key == 'return' and gameState == 'start' then
gameState = 'menu'
end
if key == 's' and gameState == 'menu' then
gameState = 'play'
elseif key == 'h' and gameState == 'menu' then
gameState = 'help'
elseif key == 'e' or key == 'escape' and gameState == 'menu' then
love.event.quit()
end
if key == 'backspace' and gameState == 'help' then
gameState = 'menu'
end
if key == 'p' and gameState == 'play' then
game_paused = true
gameState = 'pause'
elseif key == 'p' and gameState == 'pause' then
game_paused = false
gameState = 'play'
end
player:keypressed(key)
end
function love.draw()
push:apply('start')
-- supposed to keep the background scroling??????
for i = 0, love.graphics.getWidth() / background:getWidth() do
for j = 0, love.graphics.getHeight() / background:getHeight() do
love.graphics.draw(background, i * background:getWidth(), j * background:getHeight())
end
end
if gameState == 'start' then
love.graphics.setFont(title)
love.graphics.printf('Titania', 0, 30, VIRTUAL_WIDTH, 'center')
love.graphics.setFont(start)
love.graphics.printf("Press Enter", 0, 500, VIRTUAL_WIDTH, 'center')
elseif gameState == 'menu' then
love.graphics.setFont(title)
love.graphics.printf('Titania', 0, 30, VIRTUAL_WIDTH, 'center')
love.graphics.setFont(menu)
love.graphics.printf("[S]TART [H]ELP [E]XIT", 0, 500, VIRTUAL_WIDTH, 'center')
elseif gameState == 'help' then
-- draw the player
player:draw()
love.graphics.setFont(title)
love.graphics.printf('Titania', 0, 30, VIRTUAL_WIDTH, 'center')
love.graphics.setFont(menu)
love.graphics.printf("Use the ARROW keys or WASD to move and SPACE to shoot", 0, 500, VIRTUAL_WIDTH, 'center')
elseif gameState == 'play' then
-- draw the player
player:draw()
-- draw the enemy
enemy:draw()
-- text
love.graphics.setFont(title)
love.graphics.printf('TEST WAVE 1', 0, 30, VIRTUAL_WIDTH, 'center')
elseif gameState == 'pause' then
player:draw()
enemy:draw()
love.graphics.setFont(title)
love.graphics.printf('PAUSE', 0, 250, VIRTUAL_WIDTH, 'center')
end
for i,v in ipairs(listofBullets) do
v:draw()
end
push:apply('end')
end
Code: Select all
Enemy = Object:extend()
function Enemy:new()
self.image = love.graphics.newImage('graphics/blueship.png')
-- table function???
enemy = {}
--[[
this will likely be changed from "timer" to "wave" when I find the
proper way to implement the idea
]]
self.timer = 0
self.timerLim = 2 --math.random(1, 3)
self.amount = 4 --math.random(2, 5)
self.side = math.random(1, 4)
self.x = 300
self.y = 20
self.speed = 300
self.width = self.image:getWidth()
self.height = self.image:getHeight()
self.xvel = 0
self.yvel = 0
self.friction = 10
self.health = 1
end
function Enemy:update(dt)
--self.x = self.x + self.speed * dt -- you commented this out to test stuff
local window_width = love.graphics.getWidth()
local window_height = love.graphics.getHeight()
--[[
this should assist with generating multiple enemies on the screen.
hopefully we'll be able to make them "fly in" from the top of the screen...
for now, they spawn from all over the place
]]
self.timer = self.timer + dt
if self.timer > self.timerLim then
--spawn the enemy
for i = 1,self.amount do
if self.side == 1 then -- LEFT
enemy:spawn(-self.height, window_height / 2 - (self.height / 2))
end
if self.side == 2 then -- TOP
enemy:spawn(window_width / 2 - (self.width / 2), -self.height)
end
if self.side == 3 then -- RIGHT
enemy:spawn(window_width, window_height / 2 - (self.height / 2))
end
if self.side == 4 then -- BOTTOM
enemy:spawn(window_width / 2 - (self.width / 2), window_height)
end
self.side = math.random(1, 4)
end
self.timerLim = 2 --math.random(1, 3)
self.timer = 0
self.amount = 4 --math.random(2, 5)
end
--[[
this whole setup here establishes the enemy tracking the player
currently the enemy follows the player pretty aggressively
we'll fix that later...
]]
for i,v in ipairs(enemy) do
self.x = self.x + self.xvel * dt
self.y = self.y + self.yvel * dt
self.xvel = self.xvel * (1 - math.min(dt * self.friction, 1))
self.yvel = self.yvel * (1 - math.min(dt * self.friction, 1))
end
for i,v in ipairs(enemy) do
-- TRACK X AXIS
if player.x + player.width / 2 < self.x + self.width / 2 then
if self.xvel > -self.speed then
self.xvel = self.xvel - self.speed * dt
end
elseif player.x + player.width / 2 > self.x + self.width / 2 then
if self.xvel < self.speed then
self.xvel = self.xvel + self.speed * dt
end
end
-- TRACK THE Y AXIS
if player.y + player.height / 2 < self.y + self.height / 2 then
if self.yvel > -self.speed then
self.yvel = self.yvel - self.speed * dt
end
elseif player.y + player.height / 2 > self.y + self.height / 2 then
if self.yvel < self.speed then
self.yvel = self.yvel + self.speed * dt
end
end
end
end
function Enemy:spawn(x, y)
table.insert(enemy, {x = x, y = y, self.xvel, self.yvel, self.health})
end
function Enemy:draw()
for i,v in ipairs(enemy) do
love.graphics.draw(self.image, self.x, self.y)
end
end