Howdy, Stranger!

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

2D Sidescrolling Toolkit

IgnatzIgnatz Mod
edited September 2014 in General Posts: 5,396

I've been building a 2D sidescrolling "toolkit" - ie software that can be used to build a variety of sidescrolling games. It's packed with animation, as you can see from this simple level

For demonstration purposes, I've only used images provided with Codea. Level maps can be easily built in Codea as ASCII tables, using letter codes (as shown at the end of the video) to tell Codea what to put where.

I did this mainly to see what was involved, and how much Codea could do. 2D sidescrolling doesn't sound hard, but it has taken me many dozens of hours over a couple of months, and I have probably rewritten it four times. However, I've satisfied myself that Codea can produce pretty awesome results.

I'm planning to ultimately share the code so people can use it as a template, and probably write an ebook around it as a guide to designing various parts of a sidescroller (and how not to design them, because I have made a lot of mistakes along the way!).

If anybody wants to get involved and help take it further, let me know, because I am not going to produce a complete game. However, following the code requires a pretty good understanding of Codea, and I've invested a lot of time in it, so at this stage, I'm going to share it very selectively indeed.

Comments

  • Hey, @Ignatz, I love the idea, and kudos to you for putting in so much work! It's something codea has needed for a while, something I considered doing myself when I get skilled enough, and something I'm very glad to see that you've made! I hope this helps out a lot of beginners and makes sidescrollers so much easier to make (something that still poses a challenge to me). That said I'm having trouble viewing the demo though, so I have a couple of questions! Can the level editor be used standalone to make games that scroll along both the x and y axes? I am currently working on something big (well, big for me), and am stuck at the level editor stage. If your library can solve my issue, I would be ten billion more times interested than I already am.

  • IgnatzIgnatz Mod
    edited September 2014 Posts: 5,396

    @Monkeyman32123 - you can make game levels of any size with this project. So if by "scrolling" you mean the ability to go beyond the limits of the screen, definitely yes. The demo shows that.

    Here is a direct link to the video above

  • Jmv38Jmv38 Mod
    Posts: 3,295

    very nice!

  • Posts: 745

    @Ignatz,

    Looks amazing! Did you write a level editor to create the levels or have you crafted them by hand? If the former, how did you approach saving and loading? I looked at this but wasn't overly pleased with my approach when looking at foggy bummer. How did you approach collision detection? Do you cross reference the player position with the "map" to establish whether there was ground present or did you implement in physics?

  • IgnatzIgnatz Mod
    Posts: 5,396

    @West - I have a level editor. You provide a table of characters, one per tile, to define what goes in each tile, like this below - the entire level of the demo game. "g" stands for an earth block, "w" is water, "m" is a coin, "-" is blank, etc.

     local mapText={ 
        '-----------------------',
        '-----------------------',
        '-----------------------',
        '-----------------------',
        '-----------------------',
        '-----------------------',
        '----m-----cu-----------',
        '----m---m-r------------',
        'b---m---b-------kb----b',
        'b@-----bb-----t--bF--lb',
        'ggggggggggggglggggggglg',
        'ggggggggggggglggggggglg',
        'ggggggggggggglggggggglg',
        'ggggggggggggglggggggglg',
        'g-----------glggggggglg',
        'g-L---------glggggggglg',
        'g--m---h-f---lggggggglg',
        'g-------i----lggggggglg',
        'g-ggggggggggggggggggglg',
        'g--------------------lg',
        'g----------m-----m---lg',
        'g-------y----s-------lg',
        'ggggwwggggggggggggggggg',
        'ggggggggggggggggggggggg
    }
    

    This is compact and makes it very easy to define and edit levels. The levels can be any size you like. You can also easily redefine what the letters stand for, or add new ones. I put each object (other than simple blocks) in a class, to allow for maximum flexibility.

    Background images are added by defining which tiles they cover, so that has to be done separately at this stage.

    Collision detection was extremely difficult, not just for enemies, but also for walking, jumping, landing on blocks, moving on ladders etc. I ended up using a lookup table for the tiles containing blocks, to tell me which tiles couldn't be entered, but for the enemy sprites, I used an AABB overlap test. I used a simple downward force for gravity, and an upward force for jumping. I turned gravity off while on the ladder.

    Lighting is done with a shader, as you might imagine.

  • Posts: 1,595

    @Ignatz Codea can do a hell of a lot if done right, this is a good example of that. I imagine the collision took a lot of tweaking too, great work.

  • toffertoffer Mod
    Posts: 151

    @Ignatz - That look amazing ! great work. On my side, I'm building a sprite (animated) editor. I'll be glad to invest some time in your project if you think I can have some skill to help.

  • This is awesome!!! @Ignatz please be My master!!!

  • IgnatzIgnatz Mod
    Posts: 5,396

    @llEmill - thank you, but I am nobody's master..

    @toffer - you certainly have great skill! I guess you are talking about how to create animated objects that can be used in projects like mine (and others like Fogbuzz etc).

    I started out trying to use Simeon's Juice effects library, which has jumps, spins, bulging, squashing etc, based on tweens, and I found it was too difficult, because (as I said to him):

    "Suppose I have a continuous side scroller, and the character moves along smoothly along a level surface. If he comes to a hole, he should fall in, and if he comes to a wall, he should stop. If he jumps and hits the ceiling, he should fall down.

    This means I need collision code that continuously checks whether there is a surface below and in front of the character (and above, if the character is jumping).

    If I use an animation effect like Juice to (say) bounce up, I can use the getActualPosition function to get the true x,y position and test for collisions with the roof. If a collision occurs, I need to stop the animation and somehow get the character down to the floor again without the help of Juice.

    If I use Juice to leap up and sideways, eg to jump up onto a higher block, Juice will not realise the block is in the way, and I will have to use collision testing to decide when to stop the animation. If the player collides with the side of the block, I will also have to interrupt that, and get the player down to the floor again.

    If the player jumps sideways, and there is a hole, the player will need to keep falling in a convincing way after the animation ceases (ie once the player falls below his current level), in a continuing arc rather than straight down. This means my code has to integrate closely with Juice to produce a continuous movement.

    A complication is where you include a spin animation. If the player collides with the roof while spinning and partly upside down, I don't want to really have to think about how to get him back on the ground again, the right way up, having interrupted the animation.

    Another problem is that several of the Juice animations start with a slight downward movement that pushes the character partly through the floor. This causes a collision which (in my code) cancels the animation before it starts, unless I make my collision code smart enough to ignore initial collisions, which gets messy. I think none of the animations should go below the current floor level, at any stage.

    Finally, there is no function to tell the developer when an animation is finished. This is important."

    All this is a pity, because Juice has some great effects.

    So the main problem with custom animation effects is how to interrupt them if the player collides with something while the animation is running. I came to the conclusion that it is too hard to do this, but you may have a solution. If so, I'd be very happy to hear it.

  • toffertoffer Mod
    Posts: 151

    @Ignatz - It's a pixel editor. You draw frame by frame and exports a spritesheet from it.

    From the the few 2D engines I've build, I've learned that moving and animating sprites with a separate tween system is a lot harder to manage. All your tween informations (velocity, size, mass, etc...) are separated from the engine itself, mean that is harder to predict / check for collisions, triggers...

    As I don't know how you use Juice and how your engine loop is done it's harder to say if it's better to rely on a tween lib or not.

    But I can see that when you fire a tween, this one is predefined to go from A to B during a time T, so you must 'break' it if something have to cancel/adjust it. That is different when you have all your sprites properties (vel, acceleration...) adjusted from within the engine loop at each frame tick according to the game environment.

    Hope it makes sense.

  • IgnatzIgnatz Mod
    Posts: 5,396

    @toffer - I think a spritesheet would be very useful for "in place"animation, ie animations that don't change the position of the player, eg animations that flap wings, or make legs walk, or make a smile. It's when the animations change the player position that you get into trouble.

  • Posts: 2,042

    @Ignatz, when using Juice and colliding, can you not just call another juice to override the current one and react to the collision?

  • IgnatzIgnatz Mod
    Posts: 5,396

    @JakAttak- short answer, no. If you look at all the scenarios I outlined above, it would be impossible (in my view) to do that.

  • Posts: 2,042

    @Ignatz - long(er) answer (after I looked into it), Juice lacks a way to stop the current action.

    I played with it a bit, and added a method to Juice that halts all current actions and (smoothly) returns the object back to its position (or another specified position).

    With this addition, I think it would be easy to just call that function when the player collides with something, and have it smoothly return to an allowed position.

  • IgnatzIgnatz Mod
    Posts: 5,396

    @JakAttak - does it work even if you are upside down at the time of collision?

    Does it work if you are jumping and hit the side of a block, and need to slide straight down?

    It would be good to see a simple demo..

  • Posts: 2,042

    @Ignatz, yes, and yes - because you can provide new position, scale and angle for the end of the reaction.

    Here is a basic demo:

    https://www.dropbox.com/s/0imgbpywutg6wzl/Video Sep 05, 7 00 12 PM.mp4?dl=0

  • IgnatzIgnatz Mod
    Posts: 5,396

    @JakAttak - if you share the code, I'll try it out :)

  • edited September 2014 Posts: 2,042

    Here is the modified juice library: http://gist.github.com/JakAttak/21a3ad3027a6ac3e273e

    The new function is used as follows: object:stopMoves(duration, tbl) duration being the time it takes and tbl being the end result (if you don't want it to return to its original position, like so: tbl = { pos = vec2(10,10), scale = vec2(2, 0.5), angle = 120

    Look in the touched function of main to see a basic example.

    If you have any issues, let me know, I'm happy to keep working on it so that it works at its best in every scenario.

  • IgnatzIgnatz Mod
    Posts: 5,396

    ok, it may take me a couple of days to get this included, but thanks

  • Jmv38Jmv38 Mod
    Posts: 3,295

    @jakAttak the gist link does not work for me

  • IgnatzIgnatz Mod
    edited September 2014 Posts: 5,396

    @Jmv38 - try this
    https://gist.github.com/JakAttak/21a3ad3027a6ac3e273e
    (two letters were transposed)

  • edited September 2014 Posts: 2,042

    Oops. Thanks for catching that @Ignatz. Fixed it in my comment.

    EDIT: I made a mistake in the first version which broke fade and flash functionalities (I hadn't noticed because I only tested the ones that moved the object) - I fixed it in the gist, so if you already downloaded it you should grab the new juice.mover file

  • Jmv38Jmv38 Mod
    edited September 2014 Posts: 3,295

    I have grabbed the last version from TLL (updated 4 hours ago from your pull). Is this ok?

  • Posts: 2,042

    @Jmv38, yes that one should work fine

  • I'm very (VERY) interested in that lighting shader (I know, probably not the bulk of your work, I'm sorry though, that lighting is awesome)

  • IgnatzIgnatz Mod
    Posts: 5,396

    @JakAttak - I've had a look at your code, and it seems to work nicely. Some animations start with a downward movement, which triggers a collision with the floor, and I've had to disable that initial movement first. So I haven't tried your code in my project yet, I will do so soon.

  • Posts: 2,042

    @Ignatz, which movements trigger your floor collisions? When I was doing my tests, I noticed a couple 'squish' down at the beginning, but they didn't seem to move downwards

  • IgnatzIgnatz Mod
    Posts: 5,396

    @JakAttak - try bounce, and print the y value, you'll see it dips down at first

  • Posts: 2,042

    Huh, I see it. I guess the movement was just so little it didn't trip my bottom collisions.

  • IgnatzIgnatz Mod
    Posts: 5,396

    It's quite easy to disable. For example, in line 55 of bounce, you simply set

    local moveDown = savedPos.y
    

    instead of the formula given there, this prevents any movement down

  • @Ignatz you are awesome, and this project amazing! I thought how create big scrolling levels in codea recently , but you solve my problem. Thank you. Like said @llEmill you are master

  • IgnatzIgnatz Mod
    Posts: 5,396

    @lupino8211 (and @llEmill) - thank you for the encouragement. I have started a set of blog posts on how I built this, including the mistakes I made. I have just posted the first one here, and I plan to post more over the next couple of weeks.

    http://coolcodea.wordpress.com/2014/09/09/156-creating-a-2d-platform-game-part-1/

  • Posts: 2,042

    Been following the blog, and just grabbed the code. interesting stuff. I was particularly interested by the lighting, will definitely be digging into that :) The control scheme was also interesting, I probably would have just tossed a joystick in there but your way is pretty unique. all in all, great stuff.

  • IgnatzIgnatz Mod
    Posts: 5,396

    Thanks, @JakAttak - I was never much good at controlling joysticks!

    Yes, I've finished a series of posts on this project, available at http://coolcodea.wordpress.com

    I would have liked to explain a bit deeper, but I'm never sure who is reading it and how much they know....

    Anyway, side scrollers are a lot of fun to build.....and I think Codea is perfect for building them.

  • I don't know if it's at all relevant, but I recently made a pretty simple joystick (which you could easily edit and change to your needs). Not saying your control scheme is bad (I quite like it), just that I think it's nice to have different options :P
    So if there's any interest (at all), just ask and I'd be happy to give you the class!

  • IgnatzIgnatz Mod
    Posts: 5,396

    @Monkeyman32123 - I won't need it, thank you, but others might, so feel free to share it anyway (in a new thread, I suggest).

    NB Providing example code that uses it will make it easier for other people to see how it works.

  • @Ignatz Alright, will do(when I get home to my beautiful iPad)! And thank you for the link to that lighting thing, by the way. I forgot to thank you earlier

Sign In or Register to comment.