wiserim / phaser-raycaster Goto Github PK
View Code? Open in Web Editor NEWRaycasting plugin for Phaser 3. Documentation:
Home Page: https://wiserim.github.io/phaser-raycaster/
License: MIT License
Raycasting plugin for Phaser 3. Documentation:
Home Page: https://wiserim.github.io/phaser-raycaster/
License: MIT License
Is your feature request related to a problem? Please describe.
Yes, raycasting does not support Spine 2D objects.
Describe the solution you'd like
An update to this library for supporting Spine 2D objects.
Describe alternatives you've considered
None.
When using a scrolling tilemap, the original edges of screen are treated like collision points for the rays. But this only appears to happen from outside of the original bounds of the screen. For example, if the screen is 400x300. at a point of 450,300, the rays will collide with an invisible wall at x=400
Steps to reproduce the behavior:
1 .create an phaser scrolling tilemap game that is larger than screen
2. travel to the down and right.
3. turn around. when facing up-left, the rays are colliding with the original edge of the screen
Expected behavior
no collision should happen
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Windows 10/Chrome
There are two instances in 0.10.7 where .lenght
is used instead of .length
phaser-raycaster/dist/phaser-raycaster.js
Line 724 in e5d088c
phaser-raycaster/dist/phaser-raycaster.js
Line 1441 in e5d088c
Describe the bug
Tilemap raycasting no longer works in Phaser 3.52.0.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The shadows will only show in the top left corner.
Screenshots
Phaser 3.22.x
Phaser 3.52.x
Desktop:
Is your feature request related to a problem? Please describe.
Raycaster plugin doesn't seem to have TS typings, which results in a lot of guesswork:
As well as annoying (but fortunately non-breaking) errors:
Describe the solution you'd like
I would like to get TS typings for the raycaster plugin.
Describe alternatives you've considered
The plugin seems to already have JSDoc style comments. I wonder if those could be automatically converted to TS typings somehow.
Additional context
If possible, it would be for the best if the typings were built-in and not a separate package like "@types/phaser-raycast-plugin". Or if someone happens to know about these things more than me and can make it work easily, why not. I just feel that this whole electron + phaser + typescript + webpack + plugin combinations is already pretty complicated.
Description
Removing an obstacle causes the raycaster to crash.
Demo
I forked Phaser-raycaster - example 9 - field of view (v0.8 update)
and edited to destroy first obstacle on scene click:
https://codepen.io/pierre-josselin/pen/bGegjeO
Log
castCircle.js:46 Uncaught TypeError: Cannot read property 'get' of undefined
at i.s [as castCircle] (castCircle.js:46)
at initialize.<anonymous> (pen.js:91)
at initialize.h.emit (phaser.min.js:1)
at initialize.processMoveEvents (phaser.min.js:1)
at initialize.update (phaser.min.js:1)
at initialize.updateInputPlugins (phaser.min.js:1)
at initialize.onMouseMove (phaser.min.js:1)
at HTMLCanvasElement.onMouseMove (phaser.min.js:1)
Thank you for this plugin, it's awesome !
I've created a custom class called Actor
that inherits from Phaser.Container
and I've added a number of sprites to the class that are all nested inside of the container.
I've created a Phaser.GameObjects.Rectangle
that is a part of the container to act as the bounding box for ray casting for that object.
// Actor.js
class Actor extends Phaser.GameObjects.Container {
constructor (scene) {
super(scene)
this.scene.add.existing(this)
this.boundingBox = new Phaser.GameObjects.Rectangle(scene, 0, 0, 16, 32)
this.boundingBox.setDisplayOrigin(8, 24)
this.boundingBox.parent = this
this.add(this.boundingBox)
}
castRay () {
let ray = this.scene.raycaster.createRay()
ray.setOrigin(this.x, this.y)
ray.setAngleDeg(DIRECTION_ANGLES[this.direction])
const intersection = ray.cast()
console.log('inter', intersection)
}
}
// Scene.js
create () {
this.raycaster = this.raycasterPlugin.createRaycaster({
debug: { enabled: true },
})
const actor = new Actor(this)
this.raycaster.mapGameObjects(actor.boundingBox)
}
Here's a screenshot of what I'm experiencing. You can see the red rectangle is the boundingBox having been successfully mapped into the Raycaster plugin. However, you can also see the ray that's casted goes right through the rectangle and doesn't hit.
Am I doing something wrong?
Hello, how can I increase the limit of the ray instead of basing it on the scale of the game? For example, I have a config setting of:
scale: {
parent: "content",
scaleMode: Phaser.Scale.WIDTH_CONTROLS_HEIGHT,
autoCenter: Phaser.Scale.CENTER_VERTICALLY,
width: 560,
height: 1212,
},
If the player position x is greater than the scaleWidth, like player position x is 565, it would limit the result of intersection x. The pink dots are the intersection limit which 560 even though there are no colliders/mappedobjects nearby.
How can I solve this since there are no docs regarding this issue?
I want to make circular FOV in the form of the following picture.
I have tried many things such as reducing the length of the rayRange while looking at all your ray cast related codepen, but it is not easy for me to make the code into the form I want.
Can I ask for help if possible?
https://codepen.io/scm1400/pen/qBoGxQX
ray = raycaster.createRay({
origin: {
x: 400,
y: 300
},
detectionRange: 150,
ignoreNotIntersectedRays: false,
rayRange:150,
// round: true,
// autoSlice: true, //automatically slice casting result into triangles
collisionRange: 150, //ray's field of view range
});
When adding a container it just iterates over all children and it tries to create a raycaster map for each of these.
In essence this is okay, but when - for example - adding a graphics object to a container the config method falls through to the default
case. When this object is missing some required methods this will crash the game in several places.
rectangle.updateMap
which could be skipped by disabling the child map right after creating it, but this is currently not easy to do.container.updateMap
which can not be skipped by disabling the object's raycastermap.So it would be interesting to check for existence of required methods before calling them.
function isObjectSupportedByRaycaster(
object: Phaser.GameObjects.GameObject | Phaser.GameObjects.Components.GetBounds,
): object is Phaser.GameObjects.Components.GetBounds {
// add whatever methods are required for raycaster map to work.
return 'getBounds' in object;
}
or in js
function isObjectSupportedByRaycaster(object) {
// add whatever methods are required for raycaster map to work.
return typeof object.getBounds === 'function';
}
In my game I'm spawning a few rays for hitbox detection and I'd love to have some convenience methods for destroying them. Right now I'm not sure of the proper way to clean up my raycasts and physics objects linked to those ray casts other than deleting the physics body and graphics objects manually. Even then I'm not sure if there are still objects hanging around in memory linked to the ray itself.
Hi,
Just want to warn you that it does not work with the actual phaser beta (3.50.0-beta.9). This may be a bug in phaser but I think its short before stable release.
Maybe worth a look... for a quick scan just: npm i [email protected]
Thank you for this awesome plugin. Saved me a lot of time!!!
Hello wiserim,
Thank you for making this project! I'm finding it very useful.
Could you add your contact info to GitHub so I could send you an email with some feedback and questions I have? Also may have an opportunity for you if interested.
Sorry for opening an issue, no other way to reach out to you :p
This took a while to figure out. I assumed I was doing something wrong as the library looks well-written and well-maintained.
else if (!object.data) {
object.setDataEnabled();
object.data.set('raycasterMap', map);
}
The objects I was passing to the mapGameObjects already have a data field set by myself. You may want to reconsider this requirement or put a big warning somewhere that no data needs to be on the object when it's passed onto the library.
Thanks and keep up the good work.
What about Matter Physics? It would be great to make this work both with matter and arcade physics. If you could give a quick overview of what needs to be changed to make this work with matter ill happily have a look by myself. Thank you!
In my game I am using shapes from PhysicsEditor to generate Matter Sprites with polygon shapes for Matter colliders. These sprites are then passed into raycaster.mapGameObjects
as dynamic.
But since I upgraded to 0.10.7/8, I started getting an exception thrown when calling mapGameObjects
with certain, but not all, concave shapes.
I suspect it might have to do with the recent optimization that was introduced in 0.10.7 regarding the array of neighbours. For this specific error to be thrown, it seems like the pointA.neighbours
array is missing for some reason.
The sprite is created as follows:
const hullImage = gameContext.matter.add.sprite(
x,
y,
ImageDatabase.GameElementsSpritesheetKey,
hullPhaserImageKey,
{
shape: shapes[hullPhysicsShapeName],
}
);
This is an example of shapes[hullPhysicsShapeName]
which throws the exception:
{"type":"fromPhysicsEditor","label":"AngelicaBot_Hull","isStatic":false,"density":0.10000000149011612,"restitution":0,"friction":0.10000000149011612,"frictionAir":0.01,"frictionStatic":0.5,"collisionFilter":{"group":0,"category":1,"mask":255},"fixtures":[{"label":"","isSensor":false,"vertices":[[{"x":0,"y":19},{"x":12,"y":6},{"x":47,"y":2},{"x":90,"y":14},{"x":215,"y":64},{"x":5,"y":42}],[{"x":1,"y":124},{"x":0,"y":102},{"x":91,"y":127},{"x":71,"y":139},{"x":13,"y":137}],[{"x":47,"y":2},{"x":71,"y":2},{"x":90,"y":14}],[{"x":0,"y":102},{"x":5,"y":97},{"x":214,"y":76},{"x":229,"y":98},{"x":231,"y":125},{"x":91,"y":127}],[{"x":90,"y":14},{"x":228,"y":14},{"x":233,"y":19},{"x":233,"y":35},{"x":215,"y":64}],[{"x":0,"y":59},{"x":5,"y":42},{"x":215,"y":64},{"x":214,"y":76},{"x":5,"y":97}]]}]}
And this is an example of shapes[hullPhysicsShapeName]
which DOES NOT throw the exception:
{"type":"fromPhysicsEditor","label":"Hull_01","isStatic":false,"density":0.1,"restitution":0,"friction":0.1,"frictionAir":0.02,"frictionStatic":0.5,"collisionFilter":{"group":0,"category":1,"mask":255},"fixtures":[{"label":"","isSensor":false,"vertices":[[{"x":182,"y":47},{"x":240,"y":46},{"x":250,"y":57},{"x":251,"y":91},{"x":228,"y":102}],[{"x":228,"y":154},{"x":240,"y":154},{"x":250,"y":165},{"x":251,"y":199},{"x":244,"y":206},{"x":182,"y":210},{"x":171,"y":194}],[{"x":3,"y":57},{"x":14,"y":47},{"x":72,"y":46},{"x":171,"y":194},{"x":12,"y":99},{"x":5,"y":92}],[{"x":171,"y":62},{"x":182,"y":47},{"x":228,"y":102},{"x":228,"y":154},{"x":171,"y":194}],[{"x":3,"y":113},{"x":12,"y":99},{"x":12,"y":148},{"x":4,"y":143}],[{"x":3,"y":165},{"x":12,"y":148},{"x":83,"y":194},{"x":72,"y":209},{"x":14,"y":210},{"x":4,"y":199}],[{"x":12,"y":148},{"x":12,"y":99},{"x":171,"y":194},{"x":83,"y":194}],[{"x":83,"y":62},{"x":171,"y":62},{"x":171,"y":194}]]}]}
In my main game class I have a createCar
method, which dynamically creates a car and iterates over other cars and maps raycast between each other (so cars can detect the distance between each other):
createCar(scene, x, y, angle, speed, name) {
const car = new Car(scene, x, y, angle, speed);
car.name = name; // for debug
this.carsGroup.children.iterate((c) => {
c.raycaster.mapGameObjects(car, true);
car.raycaster.mapGameObjects(c, true);
});
this.carsGroup.add(car);
}
It works unless I want to delete a car:
update() {
this.carsGroup.children.iterate((car) => {
// Car is out of screen
if (!this.cameras.main.worldView.contains(car.x, car.y)) {
this.carsGroup.remove(car);
this.carsGroup.children.iterate((c) => {
c.raycaster.removeMappedObjects(car);
car.raycaster.removeMappedObjects(c);
});
car.destroy();
} else {
car.update();
car.debug();
}
});
}
Then it fails here when it tries to retrieve the "raycasterMap" and destroy it:
object.data.get('raycasterMap').destroy();
raycaster-core.js:396 Uncaught TypeError: Cannot read properties of undefined (reading 'destroy') at Raycaster.removeMappedObjects (raycaster-core.js:396:48) at game.js:51:23
I can't figure out how to properly remove an object from the scene and memory. If I call car.destroy()
other cars throw exceptions, because the raycast still has references.
Code sample: https://codepen.io/vvyshko/pen/bGOxpbG
As seen in here for example:
I don't get what this is for, but I don't like how it fills the whole screen with a phaser-raycaster-ray-body
, which I assume has no use actually?
Here I create a raycaster and just randomly set the boundingBox
position and size to where ever:
const raycaster = scene.raycasterPlugin.createRaycaster({
debug: GameConfig.debug.raycast,
boundingBox: new Phaser.Geom.Rectangle(
300, 300, 100, 100
)
});
This affects nothing as far as I know. All of the raycastings in my game still work exactly like they did before.
So is there any reason why I shouldn't just throw the boundingBox away somewhere? The reason I am asking is that it gets in to the way when debugging the game and / or using mouseSpring, as the mouse wants to drag the raycaster bounding box instead of my game objects.
Is your feature request related to a problem? Please describe.
I am attempting to build a game with dynamic lights and shadows. That is, visibility is restricted to surfaces in FOV which are also lit. I would like to implement this with raycasters- light sources produce light-rays, used to build a "light-shape". Some of the edges of this shape describe lit walls, but some edges describe the boundary of light and dark on the floor.
Secondly, the camera entities raycast against that "light-shape" to produce the FOV.
The problem with the current implementation is that I need the camera-rays to act somewhat differently that light-rays. Whereas light-rays are stopped by any surface, camera-rays need to be able to pass through those light-shadow boundaries. It should be able to detect the light-dark boundaries, but also should pass through them to detect any further light-shapes that might lie beyond.
I hope that question does not sound too crazy :-)
Describe the solution you'd like
The ability to mark some surfaces as transparent, but detectable.
Describe the bug
When calling ray.overlap(), I receive an error this.testOverlap is not a function because its undefined.
To Reproduce
From #7 in the documentation, I have this code
`this.ray.autoSlice = true;
this.ray.enablePhysics();
this.ray.setCollisionRange(200);
this.ray.castCircle();
let visibleObjects = this.ray.overlap();
`
However, when this.ray.overlap() is called, I receive the error above.
Is there any additional setup required to use overlap?
Is your feature request related to a problem? Please describe.
I'm trying out phaser-raycaster and really liking it so far. There is one feature I'd love to see, and that's the ability to have rays bounce off of objects. This would allow a few cool uses of phaser-raycaster that I have in mind. Perhaps there's a way to do this already, but I wasn't able to figure it out.
Describe the solution you'd like
Off the top of my head, the following would be nice:
maxBounces
, a number defining how many times a ray is allowed to bounce before it's complete. defaults to 1.shouldBounce
, an optional function that when provided, will be called to determine if a given ray's collision with an object shold result in a bounce. This would allow defining only certain GameObjects as bouncable. returns boolean. defaults to undefined
.create() {
this.raycaster = this.raycasterPlugin.createRaycaster({
maxBounces: 4,
shouldBounce: (collisionInfo) => collisionInfo.bodyB.data.get("reflective") == true
});
}
Describe alternatives you've considered
I tried using a series of setOnCollide
callbacks to cast new rays when existing ones collided, but it quickly got complex and difficult to manage, especially due to the asynchronous nature of the callbacks.
Thanks for all the work you've done and for reading this issue!
The Raycaster.Map#destroy
function throws an object is not defined
error:
To Reproduce
After adding objects with mapGameObjects(gameObjects)
, call raycaster.removeMappedObjects(gameObjects);
The fix
phaser-raycaster/src/map/destroy.js
Line 12 in 1d6541e
delete object.raycasterMap;
to delete this.object.raycasterMap;
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.