lualove2dzerobrane

Lua: Value generated from `math.random` not being used


Lua is a new language to me, but the behavior I am seeing right now is completely baffling me.

I have a block of code as follows:

function PlayState:update(dt)
    -- update timer for pipe spawning
    self.timer = self.timer + dt

    -- spawn a new pipe pair every second and a half
    if self.timer > 2 then
        -- Some code here
    end

    -- Some more code here
end

As you can see, I am running some code every 2 seconds (spawning an object).. Now I want to use math.random to spawn the object between 1 and 4 seconds apart.. so I tried this:

function PlayState:update(dt)
    -- update timer for pipe spawning
    self.timer = self.timer + dt

    timeToCheck = math.random(4)
    print('timeToCheck: ' .. timeToCheck)

    -- spawn a new pipe pair every second and a half
    if self.timer > timeToCheck then
        -- Some code here
    end

    -- Some more code here
end

But that doesn't work.. the objects have zero distance between them when I did this. I added the print('timeToCheck: ' .. timeToCheck) to see if the random numbers were being generated properly and indeed they are. The output is as follows:

timeToCheck: 4
timeToCheck: 3
timeToCheck: 1
timeToCheck: 3
timeToCheck: 1
timeToCheck: 4
timeToCheck: 1
timeToCheck: 3
timeToCheck: 1
-- etc..

If I change timeToCheck to something hard coded though (example: timeToCheck = 3), then the objects are separated as expected.

It's crazy. What am I missing here?

UPDATE:

I added another print message for the self.timer. Also, I am including more code below, so you can see where I reset the timer:

function PlayState:update(dt)
    -- update timer for pipe spawning
    self.timer = self.timer + dt

    timeToCheck = math.random(4)
    print('timeToCheck: ' .. timeToCheck)
    print('self.timer: ' .. self.timer)

    -- spawn a new pipe pair every second and a half
    if self.timer > timeToCheck then
        -- modify the last Y coordinate we placed so pipe gaps aren't too far apart
        -- no higher than 10 pixels below the top edge of the screen,
        -- and no lower than a gap length (90 pixels) from the bottom
        local y = math.max(-PIPE_HEIGHT + 10, 
            math.min(self.lastY + math.random(-20, 20), VIRTUAL_HEIGHT - 90 - PIPE_HEIGHT))
        self.lastY = y

        -- add a new pipe pair at the end of the screen at our new Y
        table.insert(self.pipePairs, PipePair(y))

        -- reset timer
        self.timer = 0
    end
    -- more code here (not relevant)
end

As you can see, the ONLY place I am restting the timer to 0 is at the end of the if statement. Here is the output of print:

timeToCheck: 2
self.timer: 1.0332646000024
timeToCheck: 4
self.timer: 1.0492977999966
timeToCheck: 1
self.timer: 1.0663072000025
timeToCheck: 2
self.timer: 0.016395300015574
timeToCheck: 4
self.timer: 0.032956400013063
timeToCheck: 2
self.timer: 0.049966399994446
timeToCheck: 2
self.timer: 0.066371900000377
timeToCheck: 3
self.timer: 0.083729100006167
-- etc...

Sorry if I am being dense here, but I am a total noob to Lua and game programming.. Note that if I change the random value to a hard coded one, such as:

timeToCheck = 3, then it works fine. It only fails when I use math.random and that is really confusing


Solution

  • It looks like you're setting a new timeToCheck every frame. This would result in a new spawn roughly once per second, since timeToCheck is almost guaranteed to be 1 every few frames. You'll need to only set timeToCheck inside the if, at the same time you set the timer.

    -- reset timer
    self.timer = 0
    timeToCheck = math.random(4)
    

    You might need to initialize timeToCheck somewhere outside the update function.