• Gamedev
  • Strategies for side-scrolling a circular room

Hi,

I've been stuck on the following problem for days. I am less asking about how to solve this, as I am asking if my strategy is correct or if anyone might have other approaches. But of course, any help at all appreciated.

I have a game in which…

  1. The camera/viewport (C) follows the player's x position.
  2. When the player reaches the left or right of a room, they wrap to the other side, creating the effect of a circular room. (From A to B and B to A)
  3. The viewport is not as wide as the entire room.

This works fine, but the challenge is in E and F above: showing the room in front of you, which is really the room on the opposite side.

My attempts at cracking this in ct.js have been rough.

My current strategy has been to leverage PIXI as much as possible…

  1. Create two "placeholder" rectangular sprites at either end, representing the player's "forward" view.
  2. At each draw cycle, if the player is within a certain range of one end or the other, I capture ct.room as a texture, and then assign that texture to the placeholder sprite.

This works on the left side (!!) but for the life of me I can't get it working on the right, where the content is always in the wrong position or not visible at all.

My code, mostly for illustrative purposes of the strategy I'm trying:

let fillLeft = ct.types.list['LeftRightFill'][0];
let fillRight = ct.types.list['LeftRightFill'][1];
let renderer = ct.pixiApp.renderer;
let texture = PIXI.RenderTexture.create(4880, 640);
let textureR = PIXI.RenderTexture.create(4280, 640);

if (this.activePlayer.x <= 600 && this.activePlayer.x >= 0) { 
    renderer.render(ct.room, texture);
    fillLeft.texture = texture;
    fillLeft.x = -3680 - 600 + ct.camera.x;
    fillLeft.visible = true;
    fillRight.visible = false;
} else if (this.activePlayer.x > 3080 && this.activePlayer.x <= 3680) {
    renderer.render(ct.room, textureR);
    fillRight.texture = textureR;
    fillRight.x = ct.camera.right - 600;
    fillRight.visible = true;
    fillLeft.visible = false;
} else {
    fillLeft.visible = false;
    fillRight.visible = false;
}

Also, I am trying to ensure the solution is performant. This could become very processor intensive.

One note: I can't use repeating backgrounds, because that wouldn't show all the elements in the room aside from the background.

    lazza This works on the left side (!!) but for the life of me I can't get it working on the right, where the content is always in the wrong position or not visible at all.

    Try doing this:

    • setting the anchor of the right texture to 1;0 (I think that's the problem), and
    • using ct.camera.x instead of ct.camera.right if you use fittoscreen catmod without letterboxing, to exclude the factor of the non-constant viewport width.

    In any way, I would consider doing this instead: if a player trespasses a width of a room minus some border (viewport size, for example), all the objects from the left side are teleported to the right side. Once the player trespasses the width of the room, both they and those objects are teleported to the left side of the room.

    This is, btw, more efficient, because renderer.render(ct.room, textureR); draws the whole room in an additional pass, effectively doubling the costs to draw one frame.

      In any way, I would consider doing this instead: if a player trespasses a width of a room minus some border (viewport size, for example), all the objects from the left side are teleported to the right side. 

      OMG why didn't I think of that. Sooo much easier. 😅 Thank you @CoMiGo

      Plus my previous approach was eating my CPU.

        Wow. It pretty much works. (Minor issues but basically does the trick. And smoothly at that!)

        I'm already looping through all the Copies, so I added this check:

            if (currentX > ct.room.length - ct.camera.width/2 && this.x < ct.camera.width/2) {
                this.x += ct.room.length;
            } else if (currentX < ct.camera.width/2 && this.x > ct.room.length - ct.camera.width/2) {
                this.x -= ct.room.length;
            }
          Write a Reply...