[SOLVED] (breakout clone) powered up big ball doesn't remove several bricks at once
Posted: Tue Feb 12, 2019 4:01 pm
Hello everyone!
I'm currently working on a power-up for my endless breakout clone where the ball becomes big (with the intent to remove several bricks at once). Upon collision, the big ball collides with a set of 3 bricks. when the ball collides with the bricks, it removes the first and the third bricks but not the second(see attached gif for a visual explanation) IMPORTANT: the attached GIF has flashing colors!
What I actually want to happen is that when the Ball collides, is that it removes all three bricks at once. The bricks are part of a table. If I've understood my problem correctly, it removes the elements and moves the "list" of Bricks into a new "position" in that list.
Ball.lua
Powerup.lua
Brick.lua
I thank you for your patience, if there's something that's unclear or needs to be specified better, please let me know!
I'm currently working on a power-up for my endless breakout clone where the ball becomes big (with the intent to remove several bricks at once). Upon collision, the big ball collides with a set of 3 bricks. when the ball collides with the bricks, it removes the first and the third bricks but not the second(see attached gif for a visual explanation) IMPORTANT: the attached GIF has flashing colors!
What I actually want to happen is that when the Ball collides, is that it removes all three bricks at once. The bricks are part of a table. If I've understood my problem correctly, it removes the elements and moves the "list" of Bricks into a new "position" in that list.
Ball.lua
Code: Select all
Player = require "Player"
Bricks = require "Brick"
powerUp = require "Powerup"
numActiveBalls = 1
Balls = {}
ballsController = {}
ballsController.balls = {}
--bonusBall = {}
ballSprite = love.graphics.newImage("ball.png")
function ballsController.spawnBall(posX, posY)
Ball = {}
Ball.ballPosX = Player.posX - 8 -- posX
Ball.ballPosY = Player.posY - 16 --posY
Ball.ballOriginX = 0
Ball.ballOriginY = 0
Ball.ballOrientation = 0
Ball.ballScaleFactor = 1
Ball.ballWidth = ballSprite:getWidth()
Ball.ballHeight = ballSprite:getHeight()
Ball.ballSpeed = 300
Ball.ballMaxSpeed = 580
love.math.setRandomSeed(love.timer.getTime())
Ball.ballDirX = 0
Ball.ballDirY = 1
Ball.ballClampRoof = 0
Ball.ballClampLeft = 0
Ball.isBallAlive = true
Ball.stuckToPlayer = true
Ball.extraSizeFactor = 1
table.insert(ballsController.balls, Ball)
end
function Balls:ballStart()
if (Ball.stuckToPlayer) then
Ball.ballPosX = Player.posX - 8
Ball.ballPosY = Player.posY - 16
end
end
function Balls:handlePlayerBounce(isPlayer)
local playerHalfWidth = Player.Sprite:getWidth() * 0.5
local playerHalfHeight = Player.Sprite:getHeight() * 0.5
local playerPosX = 0
local playerPosY = 0
local playerOriginOffset = 35
if isPlayer then
playerPosX = Player.posX
playerPosY = Player.posY + playerOriginOffset -- ball origin offset
end
local playerToBallX = Ball.ballPosX + Ball.ballWidth * 0.5 - playerPosX
local playerToBallY = Ball.ballPosY - playerPosY
local ballToPlayerLength = math.sqrt(playerToBallX * playerToBallX +
playerToBallY * playerToBallY)
Ball.ballDirX = playerToBallX / ballToPlayerLength
Ball.ballDirY = playerToBallY / ballToPlayerLength
end
function Balls:handleBrickBounce()
Ball.ballDirY = - Ball.ballDirY
end
function Balls:ballHitRoof()
if Ball.ballPosY < Ball.ballClampRoof then
Ball.ballPosY = ballSprite:getHeight()
Ball.ballDirY = -Ball.ballDirY
end
end
function Balls:ballHitLeft()
if Ball.ballPosX < 0 then
Ball.ballPosX = 0
Ball.ballDirX = -Ball.ballDirX
end
end
function Balls:ballHitRight()
-- When the Ball collides with the right wall, change direction
if Ball.ballPosX + ballSprite:getWidth() * Ball.extraSizeFactor >
Window.Width then
Ball.ballDirX = -Ball.ballDirX
end
end
function Balls:ballHitPlayer()
local playerHalfWidth = Player.Sprite:getWidth() * 0.5
local playerHalfHeight = Player.Sprite:getHeight() * 0.5
local ballWidth = ballSprite:getWidth() * Ball.extraSizeFactor
local ballHeight = ballSprite:getHeight() * Ball.extraSizeFactor
if Ball.ballPosX <=
Player.posX + playerHalfWidth and
Ball.ballPosY + ballHeight >= Player.posY and
Ball.ballPosY < Player.posY + Player.Height and
Ball.ballPosX + ballWidth >= Player.posX - playerHalfWidth then
Balls:handlePlayerBounce(true)
end
end
function Balls:ballHitBrick()
local brickWidth = brickSprite:getWidth()
local brickHeight = brickSprite:getHeight()
local ballWidth = ballSprite:getWidth() * Ball.extraSizeFactor
local ballHeight = ballSprite:getHeight() * Ball.extraSizeFactor
local hasCollided = false
-- Here's where the Balls collision with Bricks happens
for i,b in ipairs(bricksLineController.bricks) do
if ((Ball.ballPosX <= (b.brickPosX + brickWidth)) and
((Ball.ballPosX + ballWidth) >= b.brickPosX) and
((Ball.ballPosY + ballHeight) >= b.brickPosY) and
(Ball.ballPosY < b.brickPosY + brickHeight)) then
if hasCollided == false then
Balls:handleBrickBounce()
hasCollided = true
end
--print("Ball hit Brick")
if b.isPowerUp then
powerUpsController:spawnPowerUp(b.brickPosX, b.brickPosY)
end
-- Highscore multiplier, multiplier will increase by 1 every 5th Brick
Manager.countToTriggerMultiplier = Manager.countToTriggerMultiplier + 1
if Manager.countToTriggerMultiplier >= Manager.triggerMultiplier then
Manager.hasMultiplier = true
Manager.scoreMultiplier = Manager.scoreMultiplier + 1
Manager.countToTriggerMultiplier = 0
end
Manager.Highscore = Manager.Highscore + 10 * Manager.scoreMultiplier
end
end
--[[
local isColliding = true
while(isColliding) do
Ball.ballPosX = Ball.ballPosX + (Ball.ballDirX * Ball.ballSpeed * 0.01)
Ball.ballPosY = Ball.ballPosY + (Ball.ballDirY * Ball.ballSpeed * 0.01)
isColliding = (Ball.ballPosX <= (b.brickPosX + brickWidth)) and
((Ball.ballPosX + ballWidth) >= b.brickPosX) and
((Ball.ballPosY + ballHeight) >= b.brickPosY) and
(Ball.ballPosY < b.brickPosY + brickHeight)
end
]]
end
-- Update Ball if it's outside the screen
function Balls:ballReset()
if Ball.ballPosY > Window.Height then
-- Reset the Ball and Multiplier
ballsController.spawnBall(Ball)
Manager.hasMultiplier = false
Manager.scoreMultiplier = 1
Manager.countToTriggerMultiplier = 0
end
end
function Balls:update(dt)
Balls:ballStart()
-- Update "collisions" between the game window, bricks and player
Balls:ballHitRoof()
Balls:ballHitLeft()
Balls:ballHitRight()
Balls:ballHitPlayer()
Balls:ballHitBrick()
Balls:ballReset()
-- note: create a "tag" system so
if isPowerUpActive == true then
-- When the power-up is active, start counting down from 30
powerUpTimer = powerUpTimer - love.timer.getDelta()
end
-- When the timer has reached 0, reset the Ball size
if powerUpTimer <= 0 then
isPowerUpActive = false
Ball.extraSizeFactor = 1
Ball.ballScaleFactor = 1
powerUpTimer = addTime
end
-- Manages several balls
for _,b in pairs(ballsController.balls) do
b.ballPosX = b.ballPosX + (b.ballDirX * b.ballSpeed * dt)
b.ballPosY = b.ballPosY + (b.ballDirY * b.ballSpeed * dt)
end
end
function Balls:draw()
-- Draws several balls
for _, b in pairs(ballsController.balls) do
love.graphics.draw(ballSprite,
b.ballPosX,
b.ballPosY,
b.ballOrientation,
b.ballScaleFactor,
b.ballScaleFactor,
b.ballOriginX,
b.ballOriginY)
end
end
function Balls:keypressed(key)
-- Makes the ball "unstuck" from player
if key == "space" then
Ball.stuckToPlayer = false
print("In Ball:keypressed")
end
end
return Balls
Code: Select all
Brick = require "Brick"
--Ball = require "Ball"
Player = require "Player"
powerUpDoubleBallSprite = love.graphics.newImage("doubleBallSprite.png")
powerUpDoubleBallColor = {}
powerUpBigBallSprite = love.graphics.newImage("bigBallSprite.png")
isPowerUpActive = false
addTime = 30
powerUpTimer = addTime
powerUpsController = {}
powerUpsController.powerups = {}
function powerUpsController:spawnPowerUp(posX, posY)
powerUp = {}
powerUp.powerUpPosX = posX
powerUp.powerUpPosY = posY
powerUp.powerUpOrientation = 0
powerUp.powerUpScaleX = 1
powerUp.powerUpScaleY = 1
powerUp.powerUpOriginX = 0
powerUp.powerUpOriginY = 0
powerUp.powerUpVelocity = 2
powerUp.powerUpDoubleX = Ball.ballPosX
powerUp.powerUpDoubleY = Ball.ballPosY
powerUp.powerUpAddSizeFactor = 9
local randomizePowerUp = 1
if randomizePowerUp == 1 then
powerUp.setRandomPowerUp = powerUpBigBallSprite
end
table.insert(powerUpsController.powerups, powerUp)
end
function powerUpsController:doubleBall()
--[[
if something then
ballsController.spawnBall(Ball) -- But should it be here then?
end
]]
end
function powerUpsController:bigBall()
Ball.extraSizeFactor = powerUp.powerUpAddSizeFactor
Ball.ballScaleFactor = Ball.extraSizeFactor
end
function powerUpsController:update(dt)
local playerHalfWidth = Player.Width * 0.5
local playerHalfHeight = Player.Height * 0.5
local randomizePowerUp = 1
-- Removes power-up if it moves "outside" of the screen
for i, p in pairs(powerUpsController.powerups) do
-- Moves the power-up positively on Y
p.powerUpPosY = p.powerUpPosY + p.powerUpVelocity
local powerUpWidth = p.setRandomPowerUp:getWidth()
local powerUpHeight = p.setRandomPowerUp:getHeight()
if ((p.powerUpPosX <= (Player.posX + playerHalfWidth)) and
((p.powerUpPosX + powerUpWidth) >= Player.posX - playerHalfWidth) and
((p.powerUpPosY + powerUpHeight) >= Player.posY) and
(p.powerUpPosY < Player.posY + playerHalfHeight)) then
isPowerUpActive = true
if p.setRandomPowerUp == powerUpBigBallSprite then
powerUpsController.bigBall()
end
-- Adds 1000 points to Highscore and removes power-up
Manager.Highscore = Manager.Highscore + 1000
table.remove(powerUpsController.powerups, i)
end
-- Removes power-up if it reaches a certain point
if p.powerUpPosY >= 950 then
table.remove(powerUpsController.powerups, i)
end
end
end
function powerUpsController:draw()
--[[
Depending on what power-up that spawns, change 'setRandomUp' (which is nil)
into the appropriate Sprite.
]]
if isPowerUpActive == true then
love.graphics.print(math.floor(powerUpTimer),
love.graphics.getWidth() * 0.5,
love.graphics.getHeight() - 50)
elseif powerUpTimer <= 0 then
isPowerUpActive = false
end
for _,p in ipairs(powerUpsController.powerups) do
love.graphics.setColor(1, 0, 0, 1)
love.graphics.rectangle("fill", p.powerUpPosX, p.powerUpPosY, 4, 4)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(p.setRandomPowerUp,
p.powerUpPosX,
p.powerUpPosY,
p.powerUpOrientation,
p.powerUpScaleX,
p.powerUpScaleY,
p.powerUpOriginX,
p.powerUpOriginY)
end
end
--love.graphics.setColor(1, 1, 1, 1)
return powerUpsController
Code: Select all
Player = require "Player"
Bricks = {}
-- Find a method to place next set of brick lines directly the first one?
bricksLineTimer = 2
bricksLineController = {}
bricksLineController.bricks = {}
-- Moved this variables outside of Controller to make the bricks usable
brickSprite = love.graphics.newImage("brick.png")
function bricksLineController.spawnBrick(posX, posY)
Brick = {}
--Brick.brickSprite = love.graphics.newImage("brick.png")
Brick.brickPosX = posX
Brick.brickPosY = posY
Brick.brickWidth = brickSprite:getWidth()
Brick.brickHeight = brickSprite:getHeight()
Brick.brickOriginX = 0
Brick.brickOriginY = 0
Brick.brickSpeed = 0.009
if love.math.random(1, 5) < 5 then
--print("YES")
Brick.isPowerUp = true
else
Brick.isPowerUp = false
--print("NO")
end
table.insert(bricksLineController.bricks, Brick)
end
function Bricks:load()
end
function Bricks:update(dt)
bricksLineTimer = bricksLineTimer - 0.01
brickHighestYPos = 1000
for _, b in pairs(bricksLineController.bricks) do
if b.brickPosY < brickHighestYPos then
brickHighestYPos = b.brickPosY - 23
end
end
--print("Brick Pos Y: "..brickHighestYPos)
if( brickHighestYPos > -24) then
for i = 0, 16 do
for j = 1, 1 do
-- 'i' is the one that spawns the bricks
-- 'j' is the one that sets the height of the bricks
-- Start spawning brick lines here?
-- and maybe spawn 3 - 4 lines ahead?
bricksLineController.spawnBrick(i * 50, -24)
end
end
end
for _,b in pairs(bricksLineController.bricks) do
b.brickPosY = b.brickPosY + b.brickSpeed
end
for i, b in ipairs(bricksLineController.bricks) do
if b.brickPosY >= 900 then
table.remove(bricksLineController.bricks, i)
print("Removed BRICKS")
end
end
end
function Bricks:draw()
local powerUpBrickColor = {math.random(0, 255) / 255,
math.random(0, 255) / 255,
math.random(0, 255) / 255,
1}
for _, b in ipairs(bricksLineController.bricks) do
if b.isPowerUp then
love.graphics.setColor(powerUpBrickColor)
else
love.graphics.setColor(1, 1, 1, 1)
end
love.graphics.draw(brickSprite,
b.brickPosX,
b.brickPosY,
0, 1, 1)
end
love.graphics.setColor(1, 1, 1, 1)
end
return Bricks
I thank you for your patience, if there's something that's unclear or needs to be specified better, please let me know!