Newbie: Sprite intersect

enonod

Well-Known Member
Licensed User
Longtime User
I hope I don't fill this forum with stupid questions. So do you.
I have used...
if sprite.IntersectsPoint(x,y) =True then sprite.direction=90
and have placed it in Timer1.tick in the example program.
I have stepped and used the watch. The sprite position goes through the x,y position (at one point being equal) and never becomes true. What am I not doing please?

Also can I drop the = True?

As an aside the debug watches are brilliantly easy to use, wow what a pleasure.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can see the behavior of IntersectsPoint in the Walking Character example by changing the Timer1_Tick code to:
B4X:
Sub Timer1_Tick
    'Manually change the current frame.
    sprite.CurrentFrame = (sprite.CurrentFrame + 1) Mod 8 + 8 * direction
    If sprite.IntersectsPoint(100,100) Then form1.Text = sprite.X & " " & sprite.Y
    gw.Tick
End Sub
Also can I drop the = True?
Yes.

If it still doesn't work, please post some of your code so we will be able to help.

BTW, your questions are good questions and I'm sure that the answers will help other users as well.
 

enonod

Well-Known Member
Licensed User
Longtime User
Thank you for your reassurance Erel.
The following is a slightly modified Sprite example provided with B4PPC for learning purposes.
In the App_Start I set cw.direction to 0 and x,y to 48,76. cw.velocity=1, Then I move one pixel in X each tick. The sprite moves perfectly and the watch shows the correct x,y including the target 176,76 and beyond.

I cannot see that putting the test after the tick would have an effect.

Sub Timer1_Tick
gw.Tick 'VERY IMPORTANT: causes the GameWindow to advance to the next step.
tick = tick + 1
If tick Mod 50 = 0 Then gw.DeleteMarkedSprites
If cw.IntersectsPoint(176,76) = True Then cw.direction = 90
End Sub

[EDIT]
I have put the intersect line in the walking sample and it doesn't work, however, without pressing any buttons, just stepping the code, it changes direction of its own accord at x=161 which is not the edge of the screen. ( If it is then I can't see where it has been set) Even so 156 is < 161
I must be missing something here.

I set direction to 0 and sprite.x to 90 and sprite.y to 76
Sub Timer1_Tick
'Manually change the current frame.
'sprite.CurrentFrame = (sprite.CurrentFrame + 1) Mod 8 + 8 * direction
'If sprite.IntersectsPoint(120,100) Then form1.Text = sprite.X & " " & sprite.Y
If sprite.IntersectsPoint(156,76)=True Then sprite.direction = 90
gw.Tick
End Sub

Any pointers please?
[EDIT-1]
Weirder still, if I simply change the number 76 to 77 in intersects line in the above code the sprite starts in direction 270, change it back to 76 and it reverts to direction 0

Now I am baffled.
 
Last edited:

enonod

Well-Known Member
Licensed User
Longtime User
Well I must be totally dense. I appreciate that the attached walkingchar did work, I tried it when you first mentioned it. I must be misunderstanding because I am not trying to use an edge. I am trying to choose a point anywhere on screen, send a sprite travelling through it and expect an event when it arrives at it.
To do this I expected to use If sprite.IntersectsPoint(156,76)= but received the unexpected results mentioned above.
I wanted to understand (especially the weirder part) what was going wrong and why. Not find an alternative.
Why dense? Because I cannot see the connection between the edge (which seem to be constants) detection and the intersects point.
If you be a bit more explicit I would be grateful.
 

enonod

Well-Known Member
Licensed User
Longtime User
I apologise but think we are talking at cross purposes and have got out of sync somehow.

... I am not trying to use an edge. I am trying to choose a point anywhere on screen, send a sprite travelling through it and expect an event when it arrives at it.
To do this I expected to use If sprite.IntersectsPoint(156,76)= but received the unexpected results mentioned above.

I still don't know why IntersectsPoint is not working for my purpose nor why I get the strange behaviour.
If it is incorrect use, then please tell me that I have chosen the wrong keyword and put me right. I wish to change direction at pre-programmed chosen points, not edges.
If I have not made myself clear please tell me. :)
Thank you.
 

enonod

Well-Known Member
Licensed User
Longtime User
Thank you for your comment. The code was posted and I did say that it was a simple modification to the Sprite example program provided with B4PPC. The modification is posted and the results I received (one of them odd).
I don't see what more I can do.
Here it is again...

I set direction to 0 and sprite.x to 90 and sprite.y to 76
Sub Timer1_Tick
'Manually change the current frame.
'sprite.CurrentFrame = (sprite.CurrentFrame + 1) Mod 8 + 8 * direction
'If sprite.IntersectsPoint(120,100) Then form1.Text = sprite.X & " " & sprite.Y
If sprite.IntersectsPoint(156,76)=True Then sprite.direction = 90
gw.Tick
End Sub

The edit can be seen with the commenting out and the replacement line.
I am not for one moment suggesting that I haven't written something stupid or missed something out. I simply posted the code and sought help.
Then the conversation appeared to go onto edges.

Have I still not made it clear?
Thank you.
 

enonod

Well-Known Member
Licensed User
Longtime User
Sorry, I misunderstood.
The file and support is attached.
It is the original Sprite demo with unnecessary??? lines removed so that I didn't get confused and could analyze the simplest situation.
A breakpoint was placed on line 33 and watches for cw.X and cw.direction.

I am sure it is something stupid but I cannot understand why changing the number as mentioned in earlier post, had the effect it did.

Thank you if you are able and willing to assist.
 

agraham

Expert
Licensed User
Longtime User
The problem is that the starting X and Y co-ordinates for the sprite are for the upper left corner. It also appears that the intersect test is a > or < rather than an equals test. So for your 15 x 15 sprite starting at Y = 76 the values that will produce an intersection are between Y = (76 + 1) = 77 and Y = (76 + 15 -1) = 90.

I think the same hold for the intersection test on X. The intersection at Y=100 occurs when cw.X = 86 not 85. EDIT I just realised this is a rubbish statement. Please ignore it. I haven't tested X intersection properly

EDIT AGAIN : I have now tested the X intersection and it does exhibit the same "off by one" effect as the Y intersection.
 
Last edited:

enonod

Well-Known Member
Licensed User
Longtime User
Thank you for your assistance agraham. I understand what you are driving at and it is fine if it is consistent (which I don't know).
When you say the upper left corner do you mean the actual pixel on the corner or a position one removed from the corner i.e. outside the sprite?
I can understand > or < when the sprite is moving in that direction so that while moving in X it is OK but if it is not moving in Y direction then...
As an observation it would be useful if the help file reflected this important aspect.
Any further observation will be welcome while I experiment.
Thank you again.

[Edit] It may be observed that by adjusting these numbers, the sprite is then out of position when it turns the corner.
[Further Edit] If for 176 one uses 174 (not 175) the sprite oddly is in position when turning in the grid. I don't quite see why unless it is a 'fence posts' problem in my calculations.
 
Last edited:

agraham

Expert
Licensed User
Longtime User
it is fine if it is consistent (which I don't know)
It will be I'm sure.
When you say the upper left corner do you mean the actual pixel on the corner or a position one removed from the corner i.e. outside the sprite?
The actual pixel I think, check it yourself with a stationary sprite at 0,0 and 1,1.
It may be observed that by adjusting these numbers, the sprite is then out of position when it turns the corner.
:confused:
 

enonod

Well-Known Member
Licensed User
Longtime User
Thank you for getting me going agraham. The query at the end of your post...
the turn point I originally used 176,76 would have turned the sprite to travel down the grid exactly between the lines. By having to adjust the number it runs down on the line.
By changing the number to X=174 to turn the sprite travels between the lines.
The line is at 175 and the sprite should be at 176 to not overlap it.
That was all... I can't see why. No answer required, I'll get there in the end.
 

enonod

Well-Known Member
Licensed User
Longtime User
The problem is that the starting X and Y co-ordinates for the sprite are for the upper left corner. It also appears that the intersect test is a > or < rather than an equals test. So for your 15 x 15 sprite starting at Y = 76 the values that will produce an intersection are between Y = (76 + 1) = 77 and Y = (76 + 15 -1) = 90.

Sorry to bring this up again but I am not quite clear. When you say < and > do you mean the internal B4PPC test? If so, can you say why it is not = because...

If the corner pixel of the sprite is actually on Y=76 and moves in direction zero (X changing not Y) then the pixel at the other end of the sprite block (15 x 15 hence +15) will travel along coord 76 and pass over each X pixel at Y76 Why must I check one pixel down the block at Y 77?
This seems to suggest that the edge pixels of a sprite (all of them round the block) cannot be tested for position

[EDIT] and what about a single pixel sprite (if you could see it)

Any further enlightenment will be appreciated.
 
Last edited:

agraham

Expert
Licensed User
Longtime User
Sorry to bring this up again but I am not quite clear. When you say < and > do you mean the internal B4PPC test? If so, can you say why it is not =
Yes, I mean the collision test and no, I don't know why.

If the corner pixel of the sprite is actually on Y=76 and moves in direction zero (X changing not Y) then the pixel at the other end of the sprite block (15 x 15 hence +15) will travel along coord 76 and pass over each X pixel at Y76 Why must I check one pixel down the block at Y 77?
This seems to suggest that the edge pixels of a sprite (all of them round the block) cannot be tested for position. And what about a single pixel sprite (if you could see it). Any further enlightenment will be appreciated.
I can't really offer any further enlightenment. Just play with various settings and see how it behaves.
 

enonod

Well-Known Member
Licensed User
Longtime User
Thank you agraham, I have done that now and with the help of the attached diagram I can illustrate what actually happens in practice. This may be of interest to anyone using this Intersect command, because it 'seems' to have a problem.

I have attached a program illustrating the principle (larger grid to give time to watch) and in the array of numbers have use +1 to highlight where the problem occurs. (Run on destop.)

The green sprite moves one pixel at a time until it is detected, then changes direction 90 degrees and so will travel clockwise.
It starts at x=1 y=1 and progresses x=2 y=1, x=3 y=1 etc.

I attempt to detect its arrival using the Red points such that when the direction changes the sprite is always between the large grid lines.
It does seem to me odd that an equality test is not done instead of > & < because it can clearly be seen from the diagram that a single pixel horizontal line used as a sprite say x=1 y=1 to x=5 y=1 won't work (not tested) because it doesn't hit the blue.

The intersect points actually required to make this work are shown Blue. Note that one of the expected Reds works anyway.

If the red points are used then the sprite does not always travel between the grid lines it is often out by one but of course not always.
If you find a flaw in this please let me know.
 
Top