RafaelBarbosatec / bonfire

(RPG maker) Create RPG-style or similar games more simply with Flame.
https://bonfire-engine.github.io
MIT License
1.22k stars 188 forks source link

Bugfix/tile rotation anchor #534

Closed dvmatyun closed 3 months ago

dvmatyun commented 3 months ago

Description

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

Breaking Change

Does your PR require Flame users to manually update their apps to accommodate your change?

dvmatyun commented 3 months ago

I also will try another solution, because Anchor.center requires all objects to have same center anchor

dvmatyun commented 3 months ago

Pushed a fix for default top-left anchor. However it still will be good to check and adjust that for all type of anchors image

RafaelBarbosatec commented 3 months ago

Hi @dvmatyun ! Thanks for contributing! I not understand why the current keyboard events not work for you, is better send de event object to caver all cases.

I like you rotation solution. I don't knew that tile did could have anchor.

Do you can separate this PR in two?

We can approve and improve the rotation solution.

dvmatyun commented 3 months ago

@RafaelBarbosatec sure, will separate them PS also check this one for right rotation decoding for base64 uncompressed JSON tile data https://github.com/RafaelBarbosatec/tiled_json_reader/pull/9

RafaelBarbosatec commented 3 months ago

@RafaelBarbosatec sure, will separate them PS also check this one for right rotation decoding for base64 uncompressed JSON tile data RafaelBarbosatec/tiled_json_reader#9

updated. thanks for contribution

dvmatyun commented 3 months ago

@RafaelBarbosatec I saw you used a center anchor for tile rotation fix. I think that may lead to some problems (because other objects are anchored to top-left by default), but maybe I'm wrong. I'm preparing a PR for solution like this (without chaning an anchor), what do you think in general about this?

void _setOtherParams(TileComponent tile) {
    tile.id = id;
    tile.angle = angle;
    tile.opacity = opacity;
    if (isFlipHorizontal) {
      tile.flipHorizontallyAroundCenter();
    }
    if (isFlipVertical) {
      tile.flipVerticallyAroundCenter();
    }

    // Needs to be debugged with different anchors. Works for default.
    // tile.anchor = Anchor.topCenter;
    _translateTileAngle(tile); // Force tile to be in it's box after rotation
  }

  void _translateTileAngle(TileComponent tile) {
    // Depending or where the rotated object is - move it to positive coordinates:

    final angle = tile.angle;
    final sin = math.sin(angle);
    final cos = math.cos(angle);
    if (tile.anchor.x != 0.5) {
      final delta = (1 - 2 * tile.anchor.x) * tile.width * tile.transform.scale.x;
      if (cos < 0.9) {
        tile.transform.x -= delta * cos;
      }
      if (sin < 0.9) {
        tile.transform.y -= delta * sin;
      }
    }

    if (tile.anchor.y != 0.5) {
      final delta = (1 - 2 * tile.anchor.y) * tile.height * tile.transform.scale.y;
      if (sin > 0.9) {
        tile.transform.x += delta * sin;
      }
      if (cos < 0.9) {
        tile.transform.y -= delta * cos;
      }
    }
  }

PS this solution can be polished too, but it workes for fine for standart 90/180/270/360 degree rotations with top-left anchor

dvmatyun commented 3 months ago

Closing this PR. This fix as well as collision fix is moved to https://github.com/RafaelBarbosatec/bonfire/pull/535/files