MelonJS tutorial platformer

378 views
Skip to first unread message

David Salcer

unread,
Dec 22, 2014, 9:45:16 AM12/22/14
to mel...@googlegroups.com
Hello guys.
I have noticed that there is new tutorial for the platformer on 2.0.2 version.

Because I was working back then on 0.9.x I was really glad so I went to use the tutorial and started step by step.
But even when I complete the first step and launch the game as tutorial says
-just to load empty (just tiles) tmx there is an error
-also the tutorial is not saying what about the meta-tiles but I added them to the tmx as I was used to to the another layer

Now I am starting to be really desperate because from the old 0.9 I just cannot manage to even run empty game, plenty of unknown errors. Would be glad if they were just syntax errors.

thank you for your time

I am at point 
"Part 2: Loading our level - Try it out" of the tutorial

[Error] TypeError: Invalid array length argument (fractional lengths not allowed)
Uint32Array                       (melonJS-2.0.2-min.js, line 12)
decodeBase64AsArray                     (melonJS-2.0.2-min.js, line 12)
setLayerData                               (melonJS-2.0.2-min.js, line 13)
readLayer                                         (melonJS-2.0.2-min.js, line 13)
(anonymous function)                     (melonJS-2.0.2-min.js, line 13)
forEach                               ([native code], line 0)
readMap                               (melonJS-2.0.2-min.js, line 13)
loadLevel                               (melonJS-2.0.2-min.js, line 13)
onResetEvent                     (play.js, line 8)
reset                               (melonJS-2.0.2-min.js, line 10)
f                               (melonJS-2.0.2-min.js, line 10)
f                               ([native code], line 0)

Aaron McLeod

unread,
Dec 22, 2014, 9:53:04 AM12/22/14
to mel...@googlegroups.com
Just to check, did you start from using the boilerplate?

The metatiles are no longer needed, as collision is done by making shapes, not using tiles. The section "Define the collision layer" explains this in part 3 of the tutorial. We want to find time to work on a better platformer tutorial to better showcase this.

Otherwise if you can post your code somewhere for me to take a look, I can help you out further.

--
You received this message because you are subscribed to the Google Groups "melonJS - A lightweight HTML5 game engine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to melonjs+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

David Salcer

unread,
Dec 22, 2014, 11:41:21 AM12/22/14
to mel...@googlegroups.com
Yes I downloaded the boilerplate from the link included at the start of the tutorial.

Just copied the code from it because I wanted to have it just like the tutorial


Dne pondělí, 22. prosince 2014 15:53:04 UTC+1 Aaron McLeod napsal(a):

Jason Oster

unread,
Dec 22, 2014, 1:13:28 PM12/22/14
to mel...@googlegroups.com
Please put your TMX file on paste in or gist. It looks like the issue may be in there.

David Salcer

unread,
Dec 23, 2014, 1:52:26 AM12/23/14
to mel...@googlegroups.com
Ok I looked into the tmx file, removed the metatiles.
Then I realized if I was correct in choosing the type Base and uncompressed.

Ok...stupid mistake by my side. I had it compressed.
So now I am able to load the game.
Proceeding to the next steps.

Sorry for that guys. :-/ such a noob

David Salcer

unread,
Dec 23, 2014, 2:43:24 AM12/23/14
to mel...@googlegroups.com
But new error appeared.

Now I am loading the tmx with the collision layer and a main player.

But when I push arrows error shows up - cannot move because of:

Type error: undefined is not a function (evaluating ´this.flipX(true)´)
update
update
update
d

David Salcer

unread,
Dec 23, 2014, 2:46:14 AM12/23/14
to mel...@googlegroups.com
/* -----
  update the player pos
  ------ */
 update: function(dt) {
    if (me.input.isKeyPressed('left')) {
     // flip the sprite on horizontal axis
     this.flipX(true); //// ERROR HERE
     // update the entity velocity
     this.body.vel.x -= this.body.accel.x * me.timer.tick;
     // change to the walking animation
     if (!this.renderable.isCurrentAnimation("walk")) {
       this.renderable.setCurrentAnimation("walk");
     }
   } else if (me.input.isKeyPressed('right')) {
     // unflip the sprite
     this.flipX(false);
     // update the entity velocity
     this.body.vel.x += this.body.accel.x * me.timer.tick;
     // change to the walking animation
     if (!this.renderable.isCurrentAnimation("walk")) {
       this.renderable.setCurrentAnimation("walk");
     }
   } else {
     this.body.vel.x = 0;
     // change to the standing animation
     this.renderable.setCurrentAnimation("stand");
   }
 
    if (me.input.isKeyPressed('jump')) {
     // make sure we are not already jumping or falling
     if (!this.body.jumping && !this.body.falling) {
       // set current vel to the maximum defined value
       // gravity will then do the rest
       this.body.vel.y = -this.body.maxVel.y * me.timer.tick;
       // set the jumping flag
       this.body.jumping = true;
     }
    }
    // apply physics to the body (this moves the entity)
   this.body.update(dt);
    // handle collisions against other shapes
   me.collision.check(this);
    // return true if we moved or if the renderable was updated
   return (this._super(me.Entity, 'update', [dt]) || this.body.vel.x !== 0 || this.body.vel.y !== 0);
 },


Jay Oster

unread,
Dec 23, 2014, 2:53:50 AM12/23/14
to mel...@googlegroups.com
Well, that needs to be updated! Use:

this.renderable.flipX(true);

David Salcer

unread,
Dec 23, 2014, 2:54:01 AM12/23/14
to mel...@googlegroups.com
Ok I was thinking that it changed but when it was in the tutorial I was confused.

so it is in my case

this.renderable.flipX

David Salcer

unread,
Dec 23, 2014, 5:14:29 AM12/23/14
to mel...@googlegroups.com
Because of the new collision method instead of metatiles.

Please how could I do the "platform" collision.
I mean that I can jump from bottom to its top. Or walk across it like it was here:

http://olivierbiot.files.wordpress.com/2011/03/tiled1.png
The orange ones in the air platform.

Because when I added the colision rectangle - I cannot jump from bottom.

David Salcer

unread,
Dec 23, 2014, 5:51:00 AM12/23/14
to mel...@googlegroups.com
I find out that the specific rectangle have to be "type: platform"

If someone like me will look here

David Salcer

unread,
Dec 23, 2014, 6:52:36 AM12/23/14
to mel...@googlegroups.com

:-(
I have problem now how to repair the jumping and colliding with enemy.

When player stomps - jumps to its head - the player is flickering and that is wrong.

so the first condition if is right because it will force the jump..but why is the player flickering in the jump after?


 case me.collision.types.ENEMY_OBJECT:
      if ((response.overlapV.y>0) && !this.body.jumping) {
        // bounce (force jump)
        this.body.falling = false;
        this.body.vel.y = -this.body.maxVel.y * me.timer.tick;
        // set the jumping flag
        this.body.jumping = true;
      }
      else {
        // let's flicker in case we touched an enemy
        this.renderable.flicker(750);
      }
      return false;
      break;


And this is the enemy code:


/**
   * colision handler
   * (called when colliding with other objects)
   */
  onCollision : function (response, other) {
    if (response.b.body.collisionType !== me.collision.types.WORLD_SHAPE) {
      // res.y >0 means touched by something on the bottom
      // which mean at top position for this one
      if (this.alive && (response.overlapV.y > 0) && response.a.body.falling) {
        this.renderable.flicker(750);
      }
      return false;
    }
    // Make all other objects solid
    return true;
  }


Maybe the overlapsV is wrong because the enemy is not flickering when player jumped on them.


I andjusted it and now when I jump on them the enemy dissapears, but the plyer is flickering. Cannot figure out why.


Aaron McLeod

unread,
Dec 23, 2014, 8:10:14 AM12/23/14
to mel...@googlegroups.com
Andre could probably explain it better than myself, but he worked out the platformer collision tile a bit ago: https://github.com/aaschmitz/melonjs-improved-platformer

He sets a type property equal to platformer on the object in the collision layer. Then what you need is the proper check in the player entity's onCollision method: https://github.com/aaschmitz/melonjs-improved-platformer/blob/gh-pages/js/entities/entities.js#L126

Jay Oster

unread,
Dec 23, 2014, 1:11:21 PM12/23/14
to mel...@googlegroups.com
Aaron, that's the same code used in the melonJS repo: https://github.com/melonjs/melonJS/blob/b528d6056f4871d7ecad9e8152d4a88fb5ab762b/examples/platformer/js/entities/entities.js#L122-L138

David, you found another bug in the tutorial! The flickering behavior is caused by both entities (player and moving enemy) calling me.collision.check(). The game ends up responding to the same collision twice on each frame. Because the "jump" code is changing the player state on the first me.collision.check() call, the same checks then evaluate false for the second call. This will be fixed by #574. Until then, you can workaround the issue with two things:
  1. Move the enemy flicker/hurt part to the player's collision handler
  2. Use a flag to prevent the double collision

Here's the updated code:

/* in game.PlayerEntity.update() */
// handle collisions against other shapes
this.collided = false;
me.collision.check(this);

/* in game.PlayerEntity.onCollision() */
case me.collision.types.ENEMY_OBJECT:
    if (this.collided) {
      return false;
    }

    if ((response.overlapV.y>0) && !this.body.jumping) {
        // bounce (force jump)
        this.body.falling = false;
        this.body.vel.y = -this.body.maxVel.y * me.timer.tick;
        // set the jumping flag
        this.body.jumping = true;
        // play some audio
        me.audio.play("stomp");

        // hurt enemy
        if (response.b.alive) {
          response.b.renderable.flicker(750);
        }
    }
    else {
        // let's flicker in case we touched an enemy
        this.renderable.flicker(750);
    }
    this.collided = true;
    return false;

/* in game.EnemyEntity.onCollision() */
if (response.b.body.collisionType !== me.collision.types.WORLD_SHAPE) {
    return false;
}
// Make all other objects solid
return true;
To unsubscribe from this group and stop receiving emails from it, send an email to melonjs+unsubscribe@googlegroups.com.

David Salcer

unread,
Dec 29, 2014, 3:35:03 AM12/29/14
to mel...@googlegroups.com
Thanks so much everyone for the help!
Reply all
Reply to author
Forward
0 new messages