Trying to change my enemy's image when collision detected
Posted: Sun Nov 30, 2014 7:56 am
I have "Boss" class, and its got properties defined for its default image and hit image. On the collision detction function I have, I start off with setting the boss.image to its default image, and then in the loop for the collision detection, if detects a hit, it changes boss.image to equal the hit image. The problem I have is that when I am shooting the boss, it reflects the image change almost half the time, it doesnt work properly. I can shoot the boss 10 times in a row and sometimes it doesnt show the image change.
love file: https://docs.google.com/uc?authuser=0&i ... t=download
zip: https://docs.google.com/uc?authuser=0&i ... t=download
Boss class:
Collision detection for boss getting hit:
Full source:
love file: https://docs.google.com/uc?authuser=0&i ... t=download
zip: https://docs.google.com/uc?authuser=0&i ... t=download
Boss class:
Code: Select all
-- Boss
function Boss.init()
local self = {}
self.x = 100
self.y = 70
self.direction = 1
self.bullets = {}
self.image = love.graphics.newImage("img/nawaz.png")
self.hit_sound = love.audio.newSource("sounds/hit.wav")
self.width = self.image:getWidth()
self.height = self.image:getHeight()
self.health = 100
self.phase = 1
self.img_hit = love.graphics.newImage("img/nawaz_hit.png")
self.img_def = love.graphics.newImage("img/nawaz.png")
function self:draw()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(self.image, self.x, self.y)
end
function self:update(dt)
if self.phase == 1 then
if boss_bullet_mark == 1 then
dt_boss_bullet_mark = love.timer.getTime()
boss_bullet_mark = 0
end
if love.timer.getTime() > dt_boss_bullet_mark + 0.5 then
spawn_boss_bullet(self.x + self.width/2, self.y + self.height, player.x, player.y, self.bullets)
boss_bullet_mark = 1
end
if self.direction == 1 then
self.x = self.x + 50 * dt
else
self.x = self.x - 50 * dt
end
if self.x > screen_width - self.width then
self.direction = 0
elseif self.x < 0 then
self.direction = 1
end
end
end
return self
end
Code: Select all
-- Check collisions
function check_collision(player, players_bullets, enemy)
enemy.image = enemy.img_def
for i=#players_bullets, 1, -1 do
bullet = players_bullets[i]
if (bullet.y >= enemy.y and bullet.y <= (enemy.y + enemy.height) and bullet.x >= enemy.x and bullet.x <= (enemy.x + enemy.width)) then
table.remove(players_bullets, i)
enemy.image = enemy.img_hit
enemy.hit_sound:play()
player.score = player.score + 1
end
end
end
Code: Select all
love.window.setMode(640, 700, {vsync = false})
-- global vars
screen_width = love.graphics.getWidth()
screen_height = love.graphics.getHeight()
stage = 1
dt_mark = 0
set_mark = 1
boss_bullet_mark = 1
dt_boss_bullet_mark = 0
-- Creating tables
Level_One = {}
Player = {}
StartScreen = {}
Bullet = {}
Boss = {}
Boss_Bullet = {}
-- Boss
function Boss.init()
local self = {}
self.x = 100
self.y = 70
self.direction = 1
self.bullets = {}
self.image = love.graphics.newImage("img/nawaz.png")
self.hit_sound = love.audio.newSource("sounds/hit.wav")
self.width = self.image:getWidth()
self.height = self.image:getHeight()
self.health = 100
self.phase = 1
self.img_hit = love.graphics.newImage("img/nawaz_hit.png")
self.img_def = love.graphics.newImage("img/nawaz.png")
function self:draw()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(self.image, self.x, self.y)
end
function self:update(dt)
if self.phase == 1 then
if boss_bullet_mark == 1 then
dt_boss_bullet_mark = love.timer.getTime()
boss_bullet_mark = 0
end
if love.timer.getTime() > dt_boss_bullet_mark + 0.5 then
spawn_boss_bullet(self.x + self.width/2, self.y + self.height, player.x, player.y, self.bullets)
boss_bullet_mark = 1
end
if self.direction == 1 then
self.x = self.x + 50 * dt
else
self.x = self.x - 50 * dt
end
if self.x > screen_width - self.width then
self.direction = 0
elseif self.x < 0 then
self.direction = 1
end
end
end
return self
end
-- Boss Bullet
function Boss_Bullet.init(boss_x, boss_y, dx, dy)
local self = {}
self.width = 5
self.height = 5
self.x = boss_x
self.y = boss_y
self.dx = dx
self.dy = dy
self.player_x = player_x
self.player_y = player_y
self.color = {102, 51, 0}
function self:draw()
love.graphics.setColor(self.color)
love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)
end
function self:update(dt)
self.x = self.x + (self.dx * dt)
self.y = self.y + (self.dy * dt)
end
return self
end
-- Update the position of the bullets
function update_boss_bullets(boss_bullets, dt)
for i=#boss_bullets, 1, -1 do
bb = boss_bullets[i]
bb:update(dt)
if bb.y > screen_height then
table.remove(boss_bullets, i)
end
end
end
-- Draw all the bullets to the screen
function draw_boss_bullets(boss_bullets)
for i=#boss_bullets, 1, -1 do
bb = boss_bullets[i]
bb:draw()
end
end
function spawn_boss_bullet(boss_x, boss_y, player_x, player_y, boss_bullets)
local angle = math.atan2((player_y - boss_y), (player_x - boss_x))
local dx = 100 * math.cos(angle)
local dy = 100 * math.sin(angle)
bb = Boss_Bullet.init(boss_x, boss_y, dx, dy)
table.insert (boss_bullets, bb)
end
-- Level One
function Level_One.init()
local self = {}
self.music = love.audio.newSource("sounds/hold_me_back_end.mp3")
function self:draw()
love.graphics.setColor(25, 25, 25)
love.graphics.rectangle("fill", 0, 0, screen_width, screen_height)
end
return self
end
-- Player
function Player.init()
local self = {}
self.width = 25
self.height = 25
self.x = (screen_width/2) - (self.width / 2)
self.y = (screen_height) - (self.height * 2)
self.bullets = {}
self.gun_sound = love.audio.newSource("sounds/shot.wav")
self.bullet_x = self.x - self.width/2
self.bullet_y = self.y
self.score = 0
self.hit_sound = love.audio.newSource("sounds/player_hit.wav")
self.alive = true
self.score_font = love.graphics.newFont("font/PressStart2P.ttf", 20)
self.score_text = "SCORE:"
function self:draw()
love.graphics.setColor(127, 140, 141)
love.graphics.setFont(self.score_font)
love.graphics.print(self.score_text..tostring(self.score), 10, 10)
if self.alive == true then
love.graphics.setColor(46, 204, 113)
love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)
end
end
function self:shoot()
self.bullet_x = (self.x + self.width/2) - (2.5)
self.bullet_y = self.y
b = Bullet.init(self.bullet_x, self.bullet_y)
table.insert (self.bullets, b)
end
function self:update(dt)
if self.alive == true then
if self.x > screen_width - self.width then
self.x = screen_width - self.width
end
if self.x < 0 then
self.x = 0
end
if self.y < 0 then
self.y = 0
end
if self.y > screen_height - self.height then
self.y = screen_height - self.height
end
if love.keyboard.isDown( "up" ) then
self.y = self.y - 200 * dt
end
if love.keyboard.isDown( "down" ) then
self.y = self.y + 200 * dt
end
if love.keyboard.isDown( "right" ) then
self.x = self.x + 200 * dt
end
if love.keyboard.isDown( "left" ) then
self.x = self.x - 200 * dt
end
if love.keyboard.isDown( "lctrl" ) then
if set_mark == 1 then
dt_mark = love.timer.getTime()
set_mark = 0
end
if love.timer.getTime() > dt_mark + 0.2 then
self:shoot(dt)
self.gun_sound:play()
set_mark = 1
end
end
end
end
return self
end
-- Bullet
function Bullet.init(x, y)
local self = {}
self.width = 5
self.height = 5
self.x = x
self.y = y
function self:draw()
love.graphics.setColor(231, 76, 60)
love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)
end
function self:update(dt)
self.y = self.y - 500 * dt
end
return self
end
-- Update the position of the bullets
function update_bullets(players_bullets, dt)
for i=#players_bullets, 1, -1 do
bullet = players_bullets[i]
bullet:update(dt)
if bullet.y < -10 then
table.remove(players_bullets, i)
end
end
end
-- Draw all the bullets to the screen
function draw_bullets(players_bullets)
for i=#players_bullets, 1, -1 do
bullet = players_bullets[i]
bullet:draw()
end
end
-- Check collisions
function check_collision(player, players_bullets, enemy)
enemy.image = enemy.img_def
for i=#players_bullets, 1, -1 do
bullet = players_bullets[i]
if (bullet.y >= enemy.y and bullet.y <= (enemy.y + enemy.height) and bullet.x >= enemy.x and bullet.x <= (enemy.x + enemy.width)) then
table.remove(players_bullets, i)
enemy.image = enemy.img_hit
enemy.hit_sound:play()
player.score = player.score + 1
end
end
end
-- Check boss bullet collisions
function check_boss_bullet_collision(player, boss_bullets)
if player.alive == true then
for i=#boss_bullets, 1, -1 do
bb = boss_bullets[i]
if (bb.y >= player.y and bb.y <= (player.y + player.height) and bb.x >= player.x and bb.x <= (player.x + player.width)) then
table.remove(boss_bullets, i)
player.hit_sound:play()
player.alive = false
end
end
end
end
-- Check for game over
function check_game_over(player)
if player.alive == false then
love.graphics.setColor(0, 0, 0, 200)
love.graphics.rectangle("fill", 0, 0, screen_width, screen_height)
game_over_font = love.graphics.newFont("font/PressStart2P.ttf", 40)
game_over_text = "GAME OVER"
love.graphics.setColor(231, 76, 60)
love.graphics.setFont(game_over_font)
love.graphics.print(game_over_text, (screen_width/2) - (game_over_font:getWidth(game_over_text)/2), (screen_height/2) - (game_over_font:getHeight(game_over_text)/2))
end
end
-- Start Screen
function StartScreen.init()
local self = {}
self.music = love.audio.newSource("sounds/hold_me_back_start.mp3")
self.start_text = "Tap to Start!"
self.title_text = "HARAM ZADON"
self.credit_text = "© 2014 Super Mega Turbo"
self.screen_font = love.graphics.newFont("font/PressStart2P.ttf", 20)
self.title_font = love.graphics.newFont("font/PressStart2P.ttf", 40)
self.credit_font = love.graphics.newFont("font/PressStart2P.ttf", 12)
self.start_text_width = self.screen_font:getWidth(self.start_text)
self.start_text_height = self.screen_font:getHeight(self.start_text)
self.title_text_width = self.title_font:getWidth(self.title_text)
self.credit_text_width = self.credit_font:getWidth(self.credit_text)
self.title_text_height = self.title_font:getHeight(self.title_text)
self.blink = true
self.dt = 0
function self:draw()
love.graphics.setFont(self.title_font)
love.graphics.setColor(155, 89, 182)
love.graphics.print(self.title_text, (screen_width/2) - (self.title_text_width/2), 200)
love.graphics.setFont(self.credit_font)
love.graphics.setColor(255, 255, 255)
love.graphics.print(self.credit_text, (screen_width/2) - (self.credit_text_width/2), (screen_height - 200))
love.graphics.setFont(self.screen_font)
love.graphics.setColor(255, 255, 255)
if self.blink == true then
love.graphics.print(self.start_text, (screen_width/2) - (self.start_text_width/2), (screen_height/2) - (self.start_text_height/2))
end
end
function self:update(dt)
self.music:play()
self.dt = self.dt + dt
if self.dt > 0.5 then
self.blink = not self.blink
self.dt = self.dt - 0.5
end
end
return self
end
-- Creating instances
start_screen = StartScreen.init()
level_one = Level_One.init()
player = Player.init()
boss = Boss.init()
-- Love game loop
function love.load()
love.graphics.setBackgroundColor(0, 0, 0)
end
function love.draw()
if stage == 0 then
start_screen:draw()
elseif stage == 1 then
level_one:draw()
player:draw()
boss:draw()
draw_bullets(player.bullets)
draw_boss_bullets(boss.bullets)
check_game_over(player)
end
end
function love.update(dt)
if love.keyboard.isDown( "return" ) then
stage = 1
end
if stage == 0 then
start_screen:update(dt)
elseif stage == 1 then
start_screen.music:stop()
level_one.music:play()
level_one.music:setVolume(0.0);
player:update(dt)
boss:update(dt)
update_bullets(player.bullets, dt)
update_boss_bullets(boss.bullets, dt)
check_collision(player, player.bullets, boss)
check_boss_bullet_collision(player, boss.bullets)
end
end