B4A Library Game Sprite Library

Hi all,
This is my first attempt at creating a library so I hope it works.
It is a heavily modified version of the code Erel kindly posted for his GameView library.

03/02/2014 - v0.1
First Release
04/02/2014 - v0.2
Added FPS code to the GameSpriteView
12/02/2014 - v0.3
Removed the list-based system replacing it with a sub _Draw() call instead. Also added a convenient DrawText() command. Useful for displaying basic text messages (FPS monitoring).
16/04/2014 - v0.4
Changed: AnimDelayRate to AnimDelayTime. Now using milliseconds for timing.
Added: Filter to the Sprite class
Added: DeltaTime to the GameSpriteView class


GameSprite Library v0.4
Gsv_Screenshot_zps1470806a.png
pi_screenshot2_zps8e3b2124.png
jellybean_screenshot_zps8ff4e89b.png



GameSprite a very light-weight (10K) library designed with 2D games creation in mind. As the name suggests the library is geared towards sprite handling with a simple to understand command set.
The library features a powerful one-call animation command to set up automated animation.

Hardware acceleration is supported.

The key features are:
  • GameSpriteView - the main display supporting virtual screen sizing, global rotation, global anchor point , get FPS, get DeltaTime
  • Sprite - A bitmap-based object with positioning, anchor, size, flip, rotate, colour, alpha, animation, region support, basic collision (overlap) checking, and distance checking.

GameSpriteView methods and variables
IsHardwareAccelerated()
VirtualDisplaySize() , VirtualWidth() , VirtualHeight() , VirtualX() , VirtualY()
Anchor() , AnchorX , AnchorY
DrawText()
Rotate
FPS
Sprite methods and variables
Bitmap
Position() , X , Y , CenterX , CenterY
Size() , ScaleSize() , Width , Height
Anchor() , MidAnchor, AnchorX, AnchorY,
Rotate , FlipX, FlipY
AnimDefineCells() , AnimSequence() , AnimCellRange() , AnimCellNumber , AnimDelayTime , AnimNextCell , AnimPreviousCell , AnimPlay
Region() , ResetRegion , CopyRegion()
isOver() , Overlaps() , DistanceTo()
ARGB() , RGB() , Alpha, Filter
Visible , Copy() , Reset​


You can get the library here, which includes some basic examples you get you started.
Included in the zip is an updated Pocket Invaders, which is a fully playable game to show-case the library.

DOWNLOAD LINK

Also now available, a companion tool written in B4J called SpriteMotion for assisting in the process of defining sprites contained within a sprite sheet.
 
Last edited:

sorex

Expert
Licensed User
Longtime User
it's the same error as quoted above, the title of the emu shows (API 10) so I'm out of luck with that image.

there's an S2 image with API16 I'll give that a try.
 

sorex

Expert
Licensed User
Longtime User
works fine with that other image, too bad it doesn't work on my phone tho.
 

Jim Brown

Active Member
Licensed User
Longtime User
Added FPS code. See GameSpriteViews FPS. It returns the number of frames rendered per second, which is updated with every called to the gsv.Invalidate
 

Jim Brown

Active Member
Licensed User
Longtime User
I discovered a strange thing while evaluating the performance of the lib (rather good as far as I can see):
if I set 160 walkers in the attached example, I have a smooth animation. If I set 5 more, everything is horribly slow. The drop in FPS is huge. Any explanation?
Try this version. Instead of loading the same bitmap over and over again use MySprite.Copy(thisSprite) so that it shares the same bitmap.

I tried 800 sprites running in Legacy mode via the Genymotion emulator and things still held out well.

This code uses v0.2 of the library
B4X:
'Activity module
Sub Process_Globals
    Dim bird,birdAnimated,Walker(800) As Sprite
    Dim NUMBLOCKS As Int =  12
    Dim block,blocks(NUMBLOCKS) As Sprite
    Dim timer1 As Timer
End Sub

Sub Globals
    Dim gsv As GameSpriteView
    Dim lblFPS As Label
    Dim WalkerDir(Walker.Length) As Int
End Sub

Sub Activity_Create(FirstTime As Boolean)
    gsv.Initialize("gsv")
    Activity.AddView(gsv, 0, 0, 100%x, 100%y)
    Activity.Title="GameSpriteView - Animation"
    Activity.Color=Colors.Cyan
    ' set the virtual display wide enough to accomodate the set of blocks.
    gsv.VirtualDisplaySize(NUMBLOCKS*64,0)
    If FirstTime Then
        ' BIRD
        ' load the bird animation bitmap
        bird.Bitmap=LoadBitmap(File.DirAssets,"bird_5x5_22frames.png")
        bird.Position(50,30)
        ' copy the above bird settings into the animated bird sprite
        birdAnimated.Copy(bird)
        ' set the animation sequence to use frames 0 to 20 only
        ' also, triger the bird to auto-animate
        birdAnimated.AnimSequence(5,5,0,20,True,2,True)
        ' resize the animated bird to 2x bigger
        birdAnimated.Size(birdAnimated.Width*2,birdAnimated.Height*2)
        ' move the animated birds anchor point to the middle
        birdAnimated.MidAnchor
        ' set the animated birds postion on screen
        birdAnimated.Position(gsv.VirtualWidth*0.64,gsv.VirtualHeight*0.8)
        block.Bitmap=LoadBitmap(File.DirAssets,"block64x64.png")
        block.Y=gsv.VirtualHeight-64
        For i=0 To NUMBLOCKS-1
            blocks(i).Copy(block) : blocks(i).X=i*64
        Next
        ' WALKER
        WalkerDir(0) = 2
        Walker(0).Bitmap=LoadBitmap(File.DirAssets,"Walker_6.png")
        Walker(0).AnimSequence(6,1,0,5,True,8,True)
        Walker(0).Anchor(Walker(0).CenterX,Walker(0).Height)
        Walker(0).X=Rnd(0, 400)
        Walker(0).Y=block.Y
        For i = 1 To Walker.Length - 1
            WalkerDir(i) = 2
            Walker(i).Copy(Walker(0))
            Walker(i).AnimCellNumber=Rnd(0,100)
            Walker(i).X=Rnd(0, 400)
        Next
        ' Timer
        timer1.Initialize("Timer1", 10)
    End If
    ' add sprites to the game sprite view
    gsv.Sprites.Add(bird)
    gsv.Sprites.Add(birdAnimated)
    For i=0 To NUMBLOCKS-1
        gsv.Sprites.Add(blocks(i))
    Next
    For i = 0 To Walker.Length - 1
        gsv.Sprites.Add(Walker(i))
    Next
    If gsv.IsHardwareAccelerated = False Then
        Log("**Hardware acceleration not supported**")
    End If
    ' FPS label
    lblFPS.Initialize("")
    lblFPS.TextSize = 18
    lblFPS.TextColor = Colors.White
    Activity.AddView(lblFPS, 0, 100%y - 30dip, 50dip, 30dip)
End Sub


Sub Timer1_Tick
    ' update the walkers position
    For i = 0 To Walker.Length - 1
        If Walker(i).X<-60 OR Walker(i).X>gsv.VirtualWidth+60 Then
            WalkerDir(i)=-WalkerDir(i)
            Walker(i).FlipX=(WalkerDir(i)<0)
        End If
        Walker(i).X=Walker(i).X+WalkerDir(i)
    Next
    gsv.Invalidate
    lblFPS.Text = gsv.FPS
End Sub

Sub Activity_Resume
    timer1.Enabled = True
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    timer1.Enabled = False
End Sub

Sub gsv_Touch (Action As Int, X As Float, Y As Float)
    ' need to covert the touch physical X/Y to virtual coordinates
    birdAnimated.Position(gsv.VirtualX(X),gsv.VirtualY(Y))
End Sub
 
Last edited:

Jim Brown

Active Member
Licensed User
Longtime User
The latest update now removes the 'list-based' sprite control system and instead implements a Sub call into the B4A code. When covering Pocket Invaders I found the list-based system to be more cumbersome than having a more direct system. The new system now calls gsv_Draw where all drawing should occur. All examples have been updated to use this new system.
 
D

Deleted member 30048

Guest
Great library but I have a question, is it possible to add filters to sprites?

If I scale the size of the original sprite I can see the pixels and I don't want to use high resolution images to avoid too much ram.

Thank you!
 

Malky

Active Member
Licensed User
Longtime User
Am I missing something here?

What do the parameters need in the AnimSequence function?

There are 5 parameters in the example up top of the page, but the downloaded examples have 7?

I have a single strip of 15 cells and have tried various, options with no success, I just get a flashing part of the middle of each cell animating?

Each cell is 75 wide by 100 height.

Very frustrating.

Malky
 

Jim Brown

Active Member
Licensed User
Longtime User
New parameters are:

mySprite.AnimSequence(Columns,Rows,FirstCell,LastCell,ForwardDir,Delay,AutoPlay)

Based on your information try mySprite.AnimSequence(15,1,0,14,True,Delay,AutoPlay)
 

Malky

Active Member
Licensed User
Longtime User
Thank you very much Jim, working first time with your parameters.

Now just need a few touch buttons to flip direction, but I'll get there.

Cheers and thanks again for your very helpful response.

Malky
 

Malky

Active Member
Licensed User
Longtime User
Hi again Jim, am I missing something with the VirtualDisplaySize settings?

I have an image sprite in each bottom corner of the screen (left/right) to move a character. The touch coordinates seem to be way out compared to the position of the actual sprite touched?
B4X:
btnLeft.Position(gsv.VirtualWidth*0.01,gsv.VirtualHeight*.8)
        btnRight.Position(gsv.VirtualWidth*0.9,gsv.VirtualHeight*.8)

Malky
 

Jim Brown

Active Member
Licensed User
Longtime User
Hi Malky, are you converting your 'physical' touch coordinates back to 'virtual' ones?
See the VirtualX() and VirtualY() functions.
The collisions demo shows a working example of how these are used.
 

Malky

Active Member
Licensed User
Longtime User
Hi Jim, I have tried converting from every option available I think? Still no luck.

I'm not grasping the virtual conversion right or the tablet is not which I very much doubt? Never blame your tools as they say :)

I had it fine on the HTC, but moving up to the tablet, I had to calculate positions and now have the bitmaps in the correct positions for left and right change of direction and 'thought' I had the detection (only x value so far) calculated as well using the bitmap coordinates, but nothing? Left obviously works, but the distance for the right movement seems way out?

Just stumped at the moment. I know it shouldn't be rocket science and I have to rush with the time I have, but quite frustrating?

Malky
 

Jim Brown

Active Member
Licensed User
Longtime User
Hi Malky,

Does the demo work (where there are multiple Androids)? This example shows how isOver() can be used to determine if the sprite is over a particular 2D coordinate. You should be able to see how physical Touch coordinates are converted to virtual ones there.

What are you setting the virtual resolution to?
 

Malky

Active Member
Licensed User
Longtime User
Hi again Jim, I am at work at the moment.

I basically cannibalized the animations example withe animated bird etc. If I recall the resolution was 800,0?

I had it working last night, but.... I positioned the left and right controls using virtual positions instead of physical (which I think is wrong), but it displays them on both the phone and the tablet fine and they work.

Because I plan to have some jumps and obstacles etc plus a scene, I am worried that this approach will come and bite me back big time as I progress. Your advice would be greatly appreciated.

I had even contemplated the libgdx engine instead with more options, but it looks even more complicated?

Thanks again,

Malky
 

Malky

Active Member
Licensed User
Longtime User
Hi Jim, thanks very much again.

Just home and although I had it working last night (after much frustration) with the <> X/Y etc, the isover function works a treat after replacing the old position test!

Do you know if it is possible to load a screen or remotely similar with primed obstacles etc as I have seen done (in libgdx though I think)? I want something to 'walk' the sprite on as well. I have a good friend who is a graphics artist, I just need to know what is possible

I will try this with various virtual resolutions as the phone seems ok for play space, but the tablet seems to make the icons bigger and it appears there is less area to work with? Could be an illusion as I don't use the tablet a lot?

Again, many thanks for this.

Malky

EDIT - Jim, one more question if I may? Is there a way to stop the animation once it completes the animation sequence? I am thinking about forcing the player to keep holding the direction sprite pressed rather than a continuous walk?
 
Last edited:

Jim Brown

Active Member
Licensed User
Longtime User
> Do you know if it is possible to load a screen or remotely similar with primed obstacles etc
Yes, perhaps in a similar way that B4a has LoadLayout, although its beyond the scope of this library, which is meant to be 'small and simple'
After all, not only would you need a routine to load the layout, but ideally a level designer too.

> Is there a way to stop the animation once it completes the animation sequence?
The best way to do this is to check the current frame of the animation then turn off AutoPlay when the last frame is reached.
See the sprites AnimCellNumber and AnimPlay options.
 
Last edited:

Malky

Active Member
Licensed User
Longtime User
Ok, thank you very much, can I integrate these functions with LibGdx?

Seems to be too many options and I just need the isover function for now, but I can't see anything like that?

I know this is well out of scope for the topic, but thought I would begginly ask :)

Malky
 

Jim Brown

Active Member
Licensed User
Longtime User
Version 0.4 uploaded.
I have added simple Filter option for sprites so that you can choose to render as unfiltered (classic clean retro look) or filtered (smooth looking) sprites.

The animation delay rate has been changed to a delay time using milliseconds, thus allowing more control over the frame timing. For example, setting the delay time to 250 means the animation updates every 1/4 second.
Be aware that if you run this updated library with previous code (0.3 and lower) your animations will run very fast. Increase the delay time to slow the animation down.

Finally, I have added a DeltaTime to return the difference between now and the time that the last frame update occured.
 

salvadoro

Member
Licensed User
Longtime User
Hi Jim, in the files folder are missing some files for the JellyBeans sample, could you update this please.

Salvador.
 
Top