Move a number of images to a rectangle

I have a number of images which I want to moveTo() so that they align horizontally, therefore I want them to stop when they hit a rectangle. I realize I could create a texture for the rectangle similarly to what is done for platforms in the “Making your first Phaser 3 game”, but I would prefer to create the rectangle programmatically. I have code similar to the following:

function create() {
  var imgs = [
    this.physics.add.image(100, 100, 'myTexture', 0),
    this.physics.add.image(100, 100, 'myTexture', 1)
  ];
 
  g = this.physics.add.group();
  g.addMultiple(imgs);
  rect = this.add.rectangle(0, Y, W, H, "#FF8000");
  this.physics.add.existing(rect);
  for (i=0; i<imgs.length; i++) {
    this.physics.moveTo(imgs[i], i*100, Y, 200)
  }
  this.physics.add.overlap(g, rect, function(c){
    c.body.stop();
    console.log("collision");
  });
}

however my images move but the overlap callback is never called. What am I doing wrong?

Do your images already have dynamic bodies when you add them to the group? It’s a static group, so any bodies that it creates shouldn’t be able to move. Are you sure that the rectangle is in the correct position? Enable debugging to check. In your call to add.overlap, what is handedCards? It’s not referenced anywhere else in the snippet.

Hi Telinc1, thanks for your answer. I modified the code example to show how the images are created, and modified the group to a non-static one. I still don’t get a collision (no log). I imagine the images do have dynamic bodies, as I’ve always been able to move them. However, I’m not sure about the rectangle. I tried enabling debugging, and I see "vectors pointing in the direction in which my images are moving, but no collision. Note that images as well as the rectangle are visible.

When overlapping a group with another body, the group’s child will be the second argument to the collision handler. In your function, c is the rectangle, not the images. To stop the movement of the images, you’ll have to add a second parameter and call stop() on its body. With this change alone, the updated code works for me - the images move to a certain point, then stop when they touch the rectangle.

The rectangle is technically added incorrectly - the fill color should be a number, not a string, which is why you can’t see it. You should specify it as 0xFF8000, not "#FF8000". Keep in mind that a rectangle’s default origin (like with other game objects) is its center, not its top left corner. If this is what’s causing your problem, use setOrigin(0) on the rectangle to move its origin. If you still can’t figure out where the rectangle is, scroll the camera (see the same example in my previous post) with debugging enabled to find it.

2 Likes

Thank you Telinc1, with your suggestion it worked! Surprisingly when I created two rectangles and added them to a static group, the order of the two parameters to the callback flipped, but I realized that and fixed the code.

Generally, the callbacks will receive the objects in the same order you pass them to the collider. The exceptions are collisions between groups and sprites (the sprite will be passed in first), tilemaps and sprites, and tilemaps and groups (the tilemap will be passed in second). It’s usually best to check the source code to see the exact order in which you’ll get your arguments (keep in mind that groups aren’t arrays).