Python + Pygame = slow game?

Started by
17 comments, last by Kylotan 15 years, 5 months ago
Hi! We are making 2D side-scroller platform adventure action game with elements of RPG. Problem is that even in this starting stages game is really slow. Right now it have 25 fps and in full screen with hardware acceleration turned on it have 35 fps. We use convert while loading sprites, and we are not bliting objects that are not in current screen. Right now there is around 5 monsters that are on screen and around 20 tiles. Problem is that this should be fast paced side-scroller and in future there will be a lot of monsters,pyshics,special effects etc. We tryed dirty draw technique which helps, but we need camera to move quickly so it's no use... Is it even possible to make game like this with Pygame? What would you suggest ,should we use some other library then Pygame? How good is PyGlet? And how big changes we need to do in code to implement it? Thanks in advance! p.s. we are testing it on this configuration (laptop) : Pentium M 1.7GHz,2GB RAM and some integrated graphic card.
Advertisement
Are you using alpha blending?
Well, for starters your not exactly running on a very high end system. integrated graphics in particular is going to slow you down a lot, specially if you don't have a strong processor or running it at full power (integrated graphics actually runs the graphics through the processor, using local ram for storage). be especially leary of using large textures, which are stored in the ram in your case. I would say go ahead and start running tests with a bunch more enemys. profile various pieces of code and see where your bottlenecks are. Python is no where near as fast as say C++, .NET, or JAVA, but it should still be enough for most things.
Quote:Original post by rip-off
Are you using alpha blending?


We are using alpha blending while loading sprites. Did u mean on that? Can you explain how could that help and for what alpha blending can be used? thx
Quote:Original post by PaulCesar
(integrated graphics actually runs the graphics through the processor, using local ram for storage).
Although integrated cards do share RAM with the cpu, many of the recent models (the Intel GMA 4500, for instance) have their own processor(s) for hardware transform, lighting and even shaders.
Quote:Python is no where near as fast as say C++, .NET, or JAVA, but it should still be enough for most things.
Pygame implements almost all of the 'heavy' processing tasks (such as blitting surfaces) in C, so there shouldn't be a drastic difference between python and C programs using pygame - unless of course you are doing some other heavy processing task directly in python.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

It depends on what you mean by "hardware acceleration". AFAIK pygame is a nice wrapper over SDL. This means that it could be using SDL's 2D rendering system, or OpenGL.

If the latter, then using alpha blending is not a problem. If the former, you need to be very careful when you use alpha blending. Doing blending during loading should be fine - as long as the final surface hasn't an alpha channel.

However, if any of your live blits are alpha-blended, this will be performed in software. SDL does not support hardware alpha blending. This incurs an additional penalty: surfaces stored in video memory have to be fetched back into system memory for blending to work.

In any case, using OpenGL will probably be faster than using SDL's 2D rendering system. My understanding is that Pyglet uses OpenGL. Pygame may or may not be able to use OpenGL, I've never used it.
Quote:Original post by rip-off
In any case, using OpenGL will probably be faster than using SDL's 2D rendering system. My understanding is that Pyglet uses OpenGL. Pygame may or may not be able to use OpenGL, I've never used it.
Pygame is pretty much a straight wrapper of SDL, and as such, you can use OpenGL. IMHO, however, pyglet is a far superior way to access OpenGL from python.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

You really need to profile to determine the slowest parts of your code. Right now it's all guesswork what's causing the slowdown.

There is the free CodeAnalyst profiler for AMD chips, which will also work to some degree for Intel machines, give it a try.

Good Luck!

-ddn
Hi,

- check to see if your background images have no alpha channel. Blitting alpha channel images is slower.
- profile.
- learn from other side scrolling games.
- 30 fps is enough.
- consider using a lower bit depth for some images if your graphics suit it. eg, 16bit images can look fine for some things (like if there is less than 65536 colors)
- consider using a smaller screen resolution.

Try learning from other side scrolling games which get decent speed:
http://www.pygame.org/project/406/


I know from experience that you can make scrolling games fast enough with pygame.

Have you done any profiling?
http://www.pygame.org/wiki/Profiling?parent=CookBook

With profiling you can see the slow parts of your code and likely speed up those parts.


Note, that you can have a fun game running at 30fps. It's mostly about keeping a consistent frame rate -- rather than keeping a massive one.


If your game is open source, post a link to it to the pygame mailing list, and people will most likely help you speed it up. If not, ask anyway :)



cheers,
ok..thanks everyone for help till now..

here is profiling of our code...can someone tell me where are critic sectors (bottle necks)...and what sectors takes more time then they should (and on what time we should try to set it)...thanks in advance!!!!
p.s. sorry for big post but i dont know how to use spoilers in this forum (if even is possible)


          490578 function calls (490463 primitive calls) in 28.605 CPU seconds   Ordered by: standard name   ncalls  tottime  percall  cumtime  percall filename:lineno(function)      919    0.006    0.000    0.006    0.000 :0(append)    35606    2.693    0.000    2.693    0.000 :0(blit)     3305    0.014    0.000    0.014    0.000 :0(clock)        1    0.000    0.000    0.000    0.000 :0(close)     2473    0.015    0.000    0.015    0.000 :0(colliderect)      115    0.021    0.000    0.022    0.000 :0(eval)     5628    4.880    0.001    4.880    0.001 :0(fill)      820    5.531    0.007    5.531    0.007 :0(flip)      804    0.017    0.000    0.017    0.000 :0(get)      804    0.004    0.000    0.004    0.000 :0(get_focused)      804    0.004    0.000    0.004    0.000 :0(get_fps)     7287    0.035    0.000    0.035    0.000 :0(get_height)    34774    0.400    0.000    0.400    0.000 :0(get_pressed)     1647    0.009    0.000    0.009    0.000 :0(get_ticks)     7287    0.042    0.000    0.042    0.000 :0(get_width)        5    0.000    0.000    0.000    0.000 :0(index)        5    0.000    0.000    0.000    0.000 :0(play)      117    0.002    0.000    0.002    0.000 :0(pop)    16985    0.472    0.000    0.472    0.000 :0(pump)        3    0.000    0.000    0.000    0.000 :0(random)      804    0.011    0.000    0.011    0.000 :0(range)     8844    0.733    0.000    0.733    0.000 :0(remove)      804    0.081    0.000    0.081    0.000 :0(render)      855    0.074    0.000    0.074    0.000 :0(rotate)      115    0.001    0.000    0.001    0.000 :0(set_alpha)        1    0.020    0.020    0.020    0.020 :0(setprofile)       51    0.008    0.000    0.008    0.000 :0(smoothscale)    16985    0.578    0.000    0.578    0.000 :0(sum)      804    1.036    0.001    1.036    0.001 :0(tick)    116/1    0.000    0.000   28.585   28.585 <string>:1(<module>)      804    0.042    0.000    0.093    0.000 GFX_OSD.py:76(DrawHealthBar)      804    0.006    0.000    0.006    0.000 GFX_OSD.py:93(WeaponChangeRender)        1    0.000    0.000    0.000    0.000 GFX_Status.py:127(AddFX_Stars_Red)        1    0.000    0.000    0.000    0.000 GFX_Status.py:151(AddFX_CoinPickup)      804    0.008    0.000    0.008    0.000 GFX_Status.py:158(ReproduceFX_GenericBurst)      804    0.007    0.000    0.007    0.000 GFX_Status.py:181(ReproduceFX_GenericBurst2)      804    0.007    0.000    0.007    0.000 GFX_Status.py:204(ReproduceFX_GenericBurst_Red)      804    0.007    0.000    0.007    0.000 GFX_Status.py:227(ReproduceFX_GenericTrail)      804    0.007    0.000    0.007    0.000 GFX_Status.py:250(ReproduceFX_GenericTrail2)      804    0.008    0.000    0.008    0.000 GFX_Status.py:282(ReproduceFX_Shadow)      804    0.018    0.000    0.056    0.000 GFX_Status.py:305(ReproduceFX_Stars_Red)      804    0.008    0.000    0.008    0.000 GFX_Status.py:326(ReproduceFX_Stars_Blue)      804    0.007    0.000    0.007    0.000 GFX_Status.py:347(ReproduceFX_Stars_Yellow)      804    0.008    0.000    0.008    0.000 GFX_Status.py:368(ReproduceFX_Stars_White)      804    0.007    0.000    0.007    0.000 GFX_Status.py:389(ReproduceFX_Stars_Purple)      804    0.007    0.000    0.007    0.000 GFX_Status.py:410(ReproduceFX_Stars_Black)      804    0.010    0.000    0.025    0.000 GFX_Status.py:431(ReproduceFX_CoinPickup)        2    0.000    0.000    0.001    0.000 GFX_Status.py:456(AddFX)      804    0.004    0.000    0.004    0.000 GFX_Status.py:87(RenderAPnotifier)     9648    0.099    0.000    0.099    0.000 TriangleSolid.py:121(collision_with_rect)      804    0.004    0.000    0.004    0.000 buzz.py:138(rotateFrame)      804    0.023    0.000    0.346    0.000 buzz.py:143(move)       45    0.005    0.000    0.007    0.000 buzz.py:176(Jump)        9    0.000    0.000    0.002    0.000 buzz.py:190(startJump)      804    0.017    0.000    0.024    0.000 buzz.py:200(handleJump)      242    0.007    0.000    0.010    0.000 buzz.py:272(WalkRight_notBouncing)      449    0.014    0.000    0.020    0.000 buzz.py:288(WalkLeft_notBouncing)      112    0.003    0.000    0.004    0.000 buzz.py:305(Jetpack_NotUsed)      804    0.054    0.000    0.181    0.000 buzz.py:72(draw)      804    0.005    0.000    0.005    0.000 camera.py:11(set)     1608    0.015    0.000    0.021    0.000 debug.py:25(Start)     1608    0.041    0.000    0.049    0.000 debug.py:31(Stop)      804    0.023    0.000    6.410    0.008 debug.py:81(TestFunc)      945    0.004    0.000    0.004    0.000 default.py:47(collide)      804    0.007    0.000    0.007    0.000 dimwit.py:30(think)      155    0.001    0.000    0.001    0.000 dimwit.py:53(enemyToBuzz)      385    0.004    0.000    0.005    0.000 dimwit.py:69(collide)      804    0.006    0.000    0.006    0.000 event.py:38(update)      804    0.027    0.000    1.098    0.001 game.py:169(limitFramerate)      804    0.207    0.000    5.964    0.007 game.py:181(checkInput)      804    0.025    0.000    0.043    0.000 game.py:266(checkForConsole)      804    0.096    0.000    6.352    0.008 game.py:293(update)        1    0.000    0.000    0.000    0.000 game.py:315(exit)       71    0.001    0.000    0.001    0.000 game.py:323(CheckEvent)      804    0.080    0.000   28.544    0.036 game.py:66(loop)      804    0.370    0.000   14.980    0.019 game.py:90(draw)      804    0.023    0.000    0.033    0.000 germ.py:27(think)      164    0.001    0.000    0.001    0.000 germ.py:45(enemyToBuzz)    16985    3.555    0.000    4.222    0.000 input.py:296(MapMatch)    16985    0.685    0.000    5.672    0.000 input.py:65(KeyDown)      804    0.291    0.000    6.158    0.008 level.py:111(update)      804    0.380    0.000    8.646    0.011 level.py:82(draw)        1    0.023    0.023   28.585   28.585 main.py:31(main)      804    0.024    0.000    0.035    0.000 makochi_green.py:30(think)      804    0.014    0.000    0.071    0.000 makochi_green.py:40(draw)      804    0.021    0.000    0.269    0.000 makochi_green.py:48(move)      804    0.004    0.000    0.004    0.000 makochi_green.py:67(startJump)      328    0.001    0.000    0.001    0.000 makochi_green.py:71(enemyToBuzz)      804    0.010    0.000    0.015    0.000 makochi_green.py:77(handleJump)     1608    0.007    0.000    0.007    0.000 menu.py:20(isActive)      804    0.003    0.000    0.003    0.000 menu.py:35(update)     8844    0.118    0.000    1.001    0.000 npc.py:40(draw)     8844    0.177    0.000    3.368    0.000 npc.py:43(update)     2193    0.021    0.000    0.028    0.000 npc.py:54(enemyToBuzz)     4428    0.065    0.000    0.165    0.000 npc.py:67(collide)     8844    0.565    0.000    1.384    0.000 npc.py:73(checkForCollisions)   125424    1.146    0.000    1.146    0.000 object.py:26(collision_with_rect)      804    0.065    0.000    0.080    0.000 pickup.py:38(ItemCollectCheck)     2472    0.035    0.000    0.035    0.000 pickup.py:51(isVisible)      804    0.058    0.000    0.201    0.000 pickup.py:56(DrawItems)      804    0.038    0.000    0.452    0.001 player.py:325(update)        2    0.000    0.000    0.000    0.000 player.py:383(SetHP)     1610    0.010    0.000    0.010    0.000 player.py:390(GetHP)       39    0.000    0.000    0.000    0.000 player.py:670(TimerReset)     1608    0.019    0.000    0.027    0.000 player.py:673(TimerCheck)     8844    0.471    0.000    0.579    0.000 player.py:680(checkForCollisions)     1236    0.012    0.000    0.028    0.000 player.py:691(collide)        1    0.000    0.000   28.605   28.605 profile:0(main())        0    0.000             0.000          profile:0(profiler)      804    0.015    0.000    0.015    0.000 projectile.py:103(TrackBullets)      804    0.004    0.000    0.004    0.000 projectile.py:311(SendLevel)        3    0.000    0.000    0.000    0.000 random.py:147(randrange)        3    0.000    0.000    0.000    0.000 random.py:211(randint)        1    0.000    0.000    0.000    0.000 site.py:244(__call__)    14472    0.230    0.000    2.064    0.000 solid.py:135(draw)        5    0.000    0.000    0.000    0.000 sound.py:27(SoundFX)     2455    0.010    0.000    0.010    0.000 sprite.py:235(applyFriction)      156    0.001    0.000    0.001    0.000 sprite.py:250(reverseXVelocity)     3584    0.029    0.000    0.029    0.000 sprite.py:75(addVelocity)     5366    0.038    0.000    0.038    0.000 sprite.py:82(setVelocity)      803    0.003    0.000    0.003    0.000 sprite.py:91(get_speedx)     9648    1.671    0.000    2.916    0.000 sprite.py:99(updatePosition)     2412    0.012    0.000    0.012    0.000 test.py:137(rotateFrame)     2412    0.071    0.000    0.907    0.000 test.py:142(move)     3216    0.041    0.000    0.061    0.000 test.py:214(handleJump)      156    0.001    0.000    0.001    0.000 test.py:239(reverseDirection)     2412    0.143    0.000    0.507    0.000 test.py:80(draw)      804    0.004    0.000    0.004    0.000 testball.py:109(Local_applyFriction)      804    0.003    0.000    0.003    0.000 testball.py:24(think)       60    0.000    0.000    0.000    0.000 testball.py:27(enemyToBuzz)      804    0.026    0.000    0.083    0.000 testball.py:44(draw)      168    0.002    0.000    0.003    0.000 testball.py:45(collide)      804    0.044    0.000    0.384    0.000 testball.py:55(move)      804    0.011    0.000    0.017    0.000 testball.py:87(handleJump)      804    0.003    0.000    0.003    0.000 testbox.py:23(think)      804    0.015    0.000    0.029    0.000 testbox.py:40(draw)      849    0.010    0.000    0.021    0.000 testbox.py:44(collide)      804    0.024    0.000    0.258    0.000 testbox.py:47(move)      804    0.012    0.000    0.017    0.000 testbox.py:76(handleJump)     3216    0.021    0.000    0.021    0.000 transdoor.py:23(think)      396    0.002    0.000    0.002    0.000 transdoor.py:29(enemyToBuzz)     3216    0.044    0.000    0.135    0.000 transdoor.py:40(draw)     3216    0.068    0.000    0.984    0.000 transdoor.py:46(move)      734    0.005    0.000    0.005    0.000 transdoor.py:49(collide)     3216    0.012    0.000    0.012    0.000 transdoor.py:77(handleJump)      804    0.003    0.000    0.003    0.000 trap.py:22(think)      121    0.000    0.000    0.000    0.000 trap.py:28(enemyToBuzz)      218    0.057    0.000    0.057    0.000 trap.py:40(collide)      804    0.020    0.000    0.021    0.000 weapon.py:41(check_position)     3216    0.046    0.000    0.179    0.000 weapon.py:61(draw)      804    0.019    0.000    0.040    0.000 weaponRazzer.py:30(update)      804    0.004    0.000    0.004    0.000 zhaki.py:21(think)      969    0.003    0.000    0.003    0.000 zhaki.py:28(enemyToBuzz)      804    0.015    0.000    0.058    0.000 zhaki.py:40(draw)     1129    0.005    0.000    0.005    0.000 zhaki.py:41(collide)      804    0.022    0.000    0.280    0.000 zhaki.py:47(move)      804    0.011    0.000    0.018    0.000 zhaki.py:76(handleJump)

This topic is closed to new replies.

Advertisement