collinhover/impactplusplus

How much 'light' or 'shadow' is there "here"?

Closed this issue · 5 comments

I'd like to know how I could query impact++ to find out how much light there is in a certain x, y position.

Doing a stealth game :P

There is no built in method for this yet. You could do this in several ways that I can think of:

1
Lights are split into several ig.ImageDrawing (off screen canvasses), one of which is the shadows called imageCast. You could use the canvas getImageData method to get the raw RGBA data from the image, and test your x/y position. Note that getImageData is not very fast, so it may not be the best option if you are doing a lot of tests. Link to the imageCast: https://github.com/collinhover/impactplusplus/blob/master/lib/plusplus/entities/light.js#L286

2
This involves changing the way shadow casting works internally. Right now, lights get all the shadow casting entities within the light's bounding box, then they send that entity the imageCast.dataContext, the entity figures out the contour of the shadow it would cast based on the light, and then the entity draws it into the context it was given. I'm not sure how option 2 would compare in speed to option 1...

  • you'd need to move the drawing step (line 2914 of ig.EntityExtended) back into the light, and have the entity only return the contour
  • you could save all the contours and combine them into a shadow shape
  • your character probably has an AABB for collision, so you just test if all 4 vertices of the AABB are inside the shape using ig.utilsintersection.pointInPolygon
  • note it might be faster to skip combining the contours into a single shape and just test the character against all shadow shapes, and if one vertex fails just skip checking the rest

For option 2, the relevant methods are:
https://github.com/collinhover/impactplusplus/blob/master/lib/plusplus/entities/light.js#L743
https://github.com/collinhover/impactplusplus/blob/master/lib/plusplus/core/entity.js#L2579
https://github.com/collinhover/impactplusplus/blob/master/lib/plusplus/helpers/utilsintersection.js#L506

Whatever option you choose, if it works well (and fast), I'd appreciate you making a pull request to add the features to the library =)

Hm... actually, what if you just do...

if (entity.lineOfSight(lightEntity) && entity.distanceTo(lightEntity) <= lightEntity.radius 400)

I guess the only problem is to make the lineOfSight method check for entities and not only the collision...

Yes that could work if entities could block line of sight. Not a bad idea :-)

Closing for now, if you get this working feel free to make a pull request.

It turns out I really need the lineOfSight to check entities for a few other things I'm doing.

I have no idea how it works or how to expand upon it though, would appreciate if you wanna give it a go ;D