Why is Pygame so much slower than 2d game engines? - python

I am a godot user and a Python user. In pygame, in a simple game like pong, I had an average of 55-60 FPS in fullscreen. In addition, when ported to Kivy, I had an average FPS of 60-70FPS. But when I coded this in Godot, and got an average FPS of 180-200 in the viewport, while profiling! My program was extremely similar in both, and I wasn't static typing at all in Godot. Why is pygame so slow and is there anyway I can make it faster?

Godot is using OpenGL ES for drawing to the window. PyGame is based on SDL, which does not use hardware graphics primitives at all. You could also port your game to Kivy, which supports OpenGL ES too.
In terms of pushing pixels to the screen, graphics being drawn with a CPU Vs running on GPU is not a contest the CPU can ever win. That said, for a whole lot of game styles, PyGame is fast enough. There is absolutely no point updating the screen faster than the monitor is refreshing.
I would expect a basic Pong in PyGame to always run at full-FPS. On a huge high-DPI display, maybe even erasing the background is enough of a pixel-load to drop the FPS.

Related

Use VRAM (graphics card memory) in pygame for images

I'm programming a 2D game with Python and Pygame and now I want to use my internal graphics memory to load images to.
I have an Intel HD graphics card (2GB VRAM) and a Nvidia GeForce (4GB VRAM).
I want to use one of them to load images from the hard drive to it (to use the images from there).
I thought it might be a good idea as I don't (almost) need the VRAM otherwise.
Can you tell me if and how it is possible? I do not need GPU-Acceleration.
You have to create your window with the FULLSCREEN, DOUBLEBUF and HWSURFACE flags.
Then you can create and use a hardware surface by creating it with the HWSURFACE flag.
You'll also have to use pygame.display.flip() instead of pygame.display.update().
But even pygame itself discourages using hardware surfaces, since they have a bunch of disadvantages, like
- no mouse cursor
- only working in fullscreen (at least that's what pygame's documentation says)
- you can't easily manipulate the surfaces
- they may not work on all platforms
(and I never got transparency to work with them).
And it's not even clear if you really get a notable performance boot.
Maybe they'll work better in a future pygame release when pygame switches to SDL 2 and uses SDL_TEXTURE instead of SDL_HWSURFACE, who knows....

Repeating background with cocos2d (Python)

I am trying to write a (board) game with cocos2d in python. I want to have a nice grass texture as background, and it should repeat itself when the Window is resized.
Currently I loaded sprite and just drew it multiple times in a batch, depending on the window size. Problem that i am encountering is that when the window is resized i have to redraw the background every time but I think that this is not the way to go.
For the C++ API of cocos2d, there is something like GL_REPEAT, but I did not find such thing for the python API. Is there something I have been missing, or do you know an easier approach?
Thanks in advance !

How to optimize tile rendering in pygame?

I am making a tile based game, and the map needs to be rendered every frame. Right now, each tile is 32X32, and the visible map is 28X28 tiles. The performance is dreadful. I recently made it only render the visible tiles, but this still did not improve the FPS much. Right now I'm looking for a way to speed up the rendering. I attribute the slowness to the way I am rendering ; every tile is individually blitted to the screen. What would be a more effective was of doing this?
In pygame (afaik), updating the screen is always one hell of a bottle neck. Since I could not see your code, I don't know, how you are updating the screen. Only blitting the the sprites that changed is a start, but you need to only update those parts that changed, on the screen.
Basically it is the difference between using display.flip() or using update_rects() with only the changed rects. I know, that does not help at all, when you are scrolling the map.
Take a look at this question: Why is this small (155 lines-long) Pacman game on Python running so slow?, it has a similiar topic.
One thing I tried when I had a map compiled of tiles and some sprites on it, I tried always having a precompiled image of the map for an area containing the currently displayed part and some 200 or so pixels around that, so that I could blit the prepared "ground" (still only in updated parts) without the need of blitting all those tiles contained in it. That, of course, is quite some thinking you have to put into that, espacially if you have multiple layers and parts of the map that can be above your active sprites. It is interesting to think and work that through, but I cannot tell you, how much you will gain by that.
One totally different possible solution: I began with pygame once (since I did SDL in C++ prior to that). Recently I was directed to another python gaming library: pyglet. This does not suffer from the problems of updating the whole screen as much as pygame (I think it's because of usage of OpenGL acceleration; it still works on my not at all accelerated eee-Netbook). If you are not bound to pygame in any way, it might be interesting to take a look at pyglet.

Using Pygame to make scrolling shoot-em-up

I'm starting to work on a 2D scrolling shoot-em-up game, and I was wondering if pygame is suitable. I would like to hit close to 60 fps while animating a scrolling background with hundreds of sprites (mostly bullets, of course); is this feasible with pygame? From what I've read, I'm leaning toward no, but I'd like another opinion from someone with more experience with pygame.
I'm also looking at using PyOpenGL with pygame, but I have absolutely no experience with OpenGL. Will OpenGL work better in this case than native pygame graphics, and are there any good tutorials for OpenGL/PyOpenGL/using PyOpenGL with pygame?
Pygame is as good as they get for 2D CPU graphics. All the graphics is implemented in C, (PyGame wraps SDL) so the code is nearly as fast as an equivalent C software renderer.
That said, it's still (basically) a software renderer, and there's this interesting device in every modern computer called a GPU which is designed to do that. PyOpenGL/OpenGL will take advantage of it, so yes, absolutely PyOpenGL will render faster than PyGame.
Bottom line:
PyGame is fast, but not as fast as PyOpenGL. For hundreds of onscreen sprites, that will mainly be a logic problem (Python logic is slow, even by interpreted language standards). Rewriting it in SDL would make it faster (because C/C++ is faster than Python). You could also use PyOpenGL, which I predict in this case would improve performance significantly, though not dramatically (but it's much harder to use).
Like I said, though, it will be primarily a logic issue, I think. There is something to be said for using PyOpenGL, but as they say, the greatest optimization you will ever make is when your code works for the first time.
Pygame is the best solution for 2D games in python according to me. You can save Surfaces uses its optimized Sprites animation, so I think it's the fastest solution : as for development process than for code execution.

How do I track an animated object in Python?

I want to automate playing a video game with Python. I want to write a script that can grab the screen image, diff it with the next frame and track an object to click on. What libraries would be useful for this other than PIL?
There are a few options here. The brute force diff'ing approach will lead to a lot of frustration unless what you're tracking is very consistent. For this you could use any number of genetic approaches to train your program what to follow. After enough generations it would do the right thing reliably. If the thing you want to track is visually obvious (like a red ball on a white screen) then you could detect it yourself through simple brute force scanning of the bitmap.
Another approach would be just looking at the memory of the running app, and figuring out what area is controlling the position of your object. For some more info and ideas on this, see how mumble got 3D positional audio working in various games.
http://mumble.sourceforge.net/HackPositionalAudio
Answer would depend on the platform and game too.
e.g. I did once similar things for helicopter flash game, as it was very simple 2d game with well defined colored maze
It was on widows with copy to clipboard and win32 key events using win32api bindings for python.

Categories