Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / Best practice for dealing with 100's of sprites on screen?

Author
Message
Kevin Cross
20
Years of Service
User Offline
Joined: 15th Nov 2003
Location: London, UK
Posted: 16th May 2018 12:01 Edited at: 16th May 2018 12:11
My app is starting to get a little slower in AppGameKit each update. It's an app not a game but uses 100's of sprites on the screen to build the interface.

Before the main do loop all of the sprites are created and repositioned off screen i.e. -1000,-1000, and in the main do loop (depending on the app screen that's in view) some of those sprites are positioned back in to view.

I thought that because they are being positioned in the main loop each cycle that this was the reason for the slow frame rate so tried a separate test program positioning 10,000 sprites before the main do loop in the positions needed i.e. 10,10 and not -1000,-1000 and leave the main do loop empty but the frame rate hasn't really improved. I realize now that I can reduce a lot of my code by not adding them in the main game loop but doing so doesn't look like it's going to make any improvement to the speed. On some screens I'm getting a frame rate of about 10 frames per second instead of 60.

So my question is, what's the best practice for dealing with projects that has a lot of sprites on screen at once? Most of the sprites won't need to change while they're on the screen. They will only need to change once the user leaves and re-enters each screen. There will only be a few sprites and texts that will need to change each cycle (i.e. counters/timers). Is there a way to draw the sprites once and not re-draw them each cycle? I don't fully understand the different Render functions i.e. Render() and Render2DBack() but can't seem to get them to improve anything. In my main app I have a Sync() at the end of the loop and an UpdateAllTweens().

This simple program gives me a frame rate of about 20 fps on my mobile



This runs at about 25 fps.



Why does it require so much processing power when nothing is really happening in the main do loop in the second example?

I created this test project on the AppGameKit mobile as I can't get the desktop version installed at work at the moment.
Kevin Cross
20
Years of Service
User Offline
Joined: 15th Nov 2003
Location: London, UK
Posted: 16th May 2018 12:17 Edited at: 16th May 2018 12:20
Changing the viewoffset so that the sprites aren't on the screen makes the program run at a full 60 fps



I wanted to see if it's actually because there's so many sprites created and in memory but this example proves that's not the case
BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 16th May 2018 12:27
Some thoughts...

SetSpriteActive(0). This will remove it from the lists to check for animation and physics. I don't know if this matters when physics and animations are off, but try it anyway.

SetSpriteTransparency(0) for any sprites that have no transparency.

Do you have any fullscreen sprites that can be cropped to only the image?

Are there any sprites that you can combine and getImage() to reduce the number of sprites?

Can you split your moving and non-moving sprites into 2 lists, so that you never process and move a sprite when it's position is the same as the last frame?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Quidquid latine dictum sit, altum sonatur
TutCity is being rebuilt
Kevin Cross
20
Years of Service
User Offline
Joined: 15th Nov 2003
Location: London, UK
Posted: 16th May 2018 12:48 Edited at: 16th May 2018 12:52
Thanks for the suggestions, SetSpriteActive and SetSpriteTransparency only seemed to improve the speed by about 2 fps. It's still an improvement though so I'll look at adding it to my main app, assuming things like GetSpriteHit still work when active is set as 0.

I can probably combine a few sprites with GetImage but most sprites are a button in one way or another so that might not be that easy, or might not be many that can be combined.

They can stay in the same position on the screen each cycle and a large percentage of them won't need updating/changing at all, not until the user enters the particular screen in the app. I use SetViewOffset to move around screens, so screen 1 is x = 100 to x = 200 and screen 2 is x = 100 to 200 (I use percentage positioning and sizing).

And that's what I was planning to do, at the beginning of the cycle I would position everything once if the view offset changed and then each cycle only update half a dozen sprites like timers and animations when a user interacts with a sprite. That's what I was hoping would solve my problem but my tests above show that it's not going to help much.
Kevin Cross
20
Years of Service
User Offline
Joined: 15th Nov 2003
Location: London, UK
Posted: 16th May 2018 13:14 Edited at: 16th May 2018 13:16
@BatVink. I might look more into your GetImage() suggestion when I'm able to use my laptop. It's a pain writing code on the phone. I could add the layered sprites to one image and then that image to one sprite which can act as a button. I'd need to play around with it in a seperate program. That would definitely create less sprites on screen. Thanks.

If anyone has had to deal with a large amount of sprites on screen and found a way for it to not affect the fps by much then please let me know.
BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 16th May 2018 14:42
I use GetImage() a lot, but only before the main app starts.

A couple of tips (if you haven't used it before).
GetImage only works when the sprites are in the renderable screen area (i.e doesn't work offscreen)
Use ClearScreen() followed by DrawSprite() (for each sprite) followed by GetImage().
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Quidquid latine dictum sit, altum sonatur
TutCity is being rebuilt
IronManhood
9
Years of Service
User Offline
Joined: 6th Feb 2015
Location: US
Posted: 17th May 2018 16:32 Edited at: 17th May 2018 16:47
That would be my main suggestion. Draw all the UI elements that don't change onto a single image and create a single sprite from that.

Another thought would be to divide up the sprites into a few groups and only draw one group per frame. So like:
frame 1 - draw group 1
frame 2 - draw group 2
frame 3 - draw group 3
clear screen
frame 4 - draw group 1
frame 5 - draw group 2
frame 6 - draw group 3

I don't know how well this will work out. May feel unsnappy or something. Also, this may not work at all.
Kevin Cross
20
Years of Service
User Offline
Joined: 15th Nov 2003
Location: London, UK
Posted: 17th May 2018 20:36
Thanks. I'm going to test this all out in a separate project soon and see what works best.
george++
AGK Tool Maker
16
Years of Service
User Offline
Joined: 13th May 2007
Location: Thessaloniki, Hellas
Posted: 17th May 2018 21:32
I don't understand why you place some sprites outside the screen. You'd better hide them.
Kevin Cross
20
Years of Service
User Offline
Joined: 15th Nov 2003
Location: London, UK
Posted: 17th May 2018 21:40
Quote: "I don't understand why you place some sprites outside the screen. You'd better hide them."


Not sure what you mean. I have to move them off screen so that they don't react to GetSpriteHit() as most of the sprites act like a button. Hiding them by setting them to alpha = 0 would mean adding code to all of the GetSpriteHit lines to only react if alpha isn't 0. I assume you mean change the alpha when you say hide them. I'm sure SetSpriteVisible just changes the alpha value.
fubarpk
Retired Moderator
19
Years of Service
User Offline
Joined: 11th Jan 2005
Playing: AGK is my friend
Posted: 17th May 2018 22:41
add to your collision routine

if ............ and if getSpriteVisible(spr)
fubar
ruckertheron
7
Years of Service
User Offline
Joined: 12th Nov 2016
Location:
Posted: 17th May 2018 23:13 Edited at: 17th May 2018 23:29
I tried your code and I just adjusted SetSyncRate( 30, 0) to SetSyncRate(0 ,0) and it went to 240FPS...
Kevin Cross
20
Years of Service
User Offline
Joined: 15th Nov 2003
Location: London, UK
Posted: 18th May 2018 00:23
@ruckerthon unfortunately that doesn't make a difference on the device/phone.
Kevin Cross
20
Years of Service
User Offline
Joined: 15th Nov 2003
Location: London, UK
Posted: 20th May 2018 20:11
I tried something on the weekend to my app (not a separate project) which made the fps go from 20 to 45 and that was something like this:

... (Create all of the sprites)
do
if (drawnOnce = 0)
... (Position all of the sprites)
drawnOnce = 1
endif
loop

This seems like the simplest option to implement to improve the speed. I'll draw/position the sprites that don't need to change the once and the ones that do change every cycle I leave as normal.

Another thing I've been looking at is Tier 2. I've spent most of the weekend trying to get Android, iOS, and Mac OSX templates set up for future projects and to use for converting my current app. Tier 2 should hopefully introduce speed improvements, and re-writing is something I've been wanting to do.

I can't seem to get the iOS template to work in the Simulator. It loads but only shows the white AppGameKit splash screen. It does nothing else. It works on the device though so that's good enough. I spent quite a few hours today updating the OS and XCode to work with my 11.3 iOS device but I'm good to go now. Now I just need to learn a bit of C++
Van B
Moderator
21
Years of Service
User Offline
Joined: 8th Oct 2002
Location: Sunnyvale
Posted: 21st May 2018 08:33
I'd consider making the interface from a single text object. So each part would be a character, and the bitmap font would be a single image, split up with a subimages file. You'd have to make the text object then position each character with code.

You would be able to resize certain elements, rotate them colour etc. The main benefit is that AppGameKit would be able to draw the text object in a single pass, making it faster for rendering this stuff, because all the elements can be drawn at once from the same source. I think its certainly worth a try, if it can reduce that sprite overhead.
The code is dark and full of errors

Login to post a reply

Server time is: 2024-04-19 14:56:41
Your offset time is: 2024-04-19 14:56:41