Jump to content
This forum will be closing down. Please move to the respective dedicated project forums.

tilemap.createFromObjects has downright insane behavior


Tilde
 Share

Recommended Posts

I'm not sure if I've somehow created this monster myself through an innocuous typo or anything, but wow is this one strange. I can instantiate the enemies just fine normally, but using createFromObjects exhibits something kind of indescribable, apparently conflating the enemies group with previously-established powerup groups. I've tried a few different parameter options, but nothing quite works out so well. Even if you don't know how to fix this, check it out for the surrealism.

 

Random manual enemy spawns (correct behavior):
http://www.hardmodeorders.com/slapspark/slapspark.html
Enemy spawns from map (incorrect behavior):

http://www.hardmodeorders.com/slapspark/errorshowcase/slapspark.html

 

Kill the invisible polyknights haunting you by sparking! Defeat the singularity of enemies by collecting them and turning them into a powerup! Only for them to become the next powerup! What! It's like Pac-Man as directed by Uve Boll.

 

Relevant (and possibly relevant) code:

  entities = this.add.group();  shotPowerupGroup = this.add.group();  entities.add(shotPowerupGroup);  shotPowerupGroup.enableBody = true;  for (var i = 0; i < 10; i++) {   var shotPowerup = shotPowerupGroup.create(game.rnd.between(0, 50 * 16), game.rnd.between(0, 80 * 16), 'shotPowerup');   shotPowerup.animations.add('idle');   shotPowerup.animations.play('idle', 14, true);  }  burstPowerupGroup = this.add.group();  entities.add(burstPowerupGroup);  burstPowerupGroup.enableBody = true;  for (var i = 0; i < 5; i++) {   var burstPowerup = burstPowerupGroup.create(game.rnd.between(0, 50 * 16), game.rnd.between(0, 80 * 16), 'burstPowerup');   burstPowerup.animations.add('idle');   burstPowerup.animations.play('idle', 14, true);  }  weaponPowerups = this.add.group();  entities.add(weaponPowerups);  weaponPowerups.enableBody = true;  for (var i = 0; i < 3; i++) {   tribeamPowerup = weaponPowerups.create(game.rnd.between(0, 50 * 16), game.rnd.between(0, 80 * 16), 'triShotPowerup');   tribeamPowerup.animations.add('idle');   tribeamPowerup.animations.play('idle', 14, true);  }  missilePowerup = weaponPowerups.create(game.rnd.between(0, 50 * 16), game.rnd.between(0, 80 * 16), 'missilePowerup');  missilePowerup.animations.add('idle');  missilePowerup.animations.play('idle', 14, true);  for (var i = 0; i < 3; i++) {   backAttackPowerup = weaponPowerups.create(game.rnd.between(0, 50 * 16), game.rnd.between(0, 80 * 16), 'backAttackPowerup');   backAttackPowerup.animations.add('idle');   backAttackPowerup.animations.play('idle', 14, true);  }   // Enemies  enemies = this.add.group();  entities.add(enemies);  //polyknight  //map.createFromObjects('ObjectLayer1', 1719, '', 0, true, false, enemies, Polyknight, false);  polyknight = new Polyknight(this.game, 400, 200);  enemies.add(polyknight);  //blaad  //map.createFromObjects('ObjectLayer1', 1687, '', 0, true, false, enemies, Blaad, false);   for (var i = 0; i < 3; i++) {   blaad = new Blaad(this.game, game.rnd.between(0, 50 * 16), game.rnd.between(0, 80 * 16));   enemies.add(blaad);  }   //replid  //map.createFromObjects('ObjectLayer1', 1686, '', 0, true, false, enemies, Replid, false);  replid = new Replid(this.game, game.rnd.between(0, 50 * 16), game.rnd.between(0, 80 * 16));  enemies.add(replid);  console.log(enemies);  // Allies  allies = this.add.group();  entities.add(allies);  // Player exists   this.spawnPoint = this.add.group();  map.createFromObjects('ObjectLayer1', 1720, '', 0, true, false, this.spawnPoint, Phaser.Sprite, false);  console.log(this.spawnPoint);  this.spawnX = this.spawnPoint.children[0].x;  this.spawnY = this.spawnPoint.children[0].y;  this.spawnAngle = this.spawnPoint.children[0].rotation;  console.log(this.spawnAngle);  player = new Player(this.game, this.spawnX, this.spawnY);  player.rotation = this.spawnAngle;  console.log(this.spawnX + ", " + this.spawnY);  entities.add(player);

What the map looks like:

 

post-15035-0-21514300-1439375977.png

Link to comment
Share on other sites

Sorry, let me reframe: That first link is the intended behavior. It works. The enemies are simply being generated by their classes rather than the createFromObjects function. The second is the same thing, but with createFromObjects. The commented-out code lets you see both versions at once.

 

The black things are powerups. The things moving that are not your ship are enemies. You can shoot at them.

 

The point is, by attempting to spawn the enemies by passing in their GID and class, they somehow...I don't even know how to describe it. Some of them have undefined x/y values, causing them to be everywhere and nowhere at once, and they all have "merged" with the weaponPowerups group despite having no apparent links to them at all.

 

One interesting thing is that the spawnPoint group, as seen in the code as an object to define where the player should spawn, has 11 children despite there being only one instance of the spawnPoint object on the map and, as far as I can tell, inside the JSON file.

Link to comment
Share on other sites

It's like Pac-Man as directed by Uve Boll.

 

You, sir, have won the Internet today.

 

Funny story: I found a reply of mine from a year ago talking about this. I totally did not do this because createFromObjects didn't let me be flexible/lazy about how my sprites were created. I might take another look, but the "must know the GID ahead of time" thing is kinda a deal breaker for me these days. In the game I'm working on right now I iterate through every object in a specially named layer "entities" and create my sprites based on the name of the object. Kinda painful and doesn't look so great in Tiled. I might take another look and see if createFromObjects wouldn't work better, though... would be awfully nice to see my sprites instead of positioning those little rectangles.

 

Is this the right map JSON? My first guess is that a bunch of objects in your object layer have a width and height of 0, which Phaser will dutifully assign in createFromObjects. I'm not sure what the solution is, though, since I'm not sure how Tiled decides what the widths and heights are there. Presumably from the tilemap, if you're assigning from a tileset? Should Tiled be assigning them?

 

Your object layer also doesn't have a width or height. Not sure Phaser cares? But that seems weird.

 

Change those to the right widths and heights or make sure your sprite ignores width and height settings and see if that helps.

Link to comment
Share on other sites

I guess having a height of 0 on the object layer is typical. Ugh, so complicated. If I can get this to work right, I'll swallow the GID bullet. The only thing is, I can't change to manually setting the width/height of enemy objects, for so many reasons.

 

I'd try setting "spawn points" like I do for the player, but then I might have another problem of inexplicably bloated sprite groups. What's up with that, anyway?

 

...Maybe I'll try commenting out those lines in phaser.js.

Link to comment
Share on other sites

Ooooh! Thank you for pointing out those lines. Commenting that out made a huge difference. Although now, some stuff is overlapping in a weird way. Like Blaads are spawning where Replids are. But it generally works! Thank you.

 

I still want to know why the spawn group has 11 objects in it...

Link to comment
Share on other sites

Oh man, I just figured part of this out, it's great.

 

Observe the following code.

// Enemies  enemies = this.add.group();  entities.add(enemies);  //polyknight  map.createFromObjects('ObjectLayer1', 1719, '', 0, true, false, enemies, Polyknight, false);  //blaad  map.createFromObjects('ObjectLayer1', 1687, '', 0, true, false, enemies, Blaad, false);  //replid  map.createFromObjects('ObjectLayer1', 1686, '', 0, true, false, enemies, Replid, false);    console.log(enemies);

Right now, we have some pretty good functionality here. A new thing is happening: For every Blaad, a Polyknight is created on top of it. For every Replid, a Blaad and a Polyknight is created on top of it. Only Polyknights are created by themselves. So createFromObjects is now creating an instance of everything it created before on top of the new thing. What the heck.

 

New behavior can be seen here, the game's running pretty slow because of the ridiculous number of enemies being spawned as a result, especially in the lower-right:

 

http://www.hardmodeorders.com/slapspark/errorshowcase/slapspark.html

Link to comment
Share on other sites

I've been staring at the code for createFromObjects and I'm not seeing how that's possible. Not saying it's not happening, just not understanding how it *could* happen.

 

Then I spent a bunch of time looking at your code, enough time to get swarmed by a bunch of Polyknights.

 

I got nothin'. I wish I could help. ¯\_(ツ)_/¯

Link to comment
Share on other sites

So this is...annoying. Why on Earth would it act this way? I agree with you, judging from the method, it makes no sense that it'd spawn one everywhere there's a spawn point for any enemy. I did a check to see the GIDs of enemies being spawned and it came out clean.

Perhaps something to do with the fact that my enemy classes extend Enemy, which itself extends Sprite?

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...