Pygame Display.Update() Fix? [duplicate] - python

Just like the title implies, is there any difference? I was using pygame.display.flip and I saw on the Internet that instead of using flip they used pygame.display.update. Which one is faster?

The main difference between pygame.display.flip and pygame.display.update is, that
display.flip() will update the contents of the entire display
display.update() allows to update a portion of the screen, instead of the entire area of the screen. Passing no arguments, updates the entire display
To tell PyGame which portions of the screen it should update (i.e. draw on your monitor) you can pass a single pygame.Rect object, or a sequence of them to the display.update() function. A Rect in PyGame stores a width and a height as well as a x- and y-coordinate for the position.
PyGame's built-in dawning functions and the .blit() method for instance return a Rect, so you can simply pass it to the display.update() function in order to update only the "new" drawn area.
Due to the fact that display.update() only updates certain portions of the whole screen in comparison to display.flip(), display.update() is faster in most cases.

flip will always update the entire screen. update also updates the entire screen, if you don't give arguments. But, if you give surface(s) as arguments, it will update only those surfaces. So it can be faster, depending on how many surfaces you give it and their width and height.

pygame.display.flip() updates the whole screen.
pygame.display.update() updates only specific section but with no arguments works similar to the pygame.display.flip().

If you are doing double-buffering then you want to be using flip(). With only a single buffer either will work, and single buffering is what you are using unless you specifically create a double buffered window, such as this:
pygame.display.set((w, h), pygame.DOUBLEBUF)
Speed will be the same really if you are doing a single, full display update once a frame, so doesn't matter really which you use in single buffer mode.

Related

How do you rotate an image in Pygame without constantly redrawing the background?

I am making a randomized spinner in pygame, but the only method I've found is to constantly redraw the whole screen. Is there a way that doesn't use this, it becomes extremely laggy.
You can not. why do you want that? It is common to redraw the entire scene in each frame. Of course you can try to redraw just a rectangular section of the background. However, this is usually not worth the effort.
The pygame way to do this is to pass a list of rectangular areas to pygame.display.update(). If rectangles are passed to pygame.display.update() then not the entire display will be redrawn, just the specified areas::
Update portions of the screen for software displays
[...]
You can pass the function a single rectangle, or a sequence of rectangles. It is more efficient to pass many rectangles at once than to call update multiple times with single or a partial list of rectangles.
e.g.:
while run:
# [...]
screen.blit(background, (0, 0))
screen.blit(image1, bounding_rect1)
screen.blit(image2, bounding_rect2)
pygame.display.update([bounding_rect1, bounding_rect2])
That is how computer animation works, you're redrawing the screen on every frame. Every game practically works the same way. I am not sure what graphics pipeline pygame uses but in OpenGL you usually initialize all your geometry outside of the render loop and then use pointers to batch-process everything in the render-loop so you're not duplicating a lot of boilerplate code or making duplicate objects every frame.
A related question has been answered here:
https://gamedev.stackexchange.com/questions/125546/what-is-the-best-way-to-handle-the-actual-render-loop

Why is pygame.display.update() slower than pygame.display.flip()? [duplicate]

This question already has answers here:
Difference between pygame.display.update and pygame.display.flip
(4 answers)
Closed 5 years ago.
I do not understand what the difference is between pygame.display.update() and pygame.display.flip().
I have tried both and it seems that update() is slower than flip()...
EDIT:
My question is why update() with no parameters is much slower than flip().
Thanks!
You must first understand how pygame.display.flip and pygame.display.update work.
When the screen mode pygame.DOUBLEBUF is set, Pygame actually maintains two screens: the active screen which is presently displayed and a buffer which you (the programmer) can update behind the scenes (without the user seeing anything).
Once you are done with your edits on the buffer, you can use pygame.display.flip to switch the active screen with the buffer. The entire screen is updated. This is the recommended way to update the entire screen. Also, this is the only way to update non-software screens (OPENGL and Hardware accelerated screens for example).
pygame.display.update on the other hand treats the screen as a group of pixels (that's called a software screen). This allows a Pygame program to update only a portion of the screen. This is faster as only a portion of the screen needs to be modified.
Now, if the entire screen is to be updated (pygame.display.flip and pygame.display.update without any arguments) pygame.display.flip is faster.
Remember, I said OpenGL and HW-accelerated screens (SOFT-screens too) maintain a buffer. Drawing to this buffer is slow, but flipping is very fast (in HW-screens and OpenGL). Updating the entire screen using pygame.display.update is even slower as it does things pixel by pixel and without HW-acceleration.

Difference between pygame.display.update and pygame.display.flip

Just like the title implies, is there any difference? I was using pygame.display.flip and I saw on the Internet that instead of using flip they used pygame.display.update. Which one is faster?
The main difference between pygame.display.flip and pygame.display.update is, that
display.flip() will update the contents of the entire display
display.update() allows to update a portion of the screen, instead of the entire area of the screen. Passing no arguments, updates the entire display
To tell PyGame which portions of the screen it should update (i.e. draw on your monitor) you can pass a single pygame.Rect object, or a sequence of them to the display.update() function. A Rect in PyGame stores a width and a height as well as a x- and y-coordinate for the position.
PyGame's built-in dawning functions and the .blit() method for instance return a Rect, so you can simply pass it to the display.update() function in order to update only the "new" drawn area.
Due to the fact that display.update() only updates certain portions of the whole screen in comparison to display.flip(), display.update() is faster in most cases.
flip will always update the entire screen. update also updates the entire screen, if you don't give arguments. But, if you give surface(s) as arguments, it will update only those surfaces. So it can be faster, depending on how many surfaces you give it and their width and height.
pygame.display.flip() updates the whole screen.
pygame.display.update() updates only specific section but with no arguments works similar to the pygame.display.flip().
If you are doing double-buffering then you want to be using flip(). With only a single buffer either will work, and single buffering is what you are using unless you specifically create a double buffered window, such as this:
pygame.display.set((w, h), pygame.DOUBLEBUF)
Speed will be the same really if you are doing a single, full display update once a frame, so doesn't matter really which you use in single buffer mode.

Beginner problem with pygame

I'm just beginning a very simple pygame code that draws a green line on a white background. However, I have to use pygame.display.flip() in order for it to show up, but it seems that I would have to use this every time I made a change and this seems too impractical for me to be doing it right. Am I missing something?
There's a good reason for this. Double buffering is a technique used to prevent "flickering". Basically, you want to draw a frame to memory instead of to the monitor and then push the frame all at once when its drawn. Otherwise, you can see different elements of the same frame go up at different times.
What you want to do is call pygame.display.flip() only once per frame draw, not after every change. Usually, this is done by having a "draw" function that is called at the end of a frame once the physics manipulations and game rules are done, and flip()ing at the end of draw.
Yes, you will have to call it each time you want to update screen. By default pygame uses double buffering Wiki link.

Pygame: Updating Rects with scrolling levels

I'm currently making a 2D side-scrolling run'n'jump platform game in PyGame. Most of the stuff is working OK and very well in fact - I am exploiting the fast pyGame Sprite objects & groups.
What I'm interested to know is how people usually deal with Rects for scrolling games. I obviously have a level that is much bigger than visible area, and the player, enemies, bullets etc each have their own (x,y) coordinates which describe where they are in the level.
But now, since we use the "spriteGroup.draw(surface)" call, it will not display them in the right spot unless each objects Rects have been adjusted so that the right part displays on the screen. In other words, everytime a player/enemy/bullet/whatever else is updated, the Camera information needs to be passed, so that their Rect can be updated.
Is this the best method to use? It works but I don't really like passing the camera information to every single object at every update to offset the Rects.
Obviously the ideal method (I think) is to use Rects with "real" coordinates, blit everything to a buffer as big as the level, and then just blit the visible part to the screen, but in practice that slows the game down A LOT.
Any comments/insight would be appreciated.
Thanks
You could extend de Sprite.Group so it recives the camera information.
Then do one of these options:
A. Override the update method so it updates the on-screen coordinates of every sprite.
B. Override the draw method so it updates the on-screen coordinates of every sprite and then calls its parent draw method.
I think A it's easier and cleaner.
I don't really like passing the camera information to every single
object at every update to offset the Rects.
Camera may be global, or, a member of a global Game() class instance. Then your sprite class's draw method doesn't need an argument.
You can override draw yourself, so it does:
dest = game.camera.topleft + self.rect.topleft
screen.blit( self.surface, dest )
This keeps the bullet's rect in world-coordinates, yet blits using screen-coordinates.
One method I found is to keep track of a scrollx and a scrolly. Then, just add scrollx and scroll y to the coordinates when you move the rectangles.
You can have a 2 variables level_landlevel_d which see where you are in the level, Then check which sprites are in the visible area
level_d+height and level_l+width,
and draw them on the screen.
The simple way to do it is like that:
Create a CameraX and CameraY variables, and when you blit objects on the screen use this:
blit(surface, (x -CameraX, y -CameraY))
any object that gets affected by the camera should be drawn like that, but keep in mind that there are objects that you may want to remain uneffected (like health bars or status windows)
just keep in mind everytime you want to move camera do this
#Move Camera Right
CameraX += 10
#Move Camera Left
CameraX -= 10
#Move Camera Down
CameraY += 10
#Move Camera Up
CameraY -= 10
Just keep in mind that if they get negative values they may not work correctly, also you must probably define some limits (you dont want your camera to move over the limits of your map

Categories

Resources