Sprite attributes (properties)

enonod

Well-Known Member
Licensed User
Longtime User
I assume that you mean counting ticks. I personally think it would be a useful attribute, and would be pleased with that, but I would not want to be responsible for having things added that nobody would find useful or that you do not think sensible.
If that is not an issue in this case, then thank you.
 

enonod

Well-Known Member
Licensed User
Longtime User
I find many tests that relate to individual sprites and where they are etc. but I have not been able to find anything for the GameWindow that indicates if a (any) sprite occupies a particular space or pixel. For example a sprite may be permitted to move in a certain direction if no other sprite occupies that space (i.e. if the target sprite were to move it would collide).
To actually cause it to collide in order to discover the fact, would require moving the sprite back afterward, since collision is not a 'touch' it is an overlap.

If I have not missed something, would it be possible to ask the GameWindow if pixel X,Y is occupied (or a range)?

[Edit] Just to add a few comments (and I may be wrong here), everything relies on collision. A sprite's position appears to be its top left corner, but even if one could detect a sprite is present [SpriteAt(x,y)] it would still not appear to be possible to detect any other part of the sprite's presence. So if a sprite were detected at x,y, even though the size of the sprite is known to the coder it is still not possible to detect another part of the sprite. So any setection of a sprite can only be by its TLC, to enable calculation of the remaining occupied pixels. i.e. if the detection were simply that a piece of a sprite occupied x,y, there would be no way of knowing the total location. It might be nice to know that a sprite is sitting, stationary at an edge, thus preventing any attempt to move it off the edge, without being forced into a collision to find out. Ramble...
 
Last edited:

agraham

Expert
Licensed User
Longtime User
Ramble...
I don't understand. You know a Sprites' top left corner X and Y coordinate. You know its' Width and Height and you know if it intersects a point so if necessary you can calculate where every other part of the Sprite is located so what can't you do?

Version 1.29 has the following additions.

Sprite now has a Counter property that if non-zero is decremented every Tick. GameWindow has a CollisionCount event that occurs when a Sprite Counter reaches zero. The other events all have "collision" in their names so I thought why make this one different even though it's not really a collision!

GameWindow has a SpriteIntersectsPoint(x, y) method that returns the index of the first Sprite found that intersects the given point.

Just in case it is needed GameWindow has a RepaintImmediately property that governs whether GameWindow forces a repaint immediately after a Tick (the default) or defers the repaint to the next opportunity. This is only provided for contingency in case of any problems and hopefully should not be needed.
 

enonod

Well-Known Member
Licensed User
Longtime User
Thank you agraham, all these things are excellent and I look forward now to using them, they simplify coding.

I don't understand. You know a Sprites' top left corner X and Y coordinate. You know its' Width and Height and you know if it intersects a point so if necessary you can calculate where every other part of the Sprite is located so what can't you do?
I think (I should know) I was trying to say...
Say, two square sprites are side by side (but maybe even offset vertically).
To test this I don't want to have to collide first. The only way to detect a sprite is by its TLC (thanks to this new test) or by collision.

If one wants to move the right hand sprite to the left if clear, then the only way to test for any sprite that blocks the path even by one pixel, would be to calculate using one pixel to the left of the main sprite as being the right side of a possible blocking sprite, then use the width to find the left edge of such a sprite and then scan vertically (the height of the main sprite in an unknown amount of offset) to find whether any of those pixels tested is the TLC of a sprite. If it is then it blocks... it might be useful to instead, ask, is there a sprite overlapping the space adjacent to the main sprite. Or simpler is any pixel to the left of the main sprite (by height) used. We don't as far as I can see have access to pixels.
This was a comment that might trigger some easier way, or a suggestion of how using what exists. I could be (and probably am) talking rubbish. If it is simply ignore this.
 
Last edited:

enonod

Well-Known Member
Licensed User
Longtime User
Having read your new help file (SpriteIntersectsPoint) I see that any point of a sprite on the specified pixel, triggers. This good!
It means that the number of checks for an overlap of two sprites as I described is limited to the height of the sprite, no TLC required.
Can you please suggest a way in code for me to use this to check a range of adjacent such intersect points to achieve the aim mentioned above?
Do I need to keep changing the property for each pixel checked?
 

agraham

Expert
Licensed User
Longtime User
Version 1.291 has the following improvements.

Sprite.NextX and Sprite.NextY return the x and y coordinates a Sprite will have after the next Tick

GameWindow.CheckForSpriteCollision(index, x, y, allActiveSprites, nextMove) checks if a Sprite will collide with another Sprite if it is moved to a given x and y. The check can be done against the other Sprites current positions or those after the next Tick. Presently only the first collision will be reported. However I could return all possible collisions as an array if this would be better.

Similarly GameWindow.SpriteIntersectsPoint presently only reports the first Sprite that intersects, again I could return an array.

If I returned an array it would always contain at least one item that would be -1 for no collisions/intersections. I would probaby always return an extra item of -1 in the case of a collision/intersection so the number of collisions/intersections woulld always be ArrayLen(return()) - 1. What do you think?
 

enonod

Well-Known Member
Licensed User
Longtime User
Wow! Hitting the nail on the head comes to mind. Icing on the cake is another.
Personally I think to be realistically useful the return of the array in both cases would be preferable, nay; fantastic!!!
Everything you say makes sense. Go, Go, Go. On with 1.292

Oh, and thanks again.

[Edit] I must add that the options on CheckForSpriteCollision have been well thought out and cover all possible requirements that I can see.
 
Last edited:

enonod

Well-Known Member
Licensed User
Longtime User
I am testing some of these new items out and am having difficulty with obtaining the Index of THE sprite returned inside gw.CollisionMouse in order to then use it with gw.CheckForSpriteCollision, still inside gw.CollisionMouse.
I tried
Spr.Value=gw.Sprite1
ind=gw.SpriteIndex(Sprite1) and of course failed then
ind=gw.SpriteIndex(Spr)
Any advice please?
 

enonod

Well-Known Member
Licensed User
Longtime User
Thank you, it is clear where I went wrong.
 

enonod

Well-Known Member
Licensed User
Longtime User
Unless I have mis-read the Help on CheckForSpriteCollision Something is odd.
I have a sprite next to empty space and use the above method to check 2 pixels to the left of it. If I use AllActiveSprites as False it works and reports no collision, however, if I reverse to True it fails, saying there will be a collision.
My expectation would be that the latter MUST work if the former works???
B4X:
Sub gw_CollisionMouse
   Right=False
   Left=False
   Spr.Value=gw.Sprite1
   ind=gw.SpriteIndex(gw.Sprite1)
   Msgbox(ind)
'Check to the left for blockage
   If gw.X<(Spr.X+7) AND gw.CheckForSpriteCollision(ind,Spr.X-2,Spr.Y,True,False)=-1 Then
      Left=True
      Right=False
   Else If gw.X>(Spr.X+7) AND gw.SpriteIntersectsPoint(Spr.X+Spr.width+2,Spr.Y)=-1 Then
      Right=True
      Left=False
   End If
   If right Then
      Msgbox("right")
   Else If left Then
      Msgbox("left")
   Else
      Msgbox("blocked")
   End If
End Sub
 

agraham

Expert
Licensed User
Longtime User
Sorry, a misplaced bracket in a logical expression caused a bug.

Version 1.292 has these changes.

GameWindow.CheckForSpriteCollision and SpriteIntersectsPoint now return an array, see the help.

GameWindow.SpriteIntersectsPoint now has a nextMove parameter, see the help.
 

enonod

Well-Known Member
Licensed User
Longtime User
Many thanks for that agraham.
 

marathon332

Member
Licensed User
Longtime User
Any way to control sprite rotation in code?

Something like:

Sprite.rotation = 47 (rotate sprite 47 degrees)

Thanks for all your hard work Andrew...

--Steve
 

agraham

Expert
Licensed User
Longtime User
Any way to control sprite rotation in code?
If you mean rotate the bitmap when it is drawn then no. A Sprite itself is always rectangular although it doesn't necessarily appear so if the Sprites' bitmap has transparent parts. The way to simulate rotation would be to use an appropriate bitmap.
 

enonod

Well-Known Member
Licensed User
Longtime User
I have been testing the new features and am very pleased with them. You will be pleased to know that I can think of no others (at present, maybe never) and thank you very much for listening and implementing. I feel this library is now extremely useful.
 

eww245

Member
Licensed User
I just noticed that there is a thread running a high priority that effects movement of Sprites.
That is fine as it does not seem to effect performance of an app.

If it is set to Critical the sprite kind of glides along the screen and if set to Idle it is much more accurate and faster as far as where it should move to.

This is not being set with code but with a task manager and while creating a MouseMove event on the gamewindow with the door library.
I haven't tested it anyother way.

Can a method be created to set it's priority?
Say from 1 to 7 to allow the upper an lower priorities.
 

agraham

Expert
Licensed User
Longtime User
I just noticed that there is a thread running a high priority that effects movement of Sprites.
Is this on device or desktop and is it an optimised compiled application or in the IDE? Out of interest (because I might like to play with it!) which Task Manager are you using to alter the priority?

Basic4ppc applications are single threaded and the Sprite library runs on that single thread so whatever the thread is it has nothing to do with the application unless you are running in the desktop IDE where, although I don't know the architecture, there are several threads running under the IDE.

I believe the device IDE is single threaded and an application running under the IDE runs on that thread which is one of the reasons there is no debugging capability in the device IDE.
 
Top