Python : Update a changing variable in a window using pygame.font - python

this is my first post, I'm a begginer in programmation, in Python especially
I created a game with a controllable character, you have to avoid an AI, otherwise the chances decrease each times by 1 (from 10 to 0), I want to print chances in real time, but the problem is that it is displayed twice on top of each other, so we can't see the reamaning chances,I Don't know what to do, I already used pygame.display.update(), here's my code's part :
import pygame
pygame.init()
nombreDeFois = 10
font = pygame.font.Font(None, 36)
s = "Chances restantes : " + str(nombreDeFois)
text = font.render(s, 0, (255, 178, 51))
textpos = text.get_rect()
textpos.center = (442,15)
backgroundjeu.blit(text, textpos)
pygame.display.update()

Each time you want to display something on the screen with pygame, it gets added to what is already on the screen, so to update it you must first fill the screen with the background color in order to clear the screen and then display it. Generally, this is done every frame for a game with moving graphics.
E.g.:
display = pygame.display.set_mode(...)
#at the start of the code that runs each frame
display.fill(<insert background color>)
If you are using a background image, blit it again each frame instead.
This also means that everything needs to be redrawn each frame, though, or it would disappear immediately after the first frame.

Related

How do I upload a png image in pygame as a sprite, without the black background?

]How do I get my sprite to appear on the screen. i have been days at this and I couldn't get it to appear on the screen and it kept either taking over the screen as black.
import pygame
pygame.init()
win = pygame.display.set_mode((600,600))
pygame.display.set_caption("Napoleon")
bg = pygame.image.load("apple.png").convert()
win.blit(bg, [0,0])
flower= pygame.image.load("flower2.png").convert()
win.blit(flower, [603,29])
pygame.display.update()
Instead of convert() try convert_alpha(). Assuming your image has an alpha channel (PNG should be good) and it has been applied to your background. If your image has no alpha channel and you need a background gone, you should look into the set_colorkey() function.
Also, for future reference, you can format your code in your question by highlighting it all and pressing CTRL+K. Makes it much easier to read (and you'll get faster answers!)

Pygame Window created in the background

When I start my program that has to open pygame window, it opens it behind the current window. What have I to write to make a focus on pygame window and it won't be as background? This is for a game for mathematics revision so I need to use the python shell as well, in this example for (1+1).
This is the code I run. (just as an example)
import pygame
play = input("DO you want to play the game(y,n): ")
if play == "y":
pygame.init()
font = pygame.font.SysFont("None", 24, bold = False, italic = False )
Screen = pygame.display.set_mode((800, 600))
black = (0,0,0)
Screen.fill(black)
pygame.display.set_caption("Snake Game")
pygame.draw.rect(Screen, (218,123,255), ((0,0),(600,20)),0)
pygame.draw.rect(Screen, (0,197,243), ((0,20),(800, 580)), 16)
pygame.display.update()
#Play game for some time
Add = input("1 + 1 = ")
#Continue game on the pygame window
The only way to have the system position the pygame window in front of all the other ones is to not use the Python Shell.
Aside from doing that I do not think that there is any way to change how the system positions the window in pygame. I haven't found anything that changes whether it is positioned behind or in front of the current window. Correct me if I am wrong but I would guess that is the OS's job.
Thus, you must do everything in Pygame or else you will have the user switching between windows.
To fix this problem:
Remove all uses of the input function and use of the Python shell.
Implement a way to ask the mathematics questions in Pygame using font rendering
Implement a way to let the user type in an answer and enter it in. This can be done using font rendering and input handling.
I hope this answer helped you and if you have any further questions please feel free to post a comment below!

Preventing Image from being cleared [PYGAME- Python]

It's extremely painful to redraw each image everytime the screen is cleared.
import pygame
from pygame.locals import *
T = pygame.display.set_mode((500,500))
M = pygame.image.load("test.jpg")
X = 0
Y = 0
while True:
X += 1
Y += 1
# Other sprites are here which are also redrawn every time loop runs.
# Other code is here too, this is just a little part of it to help explain my problem
T.fill((0,0,0))
T.blit(M,(X,Y))
pygame.display.flip()
In the above code, I am loading the background image in M Variable, everytime I clear the screen to update the position of my sprites, I also have to redraw the background image which is causing severe FPS drops.
Anyway I can prevent the Background image from being cleared whenever I am using T.fill((0,0,0)) ?
First, try to convert the background image. Images should usually be converted with convert or convert_alpha to improve the performance.
M = pygame.image.load("test.jpg").convert()
Second, if the background image has the size of the screen you can omit the line T.fill((0,0,0)), since the background fills the screen anyway.
Third, if the background isn't scrolling and you only need to update some portions of the screen every frame, you can try to use pygame.display.update() instead of pygame.display.flip(). Pass a single rect or a list of rects to pygame.display.update to tell it which parts of the screen should be updated.
I'm not sure if these measures will improve the performance drastically. Pygame is rather slow because it still relies on software rendering.
Sidenote, use descriptive variable names instead of T, M, etc..

Why Does PyGame Trail the Image? [duplicate]

This question already has answers here:
Pygame how to fix 'trailing pixels'?
(4 answers)
Closed 5 years ago.
I'm trying to develop a simple game in python using pygame and IDLE. I have, since yesterday, looked through a variety of sources in order to learn about the language (and programming in general), even so I have encountered some problems and misunderstandings of how it all works. So, if anyone could please advise me on how to proceed (or point me in the direction of some good learning material) then I would appreciate it greatly.
So far, I've got a small bit of code that forms the basis of my game idea, so I will post it here and list some of my problems.
import pygame
def main():
pygame.init()
logo = pygame.image.load("coolblack.jpg")
pygame.display.set_icon(logo)
pygame.display.set_caption("Battleship")
screenWidth = 800
screenHeight = 600
screen = pygame.display.set_mode((screenWidth, screenHeight))
bgd_image = pygame.image.load("grid.png")
#--------------------------------------------------------------------
#the image named 'image' should be above 'bgd_image' but below 'cv9'
#in fact, everything should be above bgd_image, especially 'cv9'
#--------------------------------------------------------------------
image = pygame.image.load("coolblack.jpg")
cv9 = pygame.image.load("ussessexcv9.gif").convert_alpha()
xposCv9 = 400
yposCv9 = 510
step_xCv9 = 1
step_yCv9 = 1
screen.blit(bgd_image, (0,0))
screen.blit(image, (400,300))
screen.blit(cv9, (xposCv9, yposCv9))
pygame.display.flip()
clock = pygame.time.Clock()
running = True
#---------------------------------------------
#I've got a pretty good idea (sort of) about
#what is happening in the section
#below this point, however it seems that
#the image 'cv9' creates a trail of itself
#every time it moves, so how could I make it
#so that it doesn't do so?
#---------------------------------------------
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
running = False
if xposCv9>screenWidth-64 or xposCv9<0:
step_xCv9 = -step_xCv9
if yposCv9>screenHeight-64 or yposCv9<0:
step_yCv9 = -step_yCv9
xposCv9 += step_xCv9
yposCv9 += step_yCv9
screen.blit(cv9, (xposCv9, yposCv9))
pygame.display.flip()
clock.tick(60)
if __name__=="__main__":
main()
The way that pygame works is that it has internally a representation of the screen which you are updating. So, it starts entirely black, then you do your first "blit". This will update the internal representation. Then when you call "pygame.display.flip" it shows that representation on the screen. However, this will not automatically "clear" the representation for you back to all black for your next frame. So, on the next frame, you blit again (slightly to the left, say), and the first blit remains, creating your "trail".
Therefore, for what you're doing, the best thing would be to in your loop, clear the internal representation of the screen before you start drawing the next frame. You can "clear" the screen by filling it with a single color, like so...
BLACK = (0,0,0)
....
screen.blit(cv9, (xposCv9, yposCv9))
pygame.display.flip()
clock.tick(60)
screen.fill(BLACK) # Add this to "clear" the screen.
Note that if you chose to go this route, this means you will need to redraw ALL of the elements every single frame (not just the ones that changed since the last frame).
BTW, in case you are wondering, there is a good reason for why the frame is not automatically cleared at the end. In some cases, it might be faster to only update the parts of the screen that update. This can cause performance speedups in some applications. However, it's probably best to start with clearing the screen as the example shows above.

Any way to speed up Python and Pygame?

I am writing a simple top down rpg in Pygame, and I have found that it is quite slow.... Although I am not expecting python or pygame to match the FPS of games made with compiled languages like C/C++ or event Byte Compiled ones like Java, But still the current FPS of pygame is like 15. I tried rendering 16-color Bitmaps instead of PNGs or 24 Bitmaps, which slightly boosted the speed, then in desperation , I switched everything to black and white monochrome bitmaps and that made the FPS go to 35. But not more. Now according to most Game Development books I have read, for a user to be completely satisfied with game graphics, the FPS of a 2d game should at least be 40, so is there ANY way of boosting the speed of pygame?
Use Psyco, for python2:
import psyco
psyco.full()
Also, enable doublebuffering. For example:
from pygame.locals import *
flags = FULLSCREEN | DOUBLEBUF
screen = pygame.display.set_mode(resolution, flags, bpp)
You could also turn off alpha if you don't need it:
screen.set_alpha(None)
Instead of flipping the entire screen every time, keep track of the changed areas and only update those. For example, something roughly like this (main loop):
events = pygame.events.get()
for event in events:
# deal with events
pygame.event.pump()
my_sprites.do_stuff_every_loop()
rects = my_sprites.draw()
activerects = rects + oldrects
activerects = filter(bool, activerects)
pygame.display.update(activerects)
oldrects = rects[:]
for rect in rects:
screen.blit(bgimg, rect, rect)
Most (all?) drawing functions return a rect.
You can also set only some allowed events, for more speedy event handling:
pygame.event.set_allowed([QUIT, KEYDOWN, KEYUP])
Also, I would not bother with creating a buffer manually and would not use the HWACCEL flag, as I've experienced problems with it on some setups.
Using this, I've achieved reasonably good FPS and smoothness for a small 2d-platformer.
All of these are great suggestions and work well, but you should also keep in mind two things:
1) Blitting surfaces onto surfaces is faster than drawing directly. So pre-drawing fixed images onto surfaces (outside the main game loop), then blitting the surface to the main screen will be more efficient. For exmample:
# pre-draw image outside of main game loop
image_rect = get_image("filename").get_rect()
image_surface = pygame.Surface((image_rect.width, image_rect.height))
image_surface.blit(get_image("filename"), image_rect)
......
# inside main game loop - blit surface to surface (the main screen)
screen.blit(image_surface, image_rect)
2) Make sure you aren't wasting resources by drawing stuff the user can't see. for example:
if point.x >= 0 and point.x <= SCREEN_WIDTH and point.y >= 0 and point.y <= SCREEN_HEIGHT:
# then draw your item
These are some general concepts that help me keep FPS high.
When using images it is important to convert them with the convert()-function of the image.
I have read that convert() disables alpha which is normally quite slow.
I also had speed problems until I used a colour depth of 16 bit and the convert function for my images. Now my FPS are around 150 even if I blit a big image to the screen.
image = image.convert()#video system has to be initialed
Also rotations and scaling takes a lot of time to calculate. A big, transformed image can be saved in another image if it is immutable.
So the idea is to calculate once and reuse the outcome multiple times.
When loading images, if you absolutely require transparency or other alpha values, use the Surface.convert_alpha() method. I have been using it for a game I've been programming, and it has been a huge increase in performance.
E.G: In your constructor, load your images using:
self.srcimage = pygame.image.load(imagepath).convert_alpha()
As far as I can tell, any transformations you do to the image retains the performance this method calls. E.G:
self.rotatedimage = pygame.transform.rotate(self.srcimage, angle).convert_alpha()
becomes redundant if you are using an image that has had convert_alpha() ran on it.
First, always use 'convert()' because it disables alpha which makes bliting faster.
Then only update the parts of the screen that need to be updated.
global rects
rects = []
rects.append(pygame.draw.line(screen, (0, 0, 0), (20, 20), (100, 400), 1))
pygame.display.update(rects) # pygame will only update those rects
Note:
When moving a sprite you have to include in the list the rect from their last position.
You could try using Psyco (http://psyco.sourceforge.net/introduction.html). It often makes quite a bit of difference.
There are a few things to consider for a well-performing Pygame application:
Ensure that the image Surface has the same format as the display Surface. Use convert() (or convert_alpha()) to create a Surface that has the same pixel format. This improves performance when the image is blit on the display, because the formats are compatible and blit does not need to perform an implicit transformation. e.g.:
surf = pygame.image.load('my_image.png').convert_alpha()
Do not load the images in the application loop. pygame.image.load is a very time-consuming operation because the image file must be loaded from the device and the image format must be decoded. Load the images once before the application loop, but use the images in the application loop.
If you have a static game map that consists of tiles, you can buy performance by paying with memory usage. Create a large Surface with the complete map. blit the area which is currently visible on the screen:
game_map = pygame.Surface((tile_size * columns, tile_size * rows))
for x in range(columns):
for y in range(rows):
tile_image = # image for this row and column
game_map.blit(tile_image , (x * tile_size, y * tile_size))
while game:
# [...]
map_sub_rect = screen.get_rect(topleft = (camera_x, camera_y))
screen.blit(game_map, (0, 0), map_sub_rect)
# [...]
If the text is static, the text does not need to be rendered in each frame. Create the text surface once at the beginning of the program or in the constructor of a class, and blit the text surface in each frame.
If the text is dynamic, it cannot even be pre-rendered. However, the most time-consuming is to create the pygame.font.Font/pygame.font.SysFont object. At the very least, you should avoid creating the font in every frame.
In a typical application you don't need all permutations of fonts and font sizes. You just need a couple of different font objects. Create a number of fonts at the beginning of the application and use them when rendering the text. For Instance. e.g.:
fontComic40 = pygame.font.SysFont("Comic Sans MS", 40)
fontComic180 = pygame.font.SysFont("Comic Sans MS", 180)

Categories

Resources