forleafe

Return the color of a sprite?

Recommended Posts

Is there a way for PixiJS (or any plugin/script) to return the color value of a sprite if given a point value to check? 

What I'd like to do is create a collision map, which would be a large sprite with nothing but black and white shapes. This sprite would be on it's own layer underneath a painted background image. a character sprite would move around on a layer above, and any time the edges of it collides with a black part of the collision map, it would hit a wall.

Share this post


Link to post
Share on other sites
9 minutes ago, icp said:

Hi!

I think that you are looking for the .tint property:

https://pixijs.download/dev/docs/PIXI.Sprite.html#tint

I'm not sure that's quite right. It says the tint value "applied" to the sprite. But we're not applying any tint here I don't think. The map is just a black and white colored png that gets loaded in. I need to be able know, given a position, whether a part of that sprite is black or white.

Share this post


Link to post
Share on other sites

Take original source, use getImageData() on canvas to get everything and convert it to your monochrome image.

Unfortunately, nobody who did that posted a plugin, so you have to learn the same thing from scratch. Fortunately, you'll need to know whats getImageData and 2d context anyway :)

As for extract, that'll be very slow.

let img = texture.baseTexture.resource.source
let canvas = null
if (img instanceof Canvas) {
    canvas = img;
} else {
   //create canvas, use drawImage
}
let context = canvas.getContext('2d');
let imageData = context .getImageDate(0, 0, w, h);

If you want to be a hero - please make a plugin after you implement it for your game.

Share this post


Link to post
Share on other sites
On 7/14/2019 at 6:00 AM, ivan.popelyshev said:

Take original source, use getImageData() on canvas to get everything and convert it to your monochrome image.

Unfortunately, nobody who did that posted a plugin, so you have to learn the same thing from scratch. Fortunately, you'll need to know whats getImageData and 2d context anyway :)

As for extract, that'll be very slow.


let img = texture.baseTexture.resource.source
let canvas = null
if (img instanceof Canvas) {
    canvas = img;
} else {
   //create canvas, use drawImage
}
let context = canvas.getContext('2d');
let imageData = context .getImageDate(0, 0, w, h);

If you want to be a hero - please make a plugin after you implement it for your game.

Thanks so much for your reply, but I have a few additional questions if you don't mind, hun?

You say use getimagedata to fetch all of the image data from the entire canvas, but I just need the data from one black and white png Sprite, which may not even be visible on the screen. It would be covered up by other sprites.

Also, why do I need to convert it to a monochrome image if the image I'm providing is already black and white?

Lastly, what do you mean by "take original source?"

Thanks so much for your help! 💕

 

Share this post


Link to post
Share on other sites

You say use getimagedata to fetch all of the image data from the entire canvas

For every image that you download, you have to run through temp canvas to get all pixels - that way you'll get monochrome bitmaps for those images. You even can pack it 1 bit per pixel if you know bitwise operations.

It has to be done independent of pixi, you dont need renderer for that, only loader. 

You also have to pass it to Sprites somehow, maybe make a link from baseTexture to corresponding black*white image.  

If you want perfect interaction, override Sprite containsPoint() method and check which pixel was hit, look at your mono-bitmap. 

I wrote that stuff several times but so far no one made a plugin from it. I already have like 10 plugins in pixi that are actively used by people, and it looks like i have to write 10 more :)

Share this post


Link to post
Share on other sites

Usually people use different approach to collisions - they wrap objects with PhysicsEditor and download their shapes as separate JSON files.

How does that shape connect to pixijs object, its for you to decide.

That's shame that we dont provide examples for all those approaches, but our team is very small and focused on rendering nightmares, and, again, if somebody else makes a good article (GOOD and not just hello-world in medium.com), we can add a link in pixijs wiki.

Share this post


Link to post
Share on other sites
On 7/15/2019 at 4:58 PM, ivan.popelyshev said:

Sorry for complaining.

If you happen to actually solve that problem the way I wrote, I can spend time to polish it to a real plugin or at least article, and you'll be our hero :)

I'll absolutely work on this, and come up with a solution. But before I can begin I need to do a good bit of additional research/learning, and be 100% sure of this approach you're suggesting. I'm still a little unsure that I fully understand the approach.

So let me get this straight:
My objective here is to have a function that, when given a coordinate point value and a sprite, it will return the pixel color in either RGB or Hex.

In order to do this, I need to grab the image from the Pixi loader, and then run a standard Javascript method called getImageData() to break the image down and retrieve all of the data from it. I then need to sort through that data and build an array which will contain every pixel's position and color. From there, A function can easily be made which can retrieve the necessary information from the array.

Is my understanding correct? If I'm misunderstanding anything at all please feel free to correct me.

To my knowledge, I'll need to do a little extra research on the getImageData() method, and learn what the heck 2D context is. Anything else you recommend I research here?

Once again, I deeply appreciate all of the help! I do hope to create something that is useful to many people.
 

Share this post


Link to post
Share on other sites

Yep, its correct!

Now that i think about it, we can make it lazy, something like 
 

function getSpriteAlpha(sprite, point) {
   localPoint = sprite.toLocal(point);
   localPoint.x += sprite.anchor.x * sprite.texture.width;
   localPoint.y += sprite.anchor.y * sprite.texture.height;
   localPoint.x = Math.round(localPoint.x);
   if (localPoint.x < 0 || localPoint.x >= sprite.texture.width) {return false; }
   baseTex = sprite.texture.baseTexture;
   if (!baseTex.bitmapStuff) {
       const img = baseTex.resource.source;
       //generate bitmapStuff based on img, use temporary canvas + getImageData here
       
   } 
   return baseTex.bitmapStuff[localPoint.y * baseTex.height + localPoint.x];
}

OH, I almost implemented that. Guess its not that difficult.

I actually need like 10 minutes more to implement that and debug, but I'll leave it to you :) Tell me if you'll have problems with implementing the rest.

Share this post


Link to post
Share on other sites

OK, I apologize, its not 10 minutes, its 20.

https://www.pixiplayground.com/#/edit/EOxtz6zy7rsr2ryzzPNBC

A shame. Now we dont need a hero. One more interesting problem was murdered by serial task-maniac.

I hope that you can convert containsPoint to whatever you need for collisions :)

Share this post


Link to post
Share on other sites
16 hours ago, ivan.popelyshev said:

OK, I apologize, its not 10 minutes, its 20.

https://www.pixiplayground.com/#/edit/EOxtz6zy7rsr2ryzzPNBC

A shame. Now we dont need a hero. One more interesting problem was murdered by serial task-maniac.

I hope that you can convert containsPoint to whatever you need for collisions :)

Oh darn!! I was going to work on this over the weekend, but thank you very much for writing this. I very much so appreciate it!

I'm looking over what you wrote, and had a couple of questions about it.

Your containsPoint function looks like it contains all of the necessary logic for converting the bunny sprite to a bitmap image that we can determine the pixel color with if we're given a point. But as is, does this function actually return the pixel color of a given point yet? I'm having trouble understanding what this function will actually end up doing and what further work I'll need to do from here.

Second, I'm not sure I'm quite following why on mouse over, the bunny sprite has a tint filter added to it. Is there a reason you added this?

Thanks!
 

Share this post


Link to post
Share on other sites

it asks to generate "hitmap" if its not ready.

hitmap stores only 1 bit per pixel, whether alpha is more than threshold=127, or less.

tint is here for a test, if you move mouse over the bunny you'll see tint :)

if you need more than 1 bit per pixel, you can adjust the way hitmap is generated - either save every 4th byte (alpha), or just store everything (hitmap = imageData.data) 

dont forget to change address function, right now im using "hitmap[NUM / 32  ] = 32 bits, NUM%32-th bit is pixel value" , but with 1 byte per data it'll be just "hitmap[num] = alpha" , hitmap is Uint8Array.

If you fail to do your stuff in hour or two, ask me again, i'll help.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.