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.
Related
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
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.
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.
So I've been making a game using Python, specifically the PyGame module. Everything has been going fairly well (except Python's speed, am I right :P), and I've got a nice list of accomplishments from this, but I just ran into a... speedbump. Maybe a mountain. I'm not to sure yet. The problem is:
How do I go about implementing a Camera with my current engine?
That probably means nothing to you, though, so let me explain what my current engine is doing: I have a spritesheet that I use for all images. The map is made up of a double array of Tile objects, which fills up the display (800 x 640). The map also contains references to all Entity's and Particles. So now I want to create a a camera, so that the map object can be Larger than the display. To do this I've devised that I'll need some kind of camera that follows the player (with the player at the center of the screen). I've seen this implemented before in games, and even read a few other similar posts, but I need to also know Will I have to restructure all game code to work this in? My first attempt was to make all object move on the screen when the player moves, but I feel that there is a better way to do this, as this screws up collision detection and such.
So, if anyone knows any good references to problems like this, or a way to fix it, I'm all ears... er.. eyes.
Thanks
You may find this link to be of interest.
In essence, what you need to do is to distinguish between the "actual" coordinates, and the "display" coordinates of each object.
What you would do is do the bulk of the work using the actual coordinates of each entity in your game. If it helps, imagine that you have a gigantic screen that can show everything at once, and calculate everything as normal. It might help if you also designed the camera to be an entity, so that you can update the position of your camera just like any other object.
Once everything is updated, you go to the camera object, and determine what tiles, objects, particles, etc. are visible within the window, and convert their actual, world coordinates to the pixel coordinates you need to display them correctly.
If this is done correctly, you can also do things like scale and otherwise modify the image your camera is displaying without affecting gameplay.
In essence, you want to have a very clear distinction between gameplay and physics logic/code, and your rendering/display code, so your game can do whatever it wants, and you can render it however you want, with minimal crossover between the two.
So the good news is, you probably don't need to change anything about how your game itself works. The bad news is, you'll probably have to go in and rewrite your rendering/drawing code so that everything is drawn relative to the camera, not to the world.
Since I can't have a look into your code, I can't assess how useful this answer will be for you.
My approach for side scroller, moveable maps, etc. is to blit all tiles onto a pygame.Surface spanning the dimensions of the whole level/map/ etc. or at least a big chunk of it. This way I have to blit only one surface per frame which is already prepared.
For collision detection I keep the x/y values (not the entire rect) of the tiles involved in a separate list. Updating is then mainly shifting numbers around and not surfaces anymore.
Feel free to ask for more details, if you deem it useful :)
I'm currently making a game with pygame. I have one issue with my game at the moment.
The scrolling of the screen is fine, but once the image has been scrolled completely after its second time (it works fine first time) the screen blit goes all weird, all the sprites in the game leaves massive trails behind where it was previously (check screnshots). This is simply because for some stragnge reason the variable "x" is not being reset back to 0 once it has exceeded the screenwidth after the second time, it resets after it equal 1384 the first time but not after the second time..
any help is greatly appreciated.
http://pastebin.com/ub6gi8Zn (pastebin code gone)
Blit working fine before background has repeated itself twice SCREENSHOT
gyazo.com/aa5626d4927b0b9299ce2ec42c9ba501 -- after the background repeating itself twice-- sorry couldn't add more than 2 links
The problem is that you aren't clearing the screen buffer.
That is, the sprites and background just get redrawn over themselves because you haven't erased the pixels of the last time you drew those sprites on the screen!
I have never used pygame before but this is a general graphics programming problem, I tried looking up and it seems the function you are looking for is screen.fill(some_color). You fill the entire screen with a given color so the output of the last drawn frame disappear.
By the way this also happens because your "background" doesn't fill the entire area of the screen.