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

Actor built in components should be extensible - "Extending" built-in components on Actors #2896

Closed
eonarheim opened this issue Jan 20, 2024 Discussed in #2895 · 0 comments · Fixed by #2924
Closed

Actor built in components should be extensible - "Extending" built-in components on Actors #2896

eonarheim opened this issue Jan 20, 2024 Discussed in #2895 · 0 comments · Fixed by #2924

Comments

@eonarheim
Copy link
Member

Actor build in components should be extensible

See discord discussion https://discord.com/channels/1195771303215513671/1198087869282140170/1198087869282140170

Discussed in #2895

Originally posted by mattjennings January 19, 2024
I've been attempting to implement my own physics system. Thanks to ECS it's been straight forward to swap out the Motion & Collision systems with my own. This lets me still make use of Actor's built-in components such as body and collider, which is great! That is, until I inevitably need to extend either of those components with some custom behaviour to supplement the system, and this has put me in a bit of a pickle.

Consider this scenario: I want to add a set of raycasts pointing in each direction to aid in collision solving for my physics system. I could make a new separate component, but I'd like to leverage the existing body component on the actor as I think this is where it makes the most sense to be.

I could compose my own actor, but taking a peak at the default one shows there's a lot to replicate there. I thought about copying & pasting this into my own, but it uses an internal watch function.

I thought maybe I could replace the body component with my own:

class MyBodyComponent extends ex.BodyComponent {}

class MyActor extends ex.Actor {
    constructor() {
       super({})
       this.removeComponent('ex.body')
       this.addComponent(new MyBodyComponent())
    }

    public get body() { // <- called by super() before I've added it in my constructor
         return this.get(MyBodyComponent)
    }
}

super() accesses this.body which will call my custom getter, and throw an error because it won't exist yet.

So at this point I've had to settle with mutating the body, which is fine, but difficult to write cleanly

class MyActor extends ex.Actor {
    constructor() {
       super({})
       extendBody(this.body)
    }
}

extendBody(body) {
     body.myCustomProperty = 123
}

Any suggestions on how else this could be approached? I feel like composing my own Actor is the way to go here. If so, I wonder if there's a middle ground here between a bare entity and a custom Actor that Excalibur could offer.

@eonarheim eonarheim changed the title Actor build in components should be extensible - "Extending" built-in components on Actors Actor built in components should be extensible - "Extending" built-in components on Actors Jan 20, 2024
eonarheim added a commit that referenced this issue Feb 5, 2024
Closes #2896

- Fixed issue where Actor built in components could not be extended because of the way the Actor based type was built.
  - Actors now use instance properties for built-ins instead of getters
  - With the ECS refactor you can now subtype built-in `Components` and `.get(Builtin)` will return the correct subtype.
  ```typescript
  class MyBodyComponent extends ex.BodyComponent {}

  class MyActor extends ex.Actor {
      constructor() {
        super({})
        this.removeComponent(ex.BodyComponent);
        this.addComponent(new MyBodyComponent())
      }
  }

  const myActor = new MyActor();
  const myBody = myActor.get(ex.BodyComponent); // Returns the new MyBodyComponent subtype!
  ```
eonarheim added a commit to jyoung4242/Excalibur that referenced this issue Feb 16, 2024
…tors (excaliburjs#2924)

Closes excaliburjs#2896

- Fixed issue where Actor built in components could not be extended because of the way the Actor based type was built.
  - Actors now use instance properties for built-ins instead of getters
  - With the ECS refactor you can now subtype built-in `Components` and `.get(Builtin)` will return the correct subtype.
  ```typescript
  class MyBodyComponent extends ex.BodyComponent {}

  class MyActor extends ex.Actor {
      constructor() {
        super({})
        this.removeComponent(ex.BodyComponent);
        this.addComponent(new MyBodyComponent())
      }
  }

  const myActor = new MyActor();
  const myBody = myActor.get(ex.BodyComponent); // Returns the new MyBodyComponent subtype!
  ```
eonarheim added a commit that referenced this issue Feb 16, 2024
* added test for dom element existence prior to assigning this.canvas, throw error if not

* removed playbackend event emission on resume

* added fullscreen request to Loader

* fix: Release env variable for packaging

* chore: Update babel monorepo

* chore: Update dependency @types/node to v20.11.14

* chore: Update dependency @types/react-color to v3.0.11

* chore: Update dependency @types/node to v20.11.15

* fix: Allow CSS transforms on canvas (#2910)

This PR fixes an issue where CSS transforms confused the excalibur pointer system and caused clicks to land in the wrong spot

* chore: Update dependency css-loader to v6.10.0 (#2914)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore: Update dependency @types/react to v18.2.51

* chore: Update dependency karma-webpack to v5.0.1

* chore: Update dependency core-js to v3.35.1

* chore: Update dependency @types/node to v20.11.16

* chore: Update dependency docusaurus-plugin-typedoc-api to v4.1.0

* chore: Update dependency eslint to v8.56.0

* chore: Update dependency eslint-plugin-jsdoc to v46.10.1

* chore: Update dependency eslint-config-prettier to v9.1.0

* fix: Expose Tilemap collider

* feat: Pixel Art Sampler & Antialiasing Improvements (#2739)

This PR adds a new pixel art setting and special sampler for sub-pixel pixel art rendering.

Additionally this PR adds MSAA to the framebuffer implementation, giving a nicer look to some graphics when drawing to the quad boundary.

Also fixes an issue with `snapToPixel` where camera did not correctly snap to pixel

Example using the old `antialiasing: false` on pixel art

https://github.com/excaliburjs/Excalibur/assets/612071/c55a09b0-cf7e-409c-a82c-447e0bec198a

New `pixelArt: true`

https://github.com/excaliburjs/Excalibur/assets/612071/eff9f9f3-a731-482a-8e15-e778e60c225e

* fix: [#2896] Allow component subtypes to work on extend Actors (#2924)

Closes #2896

- Fixed issue where Actor built in components could not be extended because of the way the Actor based type was built.
  - Actors now use instance properties for built-ins instead of getters
  - With the ECS refactor you can now subtype built-in `Components` and `.get(Builtin)` will return the correct subtype.
  ```typescript
  class MyBodyComponent extends ex.BodyComponent {}

  class MyActor extends ex.Actor {
      constructor() {
        super({})
        this.removeComponent(ex.BodyComponent);
        this.addComponent(new MyBodyComponent())
      }
  }

  const myActor = new MyActor();
  const myBody = myActor.get(ex.BodyComponent); // Returns the new MyBodyComponent subtype!
  ```

* fix: [#2799] Change default Font Base Align to Top (#2925)

Closes #2799

This PR changes the default base align on Fonts to Top, this is more in line with user expectations. 

This does change the default rendering to the top left instead of the bottom left.

* fix: update uvPadding default when antialiasing: false or ImageFiltering.Pixel

* fix: Windows tests crash due to memory constraints (#2927)

* fix: tests

* update appveyor node

* fix lint

* rev excalibur-jasmine

* rev excalibur-jasmine

* temporarily xit

* Attempt to xit some dubious expectAsync

* xit more dubious

* improve test memory, still need to un-xit some tests

* fix for ci

* fix for ci

* clean up boot

* Add pool to dispose and fix default

* xit the memory killing batch rendering tests

* remove errant fdescribe

* add xit tests back

* feat: Implement Contact Bias Solver order for seams + Deprecate ex.Physics Static (#2926)

This PR implements arcade contact solver bias, so you can choose to solve horizontal or vertical first. Or to defer to the default order by distance.

Additionally this PR marks the `ex.Physics` static configuration object as deprecated and will be removed in v0.30. It still will work to configure physics behavior. Now the new way to configure physics will be where everything else is configured, the `ex.Engine({..})` constructor.

```typescript
const engine = new ex.Engine({
    ...
    physics: {
      solver: ex.SolverStrategy.Realistic,
      arcade: {
        contactSolveBias: ex.ContactSolveBias.VerticalFirst
      },
    }
  })
```


Without the bias

`ex.Physics.arcadeContactSolveBias = ex.ContactSolveBias.None;`



https://github.com/excaliburjs/Excalibur/assets/612071/0d7c1217-911d-4791-8425-b45d06f7da8e



Using the bias

`ex.Physics.arcadeContactSolveBias = ex.ContactSolveBias.VerticalFirst;`

https://github.com/excaliburjs/Excalibur/assets/612071/8873bedf-ea07-4e85-9376-8c1f8ae56089

* feat: Allow Tilemap meshing to be configurable

* fix: GraphicsGroup null/undefined guard to prevent crash

* fix: ParticleEmitter errant draw when using particleSprite

* fix: onCollision does not fire if collision canceled

* docs: Fix symbol linking + Pointer docs improvements (#2928)

Closes #

## Changes:

- fix: symbol link handling namespaces/fully qualified symbols
- docs: Better Mouse and Touch (formerly, "Pointers") docs using Twoslash snippets and updated for new API

* refactor(showcase): update retroski demo url (#2930)

* fix: Readme image

* fix: typo on offscreen/onscreen event docs

* fix: Fire collisionend when collider deleted + Composite collision start/end strategy (#2931)

One stealth feature 
* onCollisionEnd events now include the last side and contact which is useful for collision logic

This PR fixes 2 issues:

1. Fixes an issue where a collider that was part of a contact that was deleted did not fire a collision end event, this was unexpected
2. Fixes an issue where you may want to have composite colliders behave as constituent colliders for the purposes of start/end collision events. A new property is added to physics config, the current behavior is the default which is `'together'`, this means the whole composite collider is treated as 1 collider for onCollisionStart/onCollisionEnd. Now you can configure a `separate` which will fire onCollisionStart/onCollisionEnd for every separate collider included in the composite (useful if you are building levels or things with gaps that you need to disambiguate). You can also configure this on a per composite level to mix and match `CompositeCollider.compositeStrategy`
![image](https://github.com/excaliburjs/Excalibur/assets/612071/e1a9c954-8a39-4402-bee6-dad9b42f9c08)

* fix: Errant warning when using `pixelRatio` to upscale games

* docs: Update broken link

* feat: Add additional rayCast options `ignoreCollisionGroupAll` and `filter: (hit: RayCastHit) => boolean`

* fix: SearchAllColliders with filter

* fix: Scene transition bugs + Coroutines (#2932)

This PR fixes some Scene transition bugs
* If the root scene was overridden it would confuse the initial transition
* goto and goToScene now behave the same with regards to scene transitions
* Adds friendly warning instead of error when invalid scene update/draw's occur
* Switches Transitions to work via coroutine removing some update code in director

* feat: Debug Draw Static Helpers (#2929)

This PR adds new `ex.Debug` static for more convenient debug drawing where you might not have a graphics context accessible to you. This works by batching up all the debug draw requests and flushing them during the debug draw step.
  * `ex.Debug.drawRay(ray: Ray, options?: { distance?: number, color?: Color })`
  * `ex.Debug.drawBounds(boundingBox: BoundingBox, options?: { color?: Color })`
  * `ex.Debug.drawCircle(center: Vector, radius: number, options?: ...)`
  * `ex.Debug.drawPolygon(points: Vector[], options?: { color?: Color })`
  * `ex.Debug.drawText(text: string, pos: Vector)`
  * `ex.Debug.drawLine(start: Vector, end: Vector, options?: LineGraphicsOptions)`
  * `ex.Debug.drawLines(points: Vector[], options?: LineGraphicsOptions)`
  * `drawPoint(point: Vector, options?: PointGraphicsOptions)`

* fix: Dispose graphics context to avoid flakey test

* small refactor to avoid a breaking change and support string ids as well

---------

Co-authored-by: Erik Onarheim <erik.onarheim@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Kamran Ayub <kamran.ayub@gmail.com>
Co-authored-by: Mathieu H <32459394+mathieuher@users.noreply.github.com>
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

Successfully merging a pull request may close this issue.

1 participant