Pygame screen initialisation odd artefacts - pygame

I want to learn pygame and code small fun games with it. So I have started learning this library.
After running this code;
import pygame
from sys import exit
pygame.init()
display_surface = pygame.display.set_mode((800, 400))
pygame.display.set_caption("My Game")
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
# draw all our elements
# update everything
pygame.display.update()
I see a black screen but there are some artefacts in the screen, like this;
The screen I am talking about
In the Youtube tutorial I am following, the screen is solid black. I don't understand why my screen is different and has some green points in it. My computer works normally and if I restart the program or the computer nothing changes. The pattern is always the same. I can of course fill the display surface black with extra code, and then it works.
My question is, why do I have these points on the display surface in the first place? If someone is knowledgeable about the topic; what do these green lines mean?
I am just curious : )
MacOS Mojave 10.14.6

You must clear the screen with display_surface.fill(0):
run = True
while run :
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
display_surface.fill(0)
# draw all our elements
# update everything
pygame.display.update()
pygame.quit()
exit()

Related

How to preserve what is on the old screen after rescaling a pygame window?

I am trying to make a pygame window that can be resized but after resizing it just deletes everything on it. So I thought of a solution on my own.
pygame.init()
screen=pygame.display.set_mode((640,360),pygame.RESIZABLE)
clock=pygame.time.Clock()
screen.blit(somesurface,(0,0))
pygame.display.flip()
while True:
clock.tick(100)
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
sys.exit()
if event.type==pygame.VIDEORESIZE:
old=screen
screen=pygame.display.set_mode(event.size,pygame.RESIZABLE)
screen.blit(old,(0,0))
del old
pygame.display.flip()
But this doesnt work. The blitted surface just disappears after resizing.
I'm using python 3.8.5 and pygame 1.9.6
The main issue is that pygame.display.set_mode does not create a new surface object. It just resets the existing one. When you're 'saving' the old surface, you're just creating another reference to the same object. If you want to save the current screen surface, use surface.copy().
I updated your code to copy the screen then redraw the saved screen surface centered on the new screen. I also print the screen memory address before and after set_mode. You can see the screen address doesn't change.
import pygame
pygame.init()
screen=pygame.display.set_mode((640,360),pygame.RESIZABLE)
clock=pygame.time.Clock()
somesurface = pygame.Surface((640,360)) # new surface
somesurface.fill((255,255,255)) # fill white
pygame.draw.circle(somesurface,(100,100,255),(320,190),50) # draw blue circle
screen.blit(somesurface,(0,0)) # draw surface onto screen
pygame.display.flip()
while True:
clock.tick(100)
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
exit()
if event.type==pygame.VIDEORESIZE:
print(id(screen)) # memory address of screen object
old=screen.copy() # copy current screen to temp surface
screen=pygame.display.set_mode(event.size,pygame.RESIZABLE) # reset screen
print(id(screen)) # memory address of 'new' screen object, same address :(
screen.blit(old,((event.w-old.get_width())//2,(event.h-old.get_height())//2)) # draw back temp surface centered
del old # delete temp surface
pygame.display.flip()

How can I move a sprite image in pygame with my mouse?

Okay, I was given this project two weeks ago to create a simple chess game with the same rules as you would play in real life, and the project is due in a week. I really need help on how do I move the pawn or any chess piece up a space by using the mouse (not the keyboard).
Okay, so if you want to make the (lets just take a pawn for this example) move up y pixels, you will want your code to be something like this.
screen.blit(pawn,(x,y))
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# key goes down? look for that
if event.type == pygame.MOUSEBUTTONDOWN:
if event.key == pygame.K_UP:
keys[0] = True
then later in your code all of this of course in the main game loop
if keys[0]
y += 10
This requires some variables/images such as pawn, keys, and x/y to be defined. Cheers! also always check the docs before posting here.

My screen's black after I tried to implement collision and gravity in my game [duplicate]

i have started a new project in python using pygame and for the background i want the bottom half filled with gray and the top black. i have used rect drawing in projects before but for some reason it seems to be broken? i don't know what i am doing wrong. the weirdest thing is that the result is different every time i run the program. sometimes there is only a black screen and sometimes a gray rectangle covers part of the screen, but never half of the screen.
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAY=pygame.display.set_mode((800,800))
pygame.display.set_caption("thing")
pygame.draw.rect(DISPLAY, (200,200,200), pygame.Rect(0,400,800,400))
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
You need to update the display.
You are actually drawing on a Surface object. If you draw on the Surface associated to the PyGame display, this is not immediately visible in the display. The changes become visibel, when the display is updated with either pygame.display.update() or pygame.display.flip().
See pygame.display.flip():
This will update the contents of the entire display.
While pygame.display.flip() will update the contents of the entire display, pygame.display.update() allows updating only a portion of the screen to updated, instead of the entire area. pygame.display.update() is an optimized version of pygame.display.flip() for software displays, but doesn't work for hardware accelerated displays.
The typical PyGame application loop has to:
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (draw all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()
limit frames per second to limit CPU usage with pygame.time.Clock.tick
import pygame
from pygame.locals import *
pygame.init()
DISPLAY = pygame.display.set_mode((800,800))
pygame.display.set_caption("thing")
clock = pygame.time.Clock()
run = True
while run:
# handle events
for event in pygame.event.get():
if event.type == QUIT:
run = False
# clear display
DISPLAY.fill(0)
# draw scene
pygame.draw.rect(DISPLAY, (200,200,200), pygame.Rect(0,400,800,400))
# update display
pygame.display.flip()
# limit frames per second
clock.tick(60)
pygame.quit()
exit()
repl.it/#Rabbid76/PyGame-MinimalApplicationLoop See also Event and application loop
simply change your code to:
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAY=pygame.display.set_mode((800,800))
pygame.display.set_caption("thing")
pygame.draw.rect(DISPLAY, (200,200,200), pygame.Rect(0,400,800,400))
pygame.display.flip() #Refreshing screen
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
it should help

a white grid over a black background in pygame [duplicate]

i have started a new project in python using pygame and for the background i want the bottom half filled with gray and the top black. i have used rect drawing in projects before but for some reason it seems to be broken? i don't know what i am doing wrong. the weirdest thing is that the result is different every time i run the program. sometimes there is only a black screen and sometimes a gray rectangle covers part of the screen, but never half of the screen.
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAY=pygame.display.set_mode((800,800))
pygame.display.set_caption("thing")
pygame.draw.rect(DISPLAY, (200,200,200), pygame.Rect(0,400,800,400))
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
You need to update the display.
You are actually drawing on a Surface object. If you draw on the Surface associated to the PyGame display, this is not immediately visible in the display. The changes become visibel, when the display is updated with either pygame.display.update() or pygame.display.flip().
See pygame.display.flip():
This will update the contents of the entire display.
While pygame.display.flip() will update the contents of the entire display, pygame.display.update() allows updating only a portion of the screen to updated, instead of the entire area. pygame.display.update() is an optimized version of pygame.display.flip() for software displays, but doesn't work for hardware accelerated displays.
The typical PyGame application loop has to:
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (draw all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()
limit frames per second to limit CPU usage with pygame.time.Clock.tick
import pygame
from pygame.locals import *
pygame.init()
DISPLAY = pygame.display.set_mode((800,800))
pygame.display.set_caption("thing")
clock = pygame.time.Clock()
run = True
while run:
# handle events
for event in pygame.event.get():
if event.type == QUIT:
run = False
# clear display
DISPLAY.fill(0)
# draw scene
pygame.draw.rect(DISPLAY, (200,200,200), pygame.Rect(0,400,800,400))
# update display
pygame.display.flip()
# limit frames per second
clock.tick(60)
pygame.quit()
exit()
repl.it/#Rabbid76/PyGame-MinimalApplicationLoop See also Event and application loop
simply change your code to:
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAY=pygame.display.set_mode((800,800))
pygame.display.set_caption("thing")
pygame.draw.rect(DISPLAY, (200,200,200), pygame.Rect(0,400,800,400))
pygame.display.flip() #Refreshing screen
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
it should help

In Pygame, how can I save a screen image in headless mode?

I'm trying to capture a video of my game by saving each frame as an image than stitching them together using ffmpeg. I followed the example of these scripts:
http://www.pygame.org/wiki/DummyVideoDriver
http://www.pygame.org/wiki/HeadlessNoWindowsNeeded
Here's the basic logic of my code:
os.environ['SDL_VIDEODRIVER'] = 'dummy'
pygame.init()
pygame.display.set_mode((1,1))
screen = pygame.Surface((400, 400)).convert()
# screen becomes attribute of game object: game.screen
game = MyGame(screen)
while game.running:
game.update() # <--- updates game.screen
pygame.display.flip()
pygame.image.save(game.screen, 'frame-%03d.png' % (game.frame_num))
create_video_using_ffmpeg()
If I comment out the first line setting video driver to 'dummy', the images turn out as expected. But it opens a (small) window, so the script fails when run as a cronjob. With the line uncommented, I just get a series of blank black images.
Any idea what's going wrong?
I was able to work around this by drawing a rectangle to the base image surface serving as my screen:
os.environ['SDL_VIDEODRIVER'] = 'dummy'
pygame.init()
pygame.display.set_mode((1,1))
# surface alone wouldn't work so I needed to add a rectangle
screen = pygame.Surface((400, 400), pygame.SRCALPHA, 32)
pygame.draw.rect(screen, (0,0,0), (0, 0, 400, 400), 0)
# screen becomes attribute of game object: game.screen
game = MyGame(screen)
while game.running:
game.update() # <--- updates game.screen
pygame.display.flip()
pygame.image.save(game.screen, 'frame-%03d.png' % (game.frame_num))
create_video_using_ffmpeg()
Perhaps someone else can explain why this makes a difference. (Was I using the wrong surface parameters originally?)
This worked successfully as a cronjob.