I want to darken current screen a bit before poping up a new surface. I know there is no function in pygame to do this and that I will have to process the image to darken it. But as long as I know the only way to get current displaying surface in pygame is by saving it to disk as a file which slows down the game. Is there any other way to do this with pygame? Like saving the image to a value in memory so that I can process it without saving it somewhere.
Thanks in advance,
Stam
You don't need to save anything to a file.
When you read an image to a file, it is a Surface object. You them blit this object to the screen. But these Surface objects have the same methods and properties than the object working as the screen - (which is also a Surface): you can draw primitives, and blit other images to them - all in memory.
So, once you read your image, just make a copy of it, draw a filled rectangle with a solid transparent color on it to darken it, and then blit it to the screen. Repeat the process increasing the transparency level and pasting it on the screen again if you want a fade in effect.
import pygame
screen = pygame.display.set_mode((640,480))
img = pygame.image.load("MYIMAGE.PNG")
for opacity in range(255, 0, -15):
work_img = img.copy()
pygame.draw.rect(work_img, (255,0, 0, opacity), (0,0, 640,480))
screen.blit(work_img, (0,0))
pygame.display.flip()
pygame.time.delay(100)
Related
I am developing some software in pygame that allows a user to draw things on a canvas using different colors, pen sizes, etc. The problem is I don't know how to save the thing they have drawn as an image (e.g. png).
I need a way to frame the area where the image is on the screen and save it to the device's file system. Does anyone know how I can do this?
The PyGame display (window) is associated to a pygame.Surface object. Use pygame.image.save() to store the content of a Surface (or the screen) to a bitmap. The file type is automatically determined by the file extension:
pygame.image.save(screen, "my_file.png")
If you just want to save a section of the screen, you can define a subsurface that is directly linked to the source surface with the method subsurface:
subsurface(Rect) -> Surface
Returns a new Surface that shares its pixels with its new parent. The new Surface is considered a child of the original. Modifications to either Surface pixels will effect each other.
Create a sub-surface and save it to a file:
rect_area = pygame.Rect(x, y, width, height)
area_surf = screen.subsurface(rect_area)
pygame.image.save(area_surf, "my-file.png")
As I understood pygame drawing method, the 2nd argument of the blit function (screen.blit(surface, (0,0))) tells pygame where to draw the given surface (like an offset to start drawing from, or rather a placement of the surface on the screen). Although, from recent experimenting, it seems that pygame surfaces placements are fixed, and that (0,0) is used to crop the surface before pygame blit it to the screen, for efficiency purposes.
Are surfaces placement really fixed (is my latter observation correct)? and if so, is there another way to conveniently move an already drawn surface to another position on the screen? Or should i implement my own way of moving complex "drawable" objects?
Thanks!
A pygame.Surface object has no position, it has a size only. Note, the location of the Rect object which is returned by pygame.Surface.get_rect() is always (0, 0).
When you blit a Surface on another Surface, then each pixel is copied and placed at the corresponding position of the destination Surface. Thus always a position has to be specified, when a Surface is blit on a destination Surface.
See also Why is my collision test always returning 'true' and why is the position of the rectangle of the image always wrong (0, 0)?
[...] if so, is there another way to conveniently move an already drawn surface to another position [...]
You have a basic misunderstanding. A Surface cannot be "moved". A Surface is copied on the Surface object which is associated to the game window.
A Surface appears to be moving, because the entire scene is drawn in every frame. First the background is drawn, then the objects (Sprites, Surfaces) are drawn on top of the background and finally the display is updated (in every frame). If an object is placed at a slightly different position in every frame, then the object appears to be moving smoothly.
Like for example my game screen is 600 by 600, and my image is 600 by 1500. How can I make it so that my background moves to another part of the image when my sprite goes off screen, so it seems like I'm moving through but I'm really not?
Sorry if I seem confusing.
Thanks.
From the pygame documentation on blit, you can pass in an area of your background image that you want to draw.
My pygame is a bit rusty, but you should be able to do the following:
blit(background_image, destination_surface, ((left_x_offset, 0), (right_x_offset, 0))
The first argument is your background image (the 600 x 1500 one), the second argument is the surface you're drawing everything to, and the third argument is the area of your background image that you want to draw to the destination surface.
Since you want to move the background in relation to the character, I would set left_x_offset to the position of the character minus half the width of your screen, and right_x_offset to the position of the character plus half the screen size.
Having an issue with blitting order (I think) and transparent bounding boxes showing up during collisions.
Link to the code and the issue is here: https://github.com/CastleSeven/flappy-balloon/issues/1
Basically, whenever a collision is about to occur, the player model is occluded by a transparent bounding box around the obstacle. I'm not sure what I need to change so that JUST the non-transparent pixels are reblitted for the background on every loop.
If I change the code so that the balloon blit comes AFTER the obstacle blit, I get the inverse effect, the balloon's bounding box occludes the obstacle.
Try using a colorkey, make the background of the textures something ugly like (255, 0, 255) and set the colorkey of the textures the same color. https://www.pygame.org/docs/ref/surface.html#pygame.Surface.set_colorkey
When i try to blit an image in pygame the image blits smaller than the actual image, my simplified code is
import pygame
pygame.init()
screen = pygame.display.set_mode((1176,674),0,32)
background = pygame.image.load("picture.jpg").convert()
while True:
screen.blit(background, (0,0))
pygame.display.flip()
The resulting image is about half the size it should be
It is entirely possible that when you view it you have zoomed in. Or there could be formatting irregularities. Either way, there are two simple solutions. Solution number 1 is to just scale up the image in an image editor, if you don't have one, GIMP is free online. A better way is to scale it in the code. You can just double the size of an image you loaded with this modification to your code, solving your problem. Use pygame.transform:
import pygame
pygame.init()
screen = pygame.display.set_mode((1176,674),0,32)
background = pygame.image.load("start_screen.jpg").convert()
background = pygame.transform.scale(background, (1176,674))
while True:
screen.blit(background, (0,0))
pygame.display.flip()
this should work
I found that the issue came from my MacBooks retina screen resolution, once i downloaded a program to adjust the resolution the program worked properly