?SOLVED?Checking Distance on Overlapping Pixels

For questions about using Classic.

Post » Sun Jan 15, 2012 10:27 am

I've been trying to find information about pixel coordinates and the likes like crazy today, without any luck. I've gotten another idea how to do what I wanted to do then.
But I still don't know how to do it, or where else to look for answers on this.

Is there a way to check how much (how many pixels) one side of an object has overlapped another objects pixel area?

Related to that I would also like to know if there is a way to retrieve the furthermost pixels coordinates of any side. Let's say the furthermost pixel on the left side of the sprite, checking from the hotspot. So meaning left relative to the hotspot.

I am basically just trying to find a way to exclude transparency of sprites in calculations. And starting with pixels whose opacity or alpha level is higher than a certain amount.Shindoh2012-01-16 11:45:30
B
3
G
1
Posts: 70
Reputation: 615

Post » Sun Jan 15, 2012 11:49 am

I wouldn't know of any way of getting those informations, unless you know the shape of the object and calculate it.

But what you describe sounds like a typical job for a pixel shader. Is there a reason for trying to do it on the cpu side?
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Sun Jan 15, 2012 12:18 pm

[QUOTE=tulamide] I wouldn't know of any way of getting those informations, unless you know the shape of the object and calculate it.

But what you describe sounds like a typical job for a pixel shader. Is there a reason for trying to do it on the cpu side?[/QUOTE]
Thanks for Your time again, tulamide.

And yes, there is a reason. I am trying to use it for collision calculations.
Let's say we have an Ellipse Sprite, that we use as a collision mask.
Now if the Player Sprite, or any other movable Object Sprite overlaps the Ellipse in one Tick, let's say by 5 pixels, I want to position the Player Sprites border back exactly those 5 pixels it overlapped.

If for example the Right Pixel Border of the PlayerSprite overlaps the Left Border of the EllipseSprite by 5px on X, move the PlayerSprite.X -= 5px.
And similar procedures for .Y values and other borders.

I really need those pixel coordinates, to know where the border between transparency and opaque pixels is, so I can do accurate backplacing for the collision.

I don't know of another way doing it accurately right now.
I can think of some workarounds, but they would all be huge time consumptions compared to this and would still lack the same precision, while similar.

It's driving me slightly mad. Shindoh2012-01-15 12:21:35
B
3
G
1
Posts: 70
Reputation: 615

Post » Sun Jan 15, 2012 12:36 pm

I see.
I never worked pixel based, because I prefer time based, but couldn't you just make your own push out routine?

If the player sprite overlaps the left side of the ellipse, then repeat sending the player sprite to .X - 1 until it doesn't overlap anymore.
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Sun Jan 15, 2012 12:49 pm

[QUOTE=tulamide] I see.
I never worked pixel based, because I prefer time based, but couldn't you just make your own push out routine?

If the player sprite overlaps the left side of the ellipse, then repeat sending the player sprite to .X - 1 until it doesn't overlap anymore.[/QUOTE]
That's a good idea. But then again, how are You able to state when it doesn't overlap anymore, when You don't know where the pixel border is?

EDIT: Okay, I just got it! We just need to use a While Loop! While Player Overlaps, substract .X -= 1. Thank You!! I should think time based more often.

That means While loops inside the same Tick, until it falsifies?

2nd EDIT: Wait, this is weird. I guess I was happy a little too soon?
In theory, if While worked that way, and I am also thinking it should (from what I read now), it would be perfect and very useful. But I just made a simple test, checking the Overlap between two objects with the While condition.
I used the Overlap condition check from the Player Object, and set .X back -1, while it is overlapping.

However in reality the Player was set back -1 every Tick now, as long as it was overlapping. Not -1 in one Tick until it wouldn't overlap anymore. So You could watch as it was pushed back out in slow motion.

Then I tried the System Objects Overlapping(Advanced) condition and basically did the same as above. But this time it worked exactly as it should, it would be pushed back instantanously the next Tick.

Why? Please don't tell me it's another bug, lol.Shindoh2012-01-15 14:05:50
B
3
G
1
Posts: 70
Reputation: 615

Post » Sun Jan 15, 2012 2:34 pm

No, it's not a bug. It is just you thinking way too complicated :D

Serious, a while loop will normally be executed within one tick. But if you use triggers to start the while loop that will be true for a couple of ticks, then it will loop a couple of ticks.

Try this:
+ System: While
+ Sprite: X Less than 640
-> Sprite: Set X to .X + 1

Now if you use a textbox and an always event with
->Text: Set Text to TickCount

you will see that the sprite is immediatly at x = 640

The loop will be checked on every tick, but since the sprite is at 640 from tick 1 on, it won't be executed.

If you'd set .X to 300 or whatever in the always event, then the while loop will be executed (and will iterate 340x) on every tick, not just once.

So, take care of the trigger and make sure the while loop will only be run once and when needed.tulamide2012-01-15 14:34:49
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Sun Jan 15, 2012 3:14 pm

But tulamide, then I still don't understand this behaviour.
I do understand what You are saying.

Let me show You how I tested it and it didn't work (Events are in order):

+ Always
-> Sprite1: Set X to MouseX
-> Sprite1: Set Y to MouseY

+ While
+ Sprite1: Overlaps Sprite2
-> Sprite1: Set X to .X - 1

What should now happen (to my understanding), is that Mouse.X will always be overwritten, when Sprite1 overlaps Sprite2. This should result in Sprite1 always moving along the left border of Sprite2, whenever it tries to overlap Sprite2.

However what happens visually is nothing at all in this case. Because it behaves like in another test I did before, and just moves Sprite1 back -1px .X every Tick instead of in one.

Now when I do it like this:

+ Always
-> Sprite1: Set X to MouseX
-> Sprite1: Set Y to MouseY

+ While
+ System: Is Overlapping(Advanced) Sprite1 (PICK) Overlaps Sprite2 (PICK)
-> Sprite1: Set X to .X - 1

It works. (The Pick option doesn't even matter in this case, even when I didn't pick either it worked)
B
3
G
1
Posts: 70
Reputation: 615

Post » Sun Jan 15, 2012 6:25 pm

[QUOTE=Shindoh]
Now when I do it like this:

+ Always
-> Sprite1: Set X to MouseX
-> Sprite1: Set Y to MouseY

+ While
+ System: Is Overlapping(Advanced) Sprite1 (PICK) Overlaps Sprite2 (PICK)
-> Sprite1: Set X to .X - 1

It works. (The Pick option doesn't even matter in this case, even when I didn't pick either it worked)[/QUOTE]
This is where my advice is important: Take care of the trigger.
There is a difference between them both. Sprite's overlapping condition is like a one time switch. If it is true, it is true at the beginning of the tick, and loses its state as soon as we do an action (yes, gets invalid within the tick). Therefor the while-loop will only be executed for exactly one iteration.

The system condition on the other hand is like asking for the current status, without changing it. Therefor the while-loop will go through all iterations needed, until asking, if both are overlapping, returns false.

To prove that, you could add a global that you raise by 1 for every iteration of the while loop. You will then see, that it will only raise by 1 for every tick, if you use sprite's overlapping condition, but raise by whatever pixels needed, if you use the system's condition.

Don't ask me though, why the sprite's overlap condition behaves that way.
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Mon Jan 16, 2012 11:30 am

I see. Thank You again, tulamide. That's why I love forums, and especially this place. It's full of knowledge, and full of people with knowledge who can help each other to learn about something they are interested in and share a passion for.

Although I still think it's weird to essentially have the same condition behave differently, depending on where it is checked from. At least the different checking behaviour should be clear.
If I check for 'Is Overlapping', then I expect it to be a continuous check and not a one time result. And perform actions according to "as long as overlapping". If I wanted them to be executed once I'd use the 'perform once' expression.
But this way it would be useless in a while loop, unless I used the System Condition.
In other words, if I applied actions to the Sprite Condition, it would make no difference if they are in a while loop or not, this way. It would behave the same.Shindoh2012-01-16 11:37:44
B
3
G
1
Posts: 70
Reputation: 615

Post » Mon Jan 16, 2012 1:31 pm

[QUOTE=Shindoh]If I check for 'Is Overlapping', then I expect it to be a continuous check and not a one time result. And perform actions according to "as long as overlapping". If I wanted them to be executed once I'd use the 'perform once' expression.
But this way it would be useless in a while loop, unless I used the System Condition.
In other words, if I applied actions to the Sprite Condition, it would make no difference if they are in a while loop or not, this way. It would behave the same.[/QUOTE]
I know what you mean, although we don't have exactly the same point of view. I wouldn't expect sprite's "is overlapping" to bahave as it does, but I wouldn't expect the system's one to behave as it does, either!
And here's why. CC is a tick-based system. Every tick is like a short period of stopping the process. You can do whatever you like within that tick, and everything gets computed, and the whole process will continue as soon as you are done. So one tick may use 10ms to get computed, another one may need 2 seconds. But I'd expect consistency, everything that's true at the beginning of a tick should be true throughout the tick. Of course that would render loops within a tick almost pointless, but one could rely on the status of a tick.

I suspect that "Blue Sprite overlaps Red Sprite" is only checking before entering the tick and then gets confused by continously asking for the state of that Blue Sprite while at the same time altering its position value. I come to this conclusion, because I can make it work, if I avoid using the overlap condition as a while-condition.

+ System: Always (every tick)
-> Sprite: Set position to MouseX, MouseY
-> System: Set global variable 'done' to 0

+ Sprite: Sprite overlaps Sprite2
-> System: Set global variable 'done' to 1

+ System: While
+ System: Is global variable 'done' Equal to 1
-> Sprite: Set X to.X - 1
++ Sprite: [negated] Sprite overlaps Sprite2
--> System: Set global variable 'done' to 0

Believe it or not, this one works. The only difference is that the while-condition is a test against a value of a global now, and that global will be altered in a sub-event that checks for overlapping, again. Confuses me.
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Next

Return to Help & Support using Construct Classic

Who is online

Users browsing this forum: No registered users and 2 guests