Sprite attributes (properties)

enonod

Well-Known Member
Licensed User
Longtime User
It would be very helpful IMHO if sprite collision (ability) could be turned on/off and still have the sprite visible and doing things. It would seem to me that it could save a lot of interrupts uneccessarily and could save a lot of testing code.

If this can be done already in some way I would be grateful to hear of it.
 

agraham

Expert
Licensed User
Longtime User
Erel has given me the go-ahead to produce a new version of the Sprite library which will be the next official release. Try the attached Sprite library version 1.21.

The changes over the current Sprite library are :-

Added a Sprite.ID property that lets you name or number a Sprite and so identify a particular Sprite returned as Sprite1 or Sprite2 in a collision.

Added a GameWindow.GetSpriteID(id) method that returns a reference to a Sprite with the specified ID. This can be assigned to a Sprite Value property to manipulate the Sprite.

Added a GameWindow.CheckSpriteCollisions boolean property. True (the default) checks for Sprite collisions, set to to False to stop Collisions occurring

Modified the Sprite.IntersectsPoint hit test to work properly (I hope!).

Post here any further changes you can think of.
 

Attachments

  • Sprite1.21.zip
    7.3 KB · Views: 371

enonod

Well-Known Member
Licensed User
Longtime User
Wow, thank you very much. I have not downloaded yet but had to reply with gratitude.
 

enonod

Well-Known Member
Licensed User
Longtime User
Thank you agraham and of course Erel for permission. I can confirm that the Intersection problem is now solved and it works correctly, pixel perfect!!
 

enonod

Well-Known Member
Licensed User
Longtime User
Not wishing to appear greedy, but will you please now explain how to get over the double event triggered by a collision when neither sprite is going to be deleted.
It appears (from an earlier post I made) that the system will not simply ignore it by counting two and then dealing with it. This would of course be what is commonly called the icing on the cake.
 
Last edited:

enonod

Well-Known Member
Licensed User
Longtime User
Sorry about the multi posts but I assume editing might not get noticed.
I have checked the new anti-collision and I believe there was a misunderstanding or reading.
...and still have the sprite visible and doing things
My original intention was that individual sprites could be prevented from being collideable via a Boolean property. It might be that say 10 sprites should never or perhaps only under certain conditions be permitted to collide.
To turn the collision mechanism off altogether is undoubtedly useful, but please could the original request (possibly badly explained) be considered?
It could be done now using your new ID and filtering it in the collision sub, I presume, but it doesn't prevent the collision sub being called and slowing the system down. Of course I don't know how this could possibly be done, but sprites do already have some properties and this could presumably be just one more???
[Edit]Sorry to be a bore but I tried this and I get the error Object must first be created.... The idea of all this is to do something to a specific sprite if it collides but not if it is some other sprite.

gw.s has been created as a sprite and works
s has been created as a sprite and works
s.ID="Fred" seems OK
spr1 has also been in use ok

Sub gw_collision
Spr1.value=gw.Sprite1

If spr1.ID<>"Fred" Then
spr1.Velocity=6
...
 
Last edited:

enonod

Well-Known Member
Licensed User
Longtime User
I am going to rewrite collisions later today or tomorrow so I'll look at it then.
Thank you very much for that.

Sorry for not being clear... it refers to the first line in the collision sub
Spr1.value=gw.Sprite1
Spr1 has been in the objects list all along and not presented a problem.

[Edit] Profound apology... a typo, leaving in a comment marker. Works fine
 
Last edited:

enonod

Well-Known Member
Licensed User
Longtime User
Having got over the self inflicted error, I find that the following produces '0' on both labels.
The if is handled as true for either gw.sprite1 or 2 and the two id's are "cw" and "fred".
I cannot see that anything is wrong with the code, so I will leave it with you while you do your rewrite.
Sub gw_collision
label3.Text=gw.Sprite1.id
label4.Text=gw.Sprite2.id
Spr1.value=Gw.sprite2
If spr1.id <> "Fred" Then
spr1.Velocity=20
End If
End Sub
Thanks.
 

agraham

Expert
Licensed User
Longtime User
I'm afraid your code is wrong. Basic4ppc can't handle compound references to properties and methods like "gw.Sprite1.ID". The IDE doesn't error this but returns 0 or an empty string. The optimising compiler will however error it, though not with a helpful message. You need to use this code.
B4X:
Sub gw_collision
  Spr1.value=Gw.Sprite1
  Spr2.value=Gw.Sprite2
  label3.Text=Spr1.ID
  label4.Text=Spr2.ID
   ...
 

enonod

Well-Known Member
Licensed User
Longtime User
The first suspect should always be the author and I failed to keep suspicion on me. I don't think I really thought this would be different from Delphi.
So one must always have an interim (or effectively a temp) to overcome this.

I appreciate your help and thanks for the snippet.

[Edit]Interestingly the information on the two labels switches around for the second of the two interupts.
 
Last edited:

agraham

Expert
Licensed User
Longtime User
So one must always have an interim (or effectively a temp) to overcome this.
Sort of! Because there is no typing in Basic4ppc everything internally is a string.

Basic4ppc can cope with assignments of types between library objects

Spr1.Value = gw.Sprite1 ' assign a Sprite reference type

but internally variables and values are untyped so you can't cascade properties and methods as internally there is no reconition of types.
 

enonod

Well-Known Member
Licensed User
Longtime User
Thank you agraham, useful to know.
 

agraham

Expert
Licensed User
Longtime User
This version 1.22 of the Sprite library has the additional changes listed below.

Each Sprite has a boolean IsCollider property that defaults to True which determines whether a Sprite can collide with another Sprite or not. All Sprites will always collide with the boundary, I'll probably put an option for this in the next release.

GameWindow now draws itself properly as a Windows Control in response to Paint events. Previously it didn't which could lead to flashing and even not appearing under certain circumstances.

Each collision now hopefully only raises the collision event once. This change also increases performance as previously each collision possibility was checked twice, once for each Sprite. As each possibility is now only checked once this approximately halves the time taken for the collision checking.

Various invisible bits of internal tidying up that should not be visible.
 

Attachments

  • Sprite1.22.zip
    7.2 KB · Views: 358

RichardW

Member
Licensed User
Longtime User
AGraham as you are updating the sprite library and putting in the option to turn off collisions another feature would be to add a z-order to sprites so smaller or higher priority ones could be positioned over less important or static sprites.
 

enonod

Well-Known Member
Licensed User
Longtime User
Thank you so much for your time and effort agraham, it is very much appreciated.
 

agraham

Expert
Licensed User
Longtime User
This is probably the last iteration as I can't think of anything else to add - can you?

Version 1.23 has the following changes.

Each Sprite has an IsVisible property, default True. This is complementary to the IsActive property. An inactive Sprite is not drawn, does not move and does not take part in collisions. An active invisible Sprite acts normally except that it is not drawn.

Each Sprite has an IsContained property. If True the Sprite will collide with the game window boundary, if false it won't.

GameWindow now has SpriteOnScreen(index) and SpriteOnScreenID(id) methods that return True if the specified Sprite is positioned in the game window or False if it is not. This refers to the Sprites' position, not its' visibility.

GameWindow now has a SpriteReplace(Sprite, index) method.

More internal tidying up that should not be visible.

add a z-order to sprites
To efficiently provide an explicit z-order for individual sprites is difficult as the code needs to have high performance as it is run many times per second. However there is already an implicit z-order as sprites added later are always drawn after earlier sprites. To keep a Sprites' place in the drawing order you could use the new SpriteReplace method.
 

Attachments

  • Sprite1.23.zip
    7.4 KB · Views: 359
Last edited:

enonod

Well-Known Member
Licensed User
Longtime User
I think this is great, and I can't think of anything else that could enhance the use of sprites, (oh, except the obvious help update eventually).
Thank you again very much for making the system so much more useful.

The above statement is not binding for all time.:)
 

RichardW

Member
Licensed User
Longtime User
unhandled exception

I have uploaded a program which will trigger an exception when running the compiled (optimized) code. To cause the error simply mouse click on the egyptian delta province. This just cycles thru a series of coloured images but as compiled it will "Continue" only after displaying an annoying error message.

I have another interesting issue. I position a province sprite on the map and then drop on a city sprite on top of it. If I click the city I get 2 mouse collision events; first the underlying province and then for the city itself. This seems strange as I would expect the city first, then the province. I can get around this by using images but just curious over this behaviour.

The flashing is truly gone. I was going mad trying to figure what in my map scrolling was causing that. Thanks for fixing it.
 

enonod

Well-Known Member
Licensed User
Longtime User
There seems to be a download problem, the file has some ID on the front and registers as corrupt.
4171d1246351689-sprite-attributes-properties-sprite1.23.zip
 
Top