Reputation:
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
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