Python + Pygame = slow game?

Started by
17 comments, last by Kylotan 15 years, 5 months ago
The fill and flip functions seem to be soaking up a lot of time. Try pre-flipping for the latter.

What's the fill function being used for in this game? If you just want a flat colour, there are quicker ways of achieving the same goal. Pixel plotting isn't usually hardware-accelerated, whereas blitting is.

Sean Timarco Baggaley (Est. 1971.)Warning: May contain bollocks.
Advertisement
Well with fill function we made sky and ground but that will be removed when we will have some nice backgrounds and programmed rooms in level editor (on that we are currently working)...running field (where player moves) is right now infinite in any way so that is why filling is there and no background...
Try this

http://psyco.sourceforge.net/

It's a jit compiler for python.

-ddn
I have an old version of fedora 2, it doesnt have all the new python libraries. I hope to load Fedora 9 soon.
Right now we have around 35-40 fps on this configuration : Intel Pentium M , 1.73 GHz,2 GB RAM DDR and some integrated 32-bit graphic card.That is still too slow,we would like to have around 60 fps on Intel Pentium 3 600 MHz , 128 MB RAM and some graphic card like GeForce 3 32 MB.Is that even possible?also we was examining dirty rect animation (explanation of it is more down) , but at end it tells :There are two cases where this technique just won't work. The first is where the whole window or screen really is being updated every frame - think of a smooth-scrolling engine like an overhead real-time strategy game or a side-scroller. So what do you do in this case? Well, the short answer is - don't write this kind of game in pygame. The long answer is to scroll in steps of several pixels at a time; don't try to make scrolling perfectly smooth. Your player will appreciate a game that scrolls quickly, and won't notice the background jumping along too much.So is there any other way to do it?? To speed up bliting in side scrolling game using pygame? Is it possible to blit with Python? Also how to keep frame rate stable???Thanks in advance!!!!!!The most common cause of inadequate frame rates in pygame programs results from misunderstanding the pygame.display.update() function. With pygame, merely drawing something to the display surface doesn't cause it to appear on the screen - you need to call pygame.display.update(). There are three ways of calling this function:1. pygame.display.update() - This updates the whole window (or the whole screen for fullscreen displays).2. pygame.display.flip() - This does the same thing, and will also do the right thing if you're using doublebuffered hardware acceleration, which you're not, so on to...3. pygame.display.update(a rectangle or some list of rectangles) - This updates just the rectangular areas of the screen you specify.Most people new to graphics programming use the first option - they update the whole screen every frame. The problem is that this is unacceptably slow for most people. Calling update() takes 35 milliseconds on my machine, which doesn't sound like much, until you realize that 1000 / 35 = 28 frames per second maximum. And that's with no game logic, no blits, no input, no AI, nothing. I'm just sitting there updating the screen, and 28 fps is my maximum framerate. Ugh.The solution is called 'dirty rect animation'. Instead of updating the whole screen every frame, only the parts that changed since the last frame are updated. I do this by keeping track of those rectangles in a list, then calling update(the_dirty_rectangles) at the end of the frame. In detail for a moving sprite, I:1. Blit a piece of the background over the sprite's current location, erasing it.2. Append the sprite's current location rectangle to a list called dirty_rects.3. Move the sprite.4. Draw the sprite at it's new location.5. Append the sprite's new location to my dirty_rects list.6. Call display.update(dirty_rects)The difference in speed is astonishing. Consider that Solarwolf has dozens of constantly moving sprites updating smoothly, and still has enough time left over to display a parallax starfield in the background, and update that too.A final note - not every game requires high framerates. A strategic wargame could easily get by on just a few updates per second - in this case, the added complexity of dirty rect animation may not be necessary. ncalls  tottime  percall  cumtime  percall filename:lineno(function)     3131    0.041    0.000    0.041    0.000 :0(append)    49185   11.323    0.000   11.323    0.000 :0(blit)     3875    0.019    0.000    0.019    0.000 :0(clock)        1    0.000    0.000    0.000    0.000 :0(close)     1842    0.017    0.000    0.017    0.000 :0(colliderect)       15    0.001    0.000    0.001    0.000 :0(convert)     1876    0.064    0.000    0.064    0.000 :0(convert_alpha)      591    0.159    0.000    0.162    0.000 :0(eval)     1874    0.047    0.000    0.047    0.000 :0(fill)      942    8.434    0.009    8.434    0.009 :0(flip)      938    0.210    0.000    0.210    0.000 :0(get)      937    0.006    0.000    0.006    0.000 :0(get_focused)      937    0.005    0.000    0.005    0.000 :0(get_fps)     8042    0.047    0.000    0.047    0.000 :0(get_height)     2112    0.021    0.000    0.021    0.000 :0(get_pos)     4685    0.067    0.000    0.067    0.000 :0(get_pressed)        2    0.000    0.000    0.000    0.000 :0(get_rect)     1921    0.012    0.000    0.012    0.000 :0(get_ticks)     8042    0.038    0.000    0.038    0.000 :0(get_width)      162    0.004    0.000    0.004    0.000 :0(index)        8    0.000    0.000    0.000    0.000 :0(len)       17    0.032    0.002    0.032    0.002 :0(load_extended)      162    0.085    0.001    0.085    0.001 :0(play)     3087    0.056    0.000    0.056    0.000 :0(pop)      937    0.014    0.000    0.014    0.000 :0(range)     5932    0.418    0.000    0.418    0.000 :0(remove)      937    0.122    0.000    0.122    0.000 :0(render)      527    0.111    0.000    0.111    0.000 :0(rotate)      591    0.012    0.000    0.012    0.000 :0(set_alpha)        1    0.019    0.019    0.019    0.019 :0(setprofile)      527    0.069    0.000    0.069    0.000 :0(smoothscale)       80    0.003    0.000    0.003    0.000 :0(sqrt)      937    1.130    0.001    1.130    0.001 :0(tick)    592/1    0.003    0.000   33.451   33.451 <string>:1(<module>)      937    0.062    0.000    0.170    0.000 GFX_OSD.py:76(DrawHealthBar)      937    0.008    0.000    0.008    0.000 GFX_OSD.py:93(WeaponChangeRender)      937    0.006    0.000    0.006    0.000 GFX_Status.py:101(RenderAPnotifier)        1    0.000    0.000    0.001    0.001 GFX_Status.py:111(AddFX_ForestMakochiDestroyed)       28    0.003    0.000    0.015    0.001 GFX_Status.py:119(AddFX_GenericBurst)        3    0.000    0.000    0.003    0.001 GFX_Status.py:127(AddFX_GenericBurst_Red)        1    0.000    0.000    0.000    0.000 GFX_Status.py:149(AddFX_Stars_Red)        1    0.000    0.000    0.000    0.000 GFX_Status.py:173(AddFX_CoinPickup)      937    0.019    0.000    0.065    0.000 GFX_Status.py:180(ReproduceFX_ForestMakochiDestroy)      937    0.016    0.000    0.016    0.000 GFX_Status.py:205(ReproduceFX_MinervaBounce)      937    0.105    0.000    0.432    0.000 GFX_Status.py:235(ReproduceFX_GenericBurst)      937    0.010    0.000    0.010    0.000 GFX_Status.py:258(ReproduceFX_GenericBurst2)      937    0.020    0.000    0.059    0.000 GFX_Status.py:281(ReproduceFX_GenericBurst_Red)      937    0.014    0.000    0.014    0.000 GFX_Status.py:304(ReproduceFX_GenericTrail)      937    0.013    0.000    0.013    0.000 GFX_Status.py:327(ReproduceFX_GenericTrail2)      937    0.018    0.000    0.018    0.000 GFX_Status.py:359(ReproduceFX_Shadow)      937    0.019    0.000    0.071    0.000 GFX_Status.py:382(ReproduceFX_Stars_Red)      937    0.013    0.000    0.013    0.000 GFX_Status.py:403(ReproduceFX_Stars_Blue)      937    0.010    0.000    0.010    0.000 GFX_Status.py:424(ReproduceFX_Stars_Yellow)      937    0.011    0.000    0.011    0.000 GFX_Status.py:445(ReproduceFX_Stars_White)      937    0.014    0.000    0.014    0.000 GFX_Status.py:466(ReproduceFX_Stars_Purple)      937    0.007    0.000    0.007    0.000 GFX_Status.py:487(ReproduceFX_Stars_Black)      937    0.014    0.000    0.031    0.000 GFX_Status.py:508(ReproduceFX_CoinPickup)        3    0.000    0.000    0.001    0.000 GFX_Status.py:533(AddFX)     6868    0.088    0.000    0.088    0.000 TriangleSolid.py:121(collision_with_rect)     1874    0.013    0.000    0.013    0.000 buzz.py:140(rotateFrame)     1874    0.067    0.000    1.201    0.001 buzz.py:145(move)       64    0.021    0.000    0.022    0.000 buzz.py:178(Jump)        7    0.000    0.000    0.000    0.000 buzz.py:192(startJump)     1874    0.051    0.000    0.068    0.000 buzz.py:202(handleJump)      141    0.001    0.000    0.001    0.000 buzz.py:225(reverseDirection)      434    0.004    0.000    0.004    0.000 buzz.py:283(WalkRight)      173    0.002    0.000    0.002    0.000 buzz.py:302(WalkLeft)      330    0.002    0.000    0.002    0.000 buzz.py:321(NoMoveCommands)     1874    0.375    0.000    0.826    0.000 buzz.py:72(draw)      937    0.010    0.000    0.010    0.000 camera.py:11(set)     1874    0.019    0.000    0.028    0.000 debug.py:25(Start)     1874    0.061    0.000    0.070    0.000 debug.py:31(Stop)      937    0.055    0.000    6.220    0.007 debug.py:81(TestFunc)      146    0.001    0.000    0.001    0.000 default.py:47(collide)      937    0.014    0.000    0.014    0.000 dimwit.py:30(think)      138    0.001    0.000    0.001    0.000 dimwit.py:53(enemyToBuzz)      138    0.002    0.000    0.006    0.000 dimwit.py:69(collide)      937    0.014    0.000    0.014    0.000 event.py:38(update)      937    0.496    0.001   24.846    0.027 game.py:104(draw)      937    0.039    0.000    1.224    0.001 game.py:186(limitFramerate)      937    0.121    0.000    0.294    0.000 game.py:198(checkInput)      937    0.033    0.000    0.079    0.000 game.py:318(checkForConsole)      937    0.258    0.000    6.121    0.007 game.py:345(update)        1    0.001    0.001    0.001    0.001 game.py:380(exit)      379    0.017    0.000    0.219    0.001 game.py:388(CheckEvent)      937    0.104    0.000   32.971    0.035 game.py:77(loop)     9854    0.091    0.000    0.091    0.000 input_koki.py:10(CheckEvent)      937    0.161    0.000    0.274    0.000 input_koki.py:101(Update)    24362    0.113    0.000    0.113    0.000 input_koki.py:20(Update)      379    0.076    0.000    0.168    0.000 input_koki.py:96(CheckEvent)      937    0.483    0.001   12.871    0.014 level.py:130(draw)      937    0.305    0.000    5.708    0.006 level.py:168(update)        2    0.000    0.000    0.002    0.001 level.py:265(insertSolid)        1    0.050    0.050   33.451   33.451 main.py:56(main)        3    0.003    0.001    0.006    0.002 makochi_green.py:105(shot)      309    0.007    0.000    0.021    0.000 makochi_green.py:40(draw)      309    0.008    0.000    0.160    0.001 makochi_green.py:48(move)      309    0.010    0.000    0.014    0.000 makochi_green.py:56(think)      309    0.002    0.000    0.002    0.000 makochi_green.py:67(startJump)      309    0.005    0.000    0.008    0.000 makochi_green.py:77(handleJump)     1874    0.013    0.000    0.013    0.000 menu.py:20(isActive)      937    0.003    0.000    0.003    0.000 menu.py:35(update)     5931    0.096    0.000    0.777    0.000 npc.py:40(draw)     5931    0.154    0.000    3.451    0.001 npc.py:43(update)      236    0.005    0.000    0.006    0.000 npc.py:54(enemyToBuzz)       27    0.000    0.000    0.007    0.000 npc.py:58(shot)        1    0.000    0.000    0.000    0.000 npc.py:62(destroy)      528    0.009    0.000    0.016    0.000 npc.py:67(collide)     5931    0.348    0.000    0.772    0.000 npc.py:73(checkForCollisions)        6    0.000    0.000    0.000    0.000 ntpath.py:116(splitdrive)        6    0.000    0.000    0.000    0.000 ntpath.py:51(isabs)        2    0.000    0.000    0.000    0.000 ntpath.py:59(join)   125058    1.433    0.000    1.433    0.000 object.py:26(collision_with_rect)        2    0.000    0.000    0.000    0.000 object.py:7(__init__)      937    0.074    0.000    0.091    0.000 pickup.py:38(ItemCollectCheck)     1841    0.075    0.000    0.075    0.000 pickup.py:51(isVisible)      937    0.048    0.000    0.242    0.000 pickup.py:56(DrawItems)      937    0.049    0.000    0.701    0.001 player.py:325(update)        3    0.000    0.000    0.000    0.000 player.py:383(SetHP)     1877    0.010    0.000    0.010    0.000 player.py:390(GetHP)       47    0.000    0.000    0.001    0.000 player.py:670(TimerReset)     1874    0.024    0.000    0.036    0.000 player.py:673(TimerCheck)     5931    0.274    0.000    0.294    0.000 player.py:680(checkForCollisions)      236    0.003    0.000    0.009    0.000 player.py:691(collide)        1    0.001    0.001   33.471   33.471 profile:0(main())        0    0.000             0.000          profile:0(profiler)      937    0.047    0.000    0.089    0.000 projectile.py:17(Update)      937    0.017    0.000    0.046    0.000 projectile.py:176(DrawPointer)       65    0.002    0.000    0.002    0.000 projectile.py:181(GetPercX)       65    0.000    0.000    0.000    0.000 projectile.py:190(GetPercY)       65    0.000    0.000    0.000    0.000 projectile.py:194(GetSQ)      119    0.005    0.000    0.030    0.000 projectile.py:198(FireBullet_Generic)      937    0.059    0.000    0.340    0.000 projectile.py:24(Draw)      937    0.254    0.000    1.852    0.002 projectile.py:289(TrackBullets)       15    0.001    0.000    0.034    0.002 projectile.py:33(AddProjectile)       15    0.001    0.000    0.033    0.002 projectile.py:46(__init__)     2459    0.612    0.000    1.014    0.000 projectile.py:531(CollidedWithSolid)     2431    0.236    0.000    0.342    0.000 projectile.py:536(CollidedWithNPC)      937    0.005    0.000    0.005    0.000 projectile.py:560(SendLevel)    71318    0.501    0.000    0.501    0.000 projectile.py:564(isInRect)     5676    0.042    0.000    0.042    0.000 projectile.py:59(Update)     5676    0.090    0.000    0.280    0.000 projectile.py:66(Draw)        1    0.000    0.000    0.000    0.000 site.py:244(__call__)    21800    0.446    0.000    4.809    0.000 solid.py:135(draw)        2    0.000    0.000    0.002    0.001 solid.py:25(__init__)        2    0.000    0.000    0.002    0.001 solid.py:30(__init__)        2    0.000    0.000    0.002    0.001 solid.py:41(moreInit)        2    0.000    0.000    0.002    0.001 solid.py:9(load_image)      162    0.004    0.000    0.093    0.001 sound.py:33(SoundFX)     1267    0.010    0.000    0.010    0.000 sprite.py:189(applyFriction)      141    0.002    0.000    0.002    0.000 sprite.py:204(reverseXVelocity)     1403    0.014    0.000    0.014    0.000 sprite.py:74(addVelocity)     2032    0.013    0.000    0.013    0.000 sprite.py:81(setVelocity)     6868    1.954    0.000    3.476    0.001 sprite.py:96(updatePosition)        2    0.000    0.000    0.000    0.000 sprite.py:97(__init__)     3748    0.019    0.000    0.019    0.000 transdoor.py:23(think)       98    0.000    0.000    0.000    0.000 transdoor.py:29(enemyToBuzz)       14    0.000    0.000    0.000    0.000 transdoor.py:32(shot)     3748    0.077    0.000    0.209    0.000 transdoor.py:40(draw)     3748    0.111    0.000    1.903    0.001 transdoor.py:46(move)      244    0.002    0.000    0.002    0.000 transdoor.py:49(collide)     3748    0.021    0.000    0.021    0.000 transdoor.py:77(handleJump)      937    0.020    0.000    0.020    0.000 weapon.py:41(check_position)     1874    0.034    0.000    0.063    0.000 weapon.py:61(draw)      937    0.018    0.000    0.038    0.000 weaponMinerva.py:24(update)      937    0.004    0.000    0.004    0.000 zhaki.py:21(think)       10    0.000    0.000    0.000    0.000 zhaki.py:31(shot)      937    0.021    0.000    0.034    0.000 zhaki.py:40(draw)      937    0.030    0.000    0.560    0.001 zhaki.py:47(move)      937    0.020    0.000    0.026    0.000 zhaki.py:76(handleJump)
From what I understand SDL uses GDI functions to do its 2D drawing, blits and such which are very slow. I hear you can get better performance going through the OpenGL interfaces. There are many OpenGL 2D sprite tutorials which you can repurpose for your needs. That's really the only option, since your profile shows your bounded by the blit and update.

Good Luck!

-ddn
Ok..so it is possible to connect Pygame with PyOpenGL...is there any good tutorial for it ? We would use PyOpenGL functions only for blitting sprites, nothing else, because there is no other problems except that.
Thanks in advance!
There isn't a need to use another library than SDL, as SDL already has OpenGL support built in, you'll just need to access it. I beleive pyGame binds nearly the complete OpenGL interfaces to Python, so any examples you download off the net should work line for line in Python.

See for tutorials:

http://www.libsdl.org/opengl/index.php

[edit: Looks like pyGame doesn't expose any openGL interfaces at all. My first choice would be to extend pyGame and add in the openGL support within pyGame, possibly using the pyOpenGL as a starting point ( since they wrap all the interfaces for you ), or trying to intergrate pyOpenGL, problem is pyGame and SDL creates their own windows context and resources which might be duplicated within pyOpenGL.

I was just browsing pyGames src and it's really quite an old C based library. Doesn't take advantage of any of the 3d acceleration technological advances, even though it does use the SDL for the backend. It might be time to bring the surface class up to date with todays tech, it would get a massive improvement in performance.]


Good Luck!

-ddn

[Edited by - ddn3 on November 5, 2008 6:58:40 PM]
Quote:Original post by ddn3
[edit: Looks like pyGame doesn't expose any openGL interfaces at all. My first choice would be to extend pyGame and add in the openGL support within pyGame, possibly using the pyOpenGL as a starting point ( since they wrap all the interfaces for you ), or trying to intergrate pyOpenGL, problem is pyGame and SDL creates their own windows context and resources which might be duplicated within pyOpenGL.

Or just use Pyglet which gives you the convenience of SDL with the speed of OpenGL, rather than just giving you access to OpenGL and expecting you to code the rendering. It does what SDL and PyGame should have done years ago.

This topic is closed to new replies.

Advertisement