Page 1 of 2

[SOLVED] Collectible Object Spawns On Player Which Increases Score More Than Once

Posted: Tue Jun 07, 2022 11:44 pm
by AdonisMF
Hello everyone!


The game
I'm working on my first small Love game to learn Lua and Love2d mechanics the game consists of a player who collects apples to increase the score. There is a timer and a high score feature to see how many you can collect in a limited amount of time.

What I want to happen
What I want to happen is that when the apple is spawned on screen it doesn't spawn near the player because if it spawns on the player it causes the score to increase multiple times when the score is just supposed to go up by one. While this

What I have right now
The whole game is complete but this one bug makes the score and high score feature useless as the score can go up dramatically.

What I want help with
What I want help with is how to make the apple spawn in a random position but not near the player so it can't bug out and increase the score by a lot.

To produce the bug
Simply collect apples and when the apple is randomly changed to a new position that is next to the player you should see the score go up for how long you are on that apple.

Bug Area
I believe this is where the bug originates because this is the collision checker that makes the apple change position and increases its score.

Code: Select all

function T:CheckOverlap()
    if (P.y + P.h > T.y) and (P.y < T.y + T.h) and (P.x + P.w > T.x) and (P.x < T.x + T.w) then
        math.randomseed(os.time())
        T.x = math.random(love.graphics:getWidth())
        T.y = math.random(love.graphics:getHeight()) 
        Score = Score + 1
    end
end

Re: Collectible Object Spawns On Player

Posted: Wed Jun 08, 2022 1:08 am
by togFox
I haven't checked the code (I'm on mobile atm) but do apples disappear when collected? If so, and it spawns on the player, does the score increase by one and then disappear?

Re: Collectible Object Spawns On Player

Posted: Wed Jun 08, 2022 1:20 am
by AdonisMF
The apple doesn't disappear it just gets repositioned, and if the apple spawns on the player it increases by a lot then disappears.

Re: Collectible Object Spawns On Player Which Increases Score More Than Once

Posted: Wed Jun 08, 2022 7:23 am
by darkfrei
Just add some gap where the apples can not be spawn.
For example the player position is x, and gap is gap :)
Than calculate another two values:
xLeft = x- gap
xRight = x+ gap
If the xLeft is more than 0 and xRight is less then width then the common solution:
summ = xLeft + (width-xRight)
Make the r = random (summ)
If the r is less than xLeft then spawnX = r
Else spawnX = xRight + (r-xLeft)

Re: Collectible Object Spawns On Player Which Increases Score More Than Once

Posted: Wed Jun 08, 2022 8:03 am
by knorke
Avoiding to spawn the apple on top of the player is one solution. But there seems to be another problem. As I understand this:
you should see the score go up for how long you are on that apple.
the score goes up by several points or even infinite?
It seems very unlikely that the apple spawns multiple times in a row on top of the player.
Either there is something from with the game logic, but I do not see anything right away.
Or maybe math.random always generates the same coordinates.
Usually random generator is only seeded once at gamestart. Try moving math.randomseed(os.time()) into love.load()

By the way, on first run there is an error because there is no highscore file yet.

Re: Collectible Object Spawns On Player Which Increases Score More Than Once

Posted: Wed Jun 08, 2022 8:21 am
by togFox
Fixed it:

Code: Select all

function T:CheckOverlap()
    if (P.y + P.h > T.y) and (P.y < T.y + T.h) and (P.x + P.w > T.x) and (P.x < T.x + T.w) then
        -- math.randomseed(os.time())		-- <*************************************************
        T.x = math.random(100)
        T.y = math.random(100)
        Score = Score + 1
    end
end
I commented out the randomseed and now it works fine. I believe it is redundant and not needed - at least on 11.4 and Windows. It was causing some sort of sub-second lag. Very curious. I've never seen that before, probably because I've never used randomseed before.

Notice, for debugging purposes, I set x,y to 100.

Re: Collectible Object Spawns On Player Which Increases Score More Than Once

Posted: Wed Jun 08, 2022 8:29 am
by darkfrei
love.math.random makes random seed for you. But for the testing the math.random without seed is very ok.

Re: Collectible Object Spawns On Player Which Increases Score More Than Once

Posted: Wed Jun 08, 2022 8:44 am
by ReFreezed
When you choose a new position for the apple, do it in a loop that repeats until the new position isn't close to the player (i.e. brute force it), something like this:

Code: Select all

local function isCloseToPlayer(extraSpace)
    return (P.y + P.h > T.y - extraSpace)
       and (P.y < T.y + T.h + extraSpace)
       and (P.x + P.w > T.x - extraSpace)
       and (P.x < T.x + T.w + extraSpace)
end

function T:CheckOverlap()
    if isCloseToPlayer(0) then
        -- math.randomseed(os.time()) -- Do this only once, in love.load instead!
        Score = Score + 1
        repeat
            T.x = math.random(love.graphics:getWidth())
            T.y = math.random(love.graphics:getHeight()) 
        until not isCloseToPlayer(100) -- 100 is how close the apple and the player can be.
    end
end
Also move math.randomseed, as the others have commented on. The reason the score goes up by a lot is because math.randomseed makes math.random return the same values for up to a second, because os.time returns whole seconds (i.e. it returns the same value for a second).

Re: Collectible Object Spawns On Player Which Increases Score More Than Once

Posted: Wed Jun 08, 2022 9:05 am
by togFox
So, I think we're all saying, if you don't want to do the loopy thing:

Code: Select all

function T:CheckOverlap()
    if (P.y + P.h > T.y) and (P.y < T.y + T.h) and (P.x + P.w > T.x) and (P.x < T.x + T.w) then
        T.x = love.math.random(love.graphics:getWidth())
        T.y = love.math.random(love.graphics:getHeight())
        Score = Score + 1
    end
end
Use love.math.random() and not math.random().

Re: Collectible Object Spawns On Player Which Increases Score More Than Once

Posted: Wed Jun 08, 2022 10:49 am
by ReFreezed
Not doing the loopy thing will result in the apple sometimes spawning on top of the player though.