Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

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!

Comments

  • IgnatzIgnatz Mod
    Posts: 5,396

    @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?

  • edited June 2015 Posts: 47

    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.

  • IgnatzIgnatz Mod
    Posts: 5,396

    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

  • edited June 2015 Posts: 47

    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?

  • IgnatzIgnatz Mod
    edited June 2015 Posts: 5,396

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

  • IgnatzIgnatz Mod
    Posts: 5,396

    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.

  • dave1707dave1707 Mod
    Posts: 7,810

    @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.

  • IgnatzIgnatz Mod
    Posts: 5,396

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

  • Posts: 2,020

    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.

  • IgnatzIgnatz Mod
    Posts: 5,396

    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!

  • dave1707dave1707 Mod
    Posts: 7,810

    @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
    
  • dave1707dave1707 Mod
    edited June 2015 Posts: 7,810

    @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!

Sign In or Register to comment.