Sprite attributes (properties)

eww245

Member
Licensed User
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.


This is on the device in the IDE.
It's something i've just noticed so i'm not sure what situations it will effect a sprite.

Using FdcSoft TaskManager I can see 3 threads running at normal priority when starting the IDE.
After loading the project and running the code it is still 3 at normal.

At some point one thread goes to a high priority, don't know why it changes but it does effect the speed of sprites.

Running an optimized compiled app not using sprites I can also see 3 threads.
So this does appear to be a b4p thread not specific to the Sprite library.

I'll have to complie and see if it still does the same.
 

eww245

Member
Licensed User
I just put this together and works about the same as I explained.

The difference is setting to an idle priority does not make it faster.
Maybe because I have been moving the Sprite left and right not up or down.

The critical priority is where it is most noticeable.
If the sprite is moved quickly in circles it will still move after taking the stylus off.

[Edit]
This is using Door and Sprite Libraries

B4X:
Sub Globals
     gw.New1("Form1", 0, 0, Form1.Width, Form1.Height)
     obj.New1(false)
     obj.FromLibrary ("main.gw", "gw", b4pobject(2))
     eMove.New1(obj.Value, "MouseMove")
     eUp.New1(obj.Value, "MouseUp")
   down = false
End Sub

Sub App_Start
     sp.New3 (imagelist1.Item(0), 1, imagelist1.Width(0), imagelist1.Height(0), 1)
     gw.SetTransparentColor1 (imagelist1.Pixel(0, 1, 1))
     gw.SpriteAdd(sp.Value)

sp.X = Form1.Width/2 - sp.Width/2
sp.Y = Form1.Height/2 - sp.Height/2

     gw.Tick
 Form1.Show
End Sub

Sub gw_CollisionMouse
  down = true
End Sub

Sub eMove_NewEvent
  If down then
   obj.Value = eMove.Data
x = obj.GetProperty("X")
y = obj.GetProperty("Y")
   sp.X = x
   sp.Y = y
gw.Tick
  End If
End Sub

Sub eUp_NewEvent
If down then
   sp.X = 0
'Form1.Width/2 - sp.Width/2
   sp.Y = Form1.Height/2 - sp.Height/2
   gw.Tick
   down = false
End If
End Sub
 
Last edited:

agraham

Expert
Licensed User
Longtime User
So this does appear to be a b4p thread not specific to the Sprite library
An optimised compiled application and (I believe) the device IDE start no additional threads themselves but run on a single thread created by the Common Language Runtime. Those extra threads you see are most probably .NET CLR owned threads started to support the execution of managed code, such as Garbage Collection, and you should probably leave them alone. Just because a thread exists it doesn't mean that it is taking processor time whatever its priority.

You are using Tick in a way that is not really intended. Tick does a lot of work and trying to use it in real time following the movement of the stylus will probably 100% load the CPU. The Sprite carrying on moving after lifting the stylus is probably the system processing queued MouseMove events that it couldn't keep up with. Bear in mond that devices are very feeble compared to desktops and it is easy to run out of CPU time as soon as you start anything intensive.
 

eww245

Member
Licensed User
An optimised compiled application and (I believe) the device IDE start no additional threads themselves but run on a single thread created by the Common Language Runtime. Those extra threads you see are most probably .NET CLR owned threads started to support the execution of managed code, such as Garbage Collection, and you should probably leave them alone. Just because a thread exists it doesn't mean that it is taking processor time whatever its priority.

You are using Tick in a way that is not really intended. Tick does a lot of work and trying to use it in real time following the movement of the stylus will probably 100% load the CPU. The Sprite carrying on moving after lifting the stylus is probably the system processing queued MouseMove events that it couldn't keep up with. Bear in mond that devices are very feeble compared to desktops and it is easy to run out of CPU time as soon as you start anything intensive.

Changing the threads priority is not something that could be eaisly done, if at all, in b4p code.
So it's not something I will be doing.

Is there another way, that you can think of, to not have the Tick in the MouseMove event?
 

agraham

Expert
Licensed User
Longtime User
Is there another way, that you can think of, to not have the Tick in the MouseMove event?
As I don't know what you are trying to do I can't suggest anything. The Sprite library, and Tick as its name suggests, were really designed for moving a lot of objects around an area on a regularly timed basis.
 

Byak@

Active Member
Licensed User
can anyone give a example with scrollable background?
 

Byak@

Active Member
Licensed User
UP.anybody know?
 

merli

Member
Licensed User
gw.SpriteInsertAt(Sprite.Value, Index As Int32) requirement

Hello

Recently I tried to create Isometric game engine using ImagelibEx and Drawpolygon to create Isometric objects, boxes etc, but moving objects using this library is terribly slow on device, even on Desktop it is not so fast as I expected. So now I am trying to recreate drawing procedures using sprite library which (I think) will be more faster. I need to add Isometric objects somewhere in space so I need to reorder visibility (z order) of objects (sprites). I miss from this library something like gw.SpriteInsertAt(Sprite, Index) method for easier insert sprite at desired location. Is it possible to add such functionality into library? Now with this library I would do same functionality like this (not tested) but seems to me no optimal way how to do it.

Sub SpriteInsertAt(Sprite,Index)
gw.SpriteAdd(Sprite.Value)
For i=SpritesCount-1 To Index+1 Step -1
gw.SpriteReplace(gw.GetSprite(i-1),i)
Next
gw.SpriteReplace(Sprite,Index)
End Sub

Is there any better possibility to insert sprite at specfic location into gw?

thnx
 

agraham

Expert
Licensed User
Longtime User
Is there any better possibility to insert sprite at specfic location into gw?
From the rest of your question I assume that by "location" you mean at a specific index. You cannot insert a new sprite but you can replace an existing one. You should be able to shuffle the sprites around to get the z-order you want. I haven't tried this and you may get some visible anomalies if the sprites change size. In this case make them invisible, call Tick, shuffle them and make them visible then call Tick again.

SpareSprite.Value = Gw.GetSprite(Iindex) ' save existing sprite
Gw.SpriteReplace(NewSprite.Value, Index) ' replace with another

Alternatively, as you have to create the bitmaps for each sprite why not just draw them yourself where you want them so you have complete control.
 

merli

Member
Licensed User
That is exacty what I thought. Except I did not know that I will need to put them invisible then tick and visible and tick. I need to have correct order of Sprites in sceene, because they can overlap (one is in front of other) and sometimes I need add another sprite _inside_ scene (think about some shooting or incoming another character of object for example) and that sprite I cannot just Add because it would be by visibility on top of all objects. I need to put it exactly on sceene where it needs to be by sprite index (and of course order of this object can change while it moves through 3D sceene. It can be in front of some objects and behind other). Anyway thnx for answer and I hope it will work ...
 

agraham

Expert
Licensed User
Longtime User
Except I did not know that I will need to put them invisible then tick and visible and tick
I didn't say that you would need to do this, only that you might need to as I haven't tried using Sprites that way. Try it without first as that would be more efficient
 

merli

Member
Licensed User
Thanks for help. It is working OK without invisible/visible trick, but there is one problem. If I delete sprite with sprite.MarkForDelete and gw.DeleteMarkedSprites and then I add same sprite again through gw.AddSprite or gw.ReplaceSprite then I have to set this sprite.IsActive=True to be seen on screen. Is it feature (planned to work this way) or bug?

I wonder how fast it will be when I will need to reorder (delete insert) this way 20 or more sprites each tick. We'll see :)
 

merli

Member
Licensed User
I am sorry, but that is the only way I found how to make redrawing objects fast.
now
1) I draw 3d objects using drawer to create sprite graphics.
2) then I sort objects by visibility
3) I put objects in right order into GW.

When I tried to do it directly into form I ended with slideshow presentation.
Now it works.

Is there any way how to cast shadows? I mean one sprite is casting shadow 10 pixels to the right and bellow objects are visible through that shadow. I mean some kind of transparency. What I am try to do is something like this:
Fenstalker Studios It is in flash, but I really don't understand how that guy is making shadow. :)
 

merli

Member
Licensed User
I am using now Sprite library because I need to move objects on form (it should be a kind of game) and there are problems with moving objects on form. For moving object I need
1) delete object
2) restore somehow all what was covered by deleted object (it could be background or another objects or just their parts)
3) move object in selected direction
4) recount visibility - order of ojects can change
5) draw object moved

When I wrote som kind of algorithm for above it had bugs and was slow like hell and I had big problems with point 2) that is exactly what sprite library is doing for me ... Libray remembers what is covered by Sprite when moving. Just order of sprites has to be OK. If I swith collison off (because i need to calculate collision by myself in 3D) and most objects won't move maybe I will manage to be fast.
 

agraham

Expert
Licensed User
Longtime User
You don't need to do 1) and 2). Keep a copy of the background in one bitmap and every frame use DrawImage to draw it onto another bitmap and draw the objects on the second bitmap in the order that you want then when you have finished use DrawImage again to copy that bitmap to the one being displayed in an Image Control.
 

merli

Member
Licensed User
You are right, but in this case I have to draw all objects each game tick, which I wanted to avoid and redraw just what is needed :). But anyway I know that now using sprites I do the same thing. When sprites won't work for me I will change drawing routines again
 
Top