Help needed with 2D Platformer

Hi all again, I am having trouble with certain things on creating a 2D Platformer.

Game here: http://pastebin.com/FZnurnE3

  1. Successfully collecting the coins (when the character collides, delete the sprite)
  2. Sometimes having to ‘re-tap’ on left or right after jumping.

Thanks in advance!

PS. Use B to jump!

@JonoGaming00 - you will get a lot more help if you can try to isolate the problem, rather than asking someone to make sense of all your code, download and play it, and figure out the problem. (I like helping, but I’m not going that far).

Also, your first question isn’t clear to me. What exactly is the error, or the problem you can’t solve?

Ok @Ignatz , sorry I probably wasn’t that helpful. To be more specific about the first question, I have no idea of how to get the character to collect the coin. There is no real problem with this one, just I am unsure about how to go about doing this.

All of the tiles are created at startup depending on the information given in the levelLayout table and inserted into another table storing all of the physics information for the tiles. The character just walks on invisible physics shapes, using sprites to illustrate a world of some sort. At the moment the coin is just a sprite with an invisible circle behind it. I think what I’m trying to do is that when the two collide, the physics information for that coin is removed from the table, but I have played around with this and am not getting anywhere.

I’m sorry if this did not help, I’m not too great with tables yet.

from the Codea reference

-- destroy should be used before
-- setting a body to nil or removing from table
circle = physics.body(CIRCLE, 100)
circle:destroy()
circle = nil --or remove from table

ie physics bodies are stored separately from your normal variables, so you need to ~destroy~ them first, then delete them as you normally would

Oh probably should have looked at the reference first. Thanks!

One more thing @Ignatz , when deleting the body from a table using table.remove, I get ‘Number expected, got body’. Am I using the wrong method?

If the body is stored in item 3 of table T, then T[3]=nil should work

As regards collecting coins and deleting sprites, I did it all in my demo platformer

https://coolcodea.wordpress.com/2014/09/

Yep, thanks @Ignatz I’ll check out your demo platformer

I’m using this method to draw the coins, but once they are collected the physics body is destroyed, making coinx and coiny = nil. I have tried setting coinx and coiny to 0 but still gives an error saying coinx = nil. Obviously codea can’t draw a sprite at an x of nil.

for i,j in pairs(coins) do
        coinx=coins[i].x
        coiny=coins[i].y
        sprite("Platformer Art:Coin", coinx, coiny,50,50)
    end

Note that the x and y value is stored in the physics body.

I looked at your Platformer @Ignatz and got some ideas, but that wasn’t the way I was planning to have my character to collect coins.

@JonoGaming00 Check if the values are nil, and if they are don’t draw the sprite. A better fix would be to properly remove the coins.

After youve destroyed the physics body, remove the coin from the table. Eg if it is item number 6, use “coins[6]=nil”

If you have an array, I wouldn’t recommend removing items with coins[6]=nil. It could create holes in the table if there are items above position 6: ipairs won’t be able to get to the higher values, and #coins won’t report them either. table.remove is the way to go, it will move all items to the right down a place, so you don’t get a hole in your array.

setting to nil is not a problem in this case, where you are using pairs to iterate the table, so holes don’t matter. I don’t use ipairs unless I need the table iterated in correct order, which is hardly ever - but your point is definitely relevant for people who do use ipairs!

@JonoGaming00 I downloaded your code from the link at the top of this discussion. I uncommented the table.remove command (see below) and it appears that the coins are being destroyed and removed from the coins table OK. The thing that’s not happening is, it looks like you’re not removing the value 5 from the levelLayout where the coin was. So even though you removed the collided coins, you’re still drawing them based on the levelLayout table.

function removeCoin()
    for x,y in pairs(coins) do
        if y.dest then    -- if true then
            y:destroy()    -- destroy body
            table.remove(coins,x)    -- remove body from table
        end
    end
end

@dave1707 I have tried doing this, although it probably isn’t the rough way of doing it. I’ve tried using this:

for i,j in pairs(coins) do

if coins[i]==nil then
else
        coinx=coins[i].x
        coiny=coins[i].y
        sprite("Platformer Art:Coin", coinx, coiny,50,50)
end
    end

@JonoGaming00 I modified your code to remove the coins upon collision. See the 3 changes below with the comment – added this.

EDIT: I added more coins in my version and everything seems to work OK. The coins disappear upon collision.

function TileCoins(x,y,w,h,p)
   
    local tile = physics.body(CIRCLE, w/2)
 
    tile.gravityScale = 0
    tile.restitution = 0.1
   
    tile.x = x*100
    tile.y = HEIGHT-(100*y)
       
    tile.i=x   -- added this
    tile.j=y   --added this
   
    tile.type = STATIC
    tile.friction = 0
    tile.dest = false
   
    if p == 5 then
        tile.info = "coin"
    end
   
    return tile
end
 
function removeCoin()
    for x,y in pairs(coins) do
        if y.dest then    -- if true then
            y:destroy()    -- destroy body
            table.remove(coins,x)    -- remove body from table
            levelLayout[y.j][y.i]=0   -- added this
        end
    end
end

@dave1707 I have updated my code since then, I will update he link when I have an opportunity

@dave1707 that works, thanks so much!