Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't get anything to render from Tiled file #344

Closed
Cretezy opened this issue Apr 14, 2022 · 16 comments
Closed

Can't get anything to render from Tiled file #344

Cretezy opened this issue Apr 14, 2022 · 16 comments

Comments

@Cretezy
Copy link

Cretezy commented Apr 14, 2022

Steps to Reproduce

Reproduction: https://github.com/Cretezy/excalibur-tiled-bug

Rough important code:

const game = new Game();
game.initialize();



export class Game extends Engine {
  // ...

  async initialize() {
    // This Actor does: this.graphics.add(Resources.Box.toSprite());
    // This sprite shows up!
    const player = new Player();
    this.add(player);

    // Resources file (using Vite, so ?url required. The file does load correct and the assosiated PNG too.
    // import level1 from "../assets/levels/Level 1.tmj?url";
    // import box from "../assets/images/box.png";
    // 
    // export const Resources = {
    //   Box: new ImageSource(box),
    //   Level1: new TiledMapResource(level1),
    // } as const;
    const loader = new Loader([Resources.Box, Resources.Level1]);

    await this.start(loader);

    Resources.Level1.addTiledMapToScene(this.currentScene);
  }
}

The level in Tiled:
image

It has an object layer with excalibur="true" (bool), and a camera. Camera works correctly (tested with player sprite that does show up).

Expected Result

I expected the tilemap to be draw on screen.

Actual Result

Only see the player sprite.

image

Environment

Tested on Firefox (100) and Chromium (99) on Linux (Arch).

Tiled 1.8.4, Excalibur 0.25.3, this package 0.25.3.

Current Workaround

Download https://github.com/excaliburjs/excalibur-tiled/archive/refs/tags/v0.25.3.zip, extract in folder, import TiledMapResource from ../excalibur-tiled-0.25.3/src/tiled-map-resource.

@Cretezy
Copy link
Author

Cretezy commented Apr 14, 2022

Found a weird workaround:

Download https://github.com/excaliburjs/excalibur-tiled/archive/refs/tags/v0.25.3.zip, extract in folder, import TiledMapResource from ../excalibur-tiled-0.25.3/src/tiled-map-resource.

Basically, using the original code seems to make it work, so it's possible it's an issue with Vite. Going to dig deeper.

@eonarheim
Copy link
Member

@Cretezy Thanks for the issue and reproduction repo!

I think Vite is doing something interesting to the code, not sure what is wrong exactly. I'm still digging 👍

@Cretezy
Copy link
Author

Cretezy commented Apr 14, 2022

@eonarheim I dug pretty deep, and still nothing.

image

Using the npm version, I see that all assets are properly loaded, but I can't figure out why they aren't rendering. I see the layers and TileMap being created, the image data is populated, so I don't know what's going on still.

@eonarheim
Copy link
Member

eonarheim commented Apr 14, 2022

I think I know what's going on Vite seems to be mangling the constructor name 😞

So the instanceof check is failing and it's not being added to the Scene

*Edit with better picture
image

@Cretezy
Copy link
Author

Cretezy commented Apr 14, 2022

Where is this code you're seeing? I'll take a look.

Got it! It's the World class

Changing my Vite config to this doesn't help:

export default defineConfig({
  assetsInclude: ["**/*.tmj", "**/*.tsj"],
  publicDir: "assets",
  esbuild:{
    keepNames:true,
  }
});

@eonarheim
Copy link
Member

I'm stepping into the addTiledMapToScene -> this.world.add() -> add()

image

I've tried a few Vite config changes without luck, but it does explain why your workaround works

@Cretezy
Copy link
Author

Cretezy commented Apr 14, 2022

image

I'm also able to replicate the issue.

@Cretezy
Copy link
Author

Cretezy commented Apr 14, 2022

image

@eonarheim
Copy link
Member

Doing a little more digging this morning, I think there may be an issue with the esbuild pre-bundle not respecting the keepNames correctly vitejs/vite#5489

@Cretezy
Copy link
Author

Cretezy commented Apr 14, 2022

For now, switched to Parcel and having no issues with it!

However, I am having a collision issue. I could open a new ticket if you'd like. https://github.com/Cretezy/excalibur-tiled-bug/tree/collision

Basically when a collision happens (collisionstart), it seems like it keeps colliding (precollision). The main issue though is that when 2 blocks are sliding against each other (but shouldn't be colliding), a collision is detected.

@Cretezy
Copy link
Author

Cretezy commented Apr 14, 2022

Another question (again, I could make another issue for this if you'd like):

Why is my camera not smooth? Is this just sub-pixel snapping, or is there a lerp value that can be set somewhere?

quickshare-2022-04-14_18.22.03.mp4

Relavant code:

 public update = (engine: Engine, delta: number) => {
    const up = engine.input.keyboard.isHeld(Input.Keys.W);
    const down = engine.input.keyboard.isHeld(Input.Keys.S);
    const left = engine.input.keyboard.isHeld(Input.Keys.A);
    const right = engine.input.keyboard.isHeld(Input.Keys.D);

    if (up) {
      this.vel = vec(0, -Player.SPEED);
    } else if (down) {
      this.vel = vec(0, Player.SPEED);
    } else if (left) {
      this.vel = vec(-Player.SPEED, 0);
    } else if (right) {
      this.vel = vec(Player.SPEED, 0);
    } else {
      this.vel = vec(0, 0);
    }
  };
this.camera.strategy.lockToActor(player);

I tried onPreUpdate instead of update, I tried setting the camera's position manually in onPreDraw, I tried elasticToActor with multiple values but none gave a smooth result.

@eonarheim
Copy link
Member

@Cretezy I'm glad Parcel 2 is working for you! I posted on that similar Vite issue so hopefully we get some clarity there, I'll update our bundler docs and perhaps the template as well to call out the keepNames quirk.

For the Collision question the precollision event is a slight misnomer (open to better name suggestions for these events), it fires before collision resolution for each pair each frame, and the postcollision event which fires right after collision resolution to prevent overlap for each pair each frame.

The event collisionstart fires when colliders first make contact, and collisionend fires the first frame when that collider pair they separate. This might be what you want? One caveat to this is that TileMap use CompositeColliders to build up their solid pieces so crossing a seam in the geometry may cause another collisionstart/collisionend I could see this seam crossing behavior being considered a bug by users... let me know what you think here, I think I might have a way to change that behavior.

For the Camera question, try applying the camera strategy once in an onInitialize() instead of each frame, internally the camera strategy will create an object to keep track of state and update itself automatically with the Camera. elasticToActor should smooth move to the Actor (https://excaliburjs.com/sample-platformer/ code). If lockToActor or elasticToActor is still behaving oddly after that, I think that might be an Excalibur bug (in the ideal world the Camera should be the very last thing to update before drawing to prevent odd jitter one possible work around is to set the camera position in the Scene onPostUpdate).

I think the documentation could be clearer about how to use camera strategies, I'll make some updates 👍

@eonarheim
Copy link
Member

eonarheim commented Apr 15, 2022

Okay I can 100% replicate the jitter on lockToActor in the released version, I'll confirm it's fixed in latest before next release.

Edit: Seems to be working correctly in the lastest main branch

Workaround in your Scene add

this.on('postupdate', () => {
    this.camera.pos = actor.pos;
});

// or

onPostUpdate() {
   this.camera.pos = actor.pos;
}

@eonarheim
Copy link
Member

Also updated some documentation regarding Camera strategies https://excaliburjs.com/docs/cameras#camera-strategies

@Cretezy
Copy link
Author

Cretezy commented Apr 15, 2022

For collisions:

Yes, it does seem like it's a seam problem. Here's a video demo:

quickshare-2022-04-15_12.39.38.mp4

For camera:

I was already doing lockToActor/elasticToActor in my onInitialize in my scene. I tried your suggestion, which worked! But only in Chrome 😅 but that's good enough for now!

The platformer sample also is a little jittery in Firefox, so it seems to be a browser/GPU issue. I'm on Firefox 100 on Arch.

@eonarheim
Copy link
Member

@Cretezy I'm closing this for now I think we've resolved all the issues in this thread 👍

  1. Composite collider fix in main
  2. Improved docs
  3. Workaround Vite by switching to Parcel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants