user13785032
user13785032

Reputation:

Why does my LOVE2D program keep resetting the score?

So, I'm currently in a problem with updating my Super Mario Bros. Yeah, sure, it works fine, but the problem is this:

Whenever I touch the flagpole at the end, it literally resets my score.

It makes no sense with this program since I made a params for PlayState:enter, and I don't exactly know why my score goes back to 0.

This shows up in PlayState.lua:

function PlayState:enter(params)
    self.score = params.score
    self.lastLevelWidth = params.lastLevelWidth
    
    if self.lastLevelWidth == 0 then
        self.lastLevelWidth = 100
    else
        self.lastLevelWidth = self.lastLevelWidth + 50
    end

    self.camX = 0
    self.camY = 0
    self.level = LevelMaker.generate(100, 10)
    self.tileMap = self.level.tileMap
    self.background = math.random(3)
    self.backgroundX = 0

    self.gravityOn = true
    self.gravityAmount = 6

    self.player = Player({
        x = 0, y = 0,
        width = 16, height = 20,
        texture = 'green-alien',
        stateMachine = StateMachine {
            ['idle'] = function() return PlayerIdleState(self.player) end,
            ['walking'] = function() return PlayerWalkingState(self.player) end,
            ['jump'] = function() return PlayerJumpState(self.player, self.gravityAmount) end,
            ['falling'] = function() return PlayerFallingState(self.player, self.gravityAmount) end
        },
        map = self.tileMap,
        level = self.level,
    })

    self:spawnEnemies()

    self.player:changeState('falling')
end

I used the params to get to a new score, 0, but I don't want it to let it stay like that. This is what I have done in LevelMaker.lua:

keyCollected = false

function LevelMaker.generate(width, height)
    local tiles = {}
    local entities = {}
    local objects = {}

    local tileID = TILE_ID_GROUND
    
    -- whether we should draw our tiles with toppers
    local topper = true
    local tileset = math.random(20)
    local topperset = math.random(20)

    -- insert blank tables into tiles for later access
    for x = 1, height do
        table.insert(tiles, {})
    end
    
    -- make positions for the lock box and key in the level
    local lockBoxPosition = math.random(1, width)
    local keyPosition = math.random(1, width)
    local keySkin = math.random(1, 4)

    -- column by column generation instead of row; sometimes better for platformers
    for x = 1, width do
        local tileID = TILE_ID_EMPTY
        
        -- lay out the empty space
        for y = 1, 6 do
            table.insert(tiles[y],
                Tile(x, y, tileID, nil, tileset, topperset))
        end

        -- chance to just be emptiness
        if math.random(7) == 1 and x ~= 1 and lockBoxPosition ~= x and keyPosition ~= x then
            for y = 7, height do
                table.insert(tiles[y],
                    Tile(x, y, tileID, nil, tileset, topperset))
            end
        else
            tileID = TILE_ID_GROUND

            local blockHeight = 4

            for y = 7, height do
                table.insert(tiles[y],
                    Tile(x, y, tileID, y == 7 and topper or nil, tileset, topperset))
            end

            -- chance to generate a pillar
            if math.random(8) == 1 then
                blockHeight = 2
                
                -- chance to generate bush on pillar
                if math.random(8) == 1 then
                    table.insert(objects,
                        GameObject {
                            texture = 'bushes',
                            x = (x - 1) * TILE_SIZE,
                            y = (4 - 1) * TILE_SIZE,
                            width = 16,
                            height = 16,
                            
                            -- select random frame from bush_ids whitelist, then random row for variance
                            frame = BUSH_IDS[math.random(#BUSH_IDS)] + (math.random(4) - 1) * 7
                        }
                    )
                end
                
                -- pillar tiles
                tiles[5][x] = Tile(x, 5, tileID, topper, tileset, topperset)
                tiles[6][x] = Tile(x, 6, tileID, nil, tileset, topperset)
                tiles[7][x].topper = nil
            
            -- chance to generate bushes
            elseif math.random(8) == 1 and keyPosition ~= 1 then
                table.insert(objects,
                    GameObject {
                        texture = 'bushes',
                        x = (x - 1) * TILE_SIZE,
                        y = (6 - 1) * TILE_SIZE,
                        width = 16,
                        height = 16,
                        frame = BUSH_IDS[math.random(#BUSH_IDS)] + (math.random(4) - 1) * 7,
                        collidable = false
                    }
                )
            end
            
            if x == keyPosition then
                table.insert(objects,
                    GameObject {
                        texture = 'keys-and-locks',
                        x = (x - 1) * TILE_SIZE,
                        y = (blockHeight + 1) * TILE_SIZE,
                        width = 16,
                        height = 16,
                        frame = keySkin,
                        collidable = true,
                        consumable = true,
                        solid = false,
                        
                        onConsume = function(player, object)
                            gSounds['pickup']:play()
                            player.score = player.score + 500
                            keyCollected = true
                        end
                    }
                )
            end
            
            if x == lockBoxPosition then
                table.insert(objects,
                    GameObject {
                        texture = 'keys-and-locks',
                        x = (x - 1) * TILE_SIZE,
                        y = (blockHeight - 1) * TILE_SIZE,
                        width = 16,
                        height = 16,
                        frame = keySkin + 4,
                        collidable = true,
                        consumable = true,
                        hit = false,
                        solid = true,
                        lockedBox = false,
                        objectRemove = false,
                        
                        onCollide = function(obj)
                            if not obj.hit then
                                if keyCollected then
                                    gSounds['pickup']:play()
                                    obj.hit = true
                                    obj.objectRemove = true
                                    obj.consumable = true
                                    
                                    local pole = GameObject {
                                        texture = 'poles',
                                        x = (width * TILE_SIZE) - 32,
                                        y = (blockHeight - 1) * TILE_SIZE,
                                        width = 16,
                                        height = 48,
                                        frame = math.random(#POLES),
                                        collidable = true,
                                        consumable = true,
                                        solid = false,
                                        
                                        onConsume = function(player, object)
                                            gSounds['pickup']:play()
                                            player.score = player.score + 1000
                                            gStateMachine:change('play', {
                                                score = player.score,
                                                lastLevelWidth = width
                                            })
                                        end
                                    }
                                    local flag = GameObject {
                                        texture = 'flags',
                                        x = (width * TILE_SIZE) - 32 + 6,
                                        y = blockHeight * TILE_SIZE,
                                        width = 16,
                                        height = 10,
                                        frame = 1,
                                        collidable = true,
                                        consumable = true,
                                        solid = false,
                                        
                                        onConsume = function(player, object)
                                            gSounds['pickup']:play()
                                            player.score = player.score + 1000
                                            gStateMachine:change('play', {
                                                score = player.score,
                                                lastLevelWidth = width
                                            })
                                        end
                                    }
                                    Timer.tween(2.0 , {
                                        [flag] = {y = ((blockHeight - 1) * TILE_SIZE) + 4}
                                    })
                                    gSounds['powerup-reveal']:play()
                                    
                                    table.insert(objects, pole)
                                    table.insert(objects, flag)
                                end
                                keyCollected = false
                            end
                            gSounds['empty-block']:play()
                        end
                    }
                )
            -- chance to spawn a block
            elseif math.random(10) == 1 then
                table.insert(objects,

                    -- jump block
                    GameObject {
                        texture = 'jump-blocks',
                        x = (x - 1) * TILE_SIZE,
                        y = (blockHeight - 1) * TILE_SIZE,
                        width = 16,
                        height = 16,

                        -- make it a random variant
                        frame = math.random(#JUMP_BLOCKS),
                        collidable = true,
                        hit = false,
                        solid = true,

                        -- collision function takes itself
                        onCollide = function(obj)

                            -- spawn a gem if we haven't already hit the block
                            if not obj.hit then

                                -- chance to spawn gem, not guaranteed
                                if math.random(5) == 1 then

                                    -- maintain reference so we can set it to nil
                                    local gem = GameObject {
                                        texture = 'gems',
                                        x = (x - 1) * TILE_SIZE,
                                        y = (blockHeight - 1) * TILE_SIZE - 4,
                                        width = 16,
                                        height = 16,
                                        frame = math.random(#GEMS),
                                        collidable = true,
                                        consumable = true,
                                        solid = false,

                                        -- gem has its own function to add to the player's score
                                        onConsume = function(player, object)
                                            gSounds['pickup']:play()
                                            player.score = player.score + 100
                                        end
                                    }
                                    
                                    -- make the gem move up from the block and play a sound
                                    Timer.tween(0.1, {
                                        [gem] = {y = (blockHeight - 2) * TILE_SIZE}
                                    })
                                    gSounds['powerup-reveal']:play()

                                    table.insert(objects, gem)
                                end

                                obj.hit = true
                            end

                            gSounds['empty-block']:play()
                        end
                    }
                )
            end
        end
    end

    local map = TileMap(width, height)
    map.tiles = tiles
    
    return GameLevel(entities, objects, map)
end

What's supposed to happen is that when I collected the key and unlocked the lock block, I get a flag, and when I collide with the flag at the end of the map, I get to a new level, with the same score, but not 0. Sadly, everytime I get to a new level, it turns into 0.

I don't know if the problem is in StartState.lua:

function StartState:update(dt)
    if love.keyboard.wasPressed('enter') or love.keyboard.wasPressed('return') then
        gStateMachine:change('play', {
            score = 0,
            lastLevelWidth = 0
        })
    end
end

Any ideas why it's like this?

Upvotes: 0

Views: 210

Answers (1)

elj40
elj40

Reputation: 46

If you collide with the pole and then change to StartState, then that is the problem. I suggest feeding the score through start with: function StartState:enter(params) self.score = params.score end Then just pass self.score through to the playstate

Upvotes: 0

Related Questions