Pygame unresponsive display - python

So I am attempting to create the foundation for a basic 2D python game with X and Y movement using a sprite.
However the display is unresposive despite the code here attempting to screen.fill and screen.blit
playerX = 50
playerY = 50
player = pygame.image.load("player.png")
width, height = 64*8, 64*8
screen=pygame.display.set_mode((width, height))
screen.fill((255,255,255))
screen.blit(player, (playerX, playerY))
Am I missing something important?

A minimal, typical PyGame application
has a game loop
has to handle the events, by either pygame.event.pump() or pygame.event.get().
has to update the Surface whuch represents the display respectively window, by either pygame.display.flip() or pygame.display.update().
See pygame.event.get():
For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.
See also Python Pygame Introduction
Minimal example: repl.it/#Rabbid76/PyGame-MinimalApplicationLoop
import pygame
pygame.init()
playerX = 50
playerY = 50
player = pygame.image.load("player.png")
width, height = 64*8, 64*8
screen = pygame.display.set_mode((width, height))
# main application loop
run = True
while run:
# event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# clear the display
screen.fill((255,255,255))
# draw the scene
screen.blit(player, (playerX, playerY))
# update the display
pygame.display.flip()

Related

I need a way to map two separate actions to mouse 1 in pygame

I am making a reaction time test (with a twist) in pygame.
I understand that the code in my event loop for mouse_clicks[0] (ie: left mouse button) can register whether or not you've clicked in the area for a small circle. However, I wish to have another action for left mouse button once I figure out how to code the event loop for when a big circle flashes on the screen. So, pretty much the same action for mouse_clicks[0] but with "if math.sqrt(sqx + sqy) < CIRCLE_RADIUS_LARGE". How could I achieve this using the pygame event loop. This is my first independent pygame so any help would be greatly appreciated. Much love, cLappy.
while running:
Clock.tick(FPS)
event_list = pygame.event.get()
mouse_clicks = pygame.mouse.get_pressed()
for event in event_list:
if mouse_clicks[2]:
pygame.display.update()
SCREEN.fill(BLACK)
circle(BLUE, CIRCLE_RADIUS_SMALL)
if mouse_clicks[0]:
x = pygame.mouse.get_pos()[0]
y = pygame.mouse.get_pos()[1]
sqx = (x - 640) ** 2
sqy = (y - 360) ** 2
if math.sqrt(sqx + sqy) < CIRCLE_RADIUS_SMALL:
reset_circle(BLUE, CIRCLE_RADIUS_SMALL)
pygame.display.update()
if event.type == pygame.QUIT:
running = False
You must draw the objects in the application loop, but not in the event loop. The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
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 (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()
Minimal example
import pygame, math
pygame.init()
SCREEN = pygame.display.set_mode((400, 400))
CIRCLE_RADIUS_SMALL = 20
circles = []
clock = pygame.time.Clock()
running = True
while running:
clock.tick(100)
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
circles.append(event.pos)
if event.button == 3:
for center in circles[:]:
dx = center[0] - event.pos[0]
dy = center[1] - event.pos[1]
if math.sqrt(dx*dx + dy*dy) < CIRCLE_RADIUS_SMALL:
circles.remove(center)
SCREEN.fill("black")
for center in circles:
pygame.draw.circle(SCREEN, "blue", center, CIRCLE_RADIUS_SMALL)
pygame.display.update()

Scale Everything On Pygame Display Surface

So I'm making a 2D pixel art game in pygame and as you could assume, all my sprite textures appear very small. I'm wondering if there's a way I can globally scale everything up in my game without either having to scale each sprite up individually or messing up the coordinates. Every sprite will move on a grid: one unit is 16x16 pixels and when my player sprite moves, for example, it will just move over in a direction 16 pixels.
Here's my main script:
import sys
from pygame.locals import *
import pygame
from game.sprites import Ghost
pygame.init()
WINDOW_WIDTH = 640
WINDOW_HEIGHT = 640
DES_WIDTH = 64
DES_HEIGHT = 64
COL_BG = (46, 48, 55)
COL_FG = (235, 229, 206)
X = 1000
Y = 1000
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Through The Doors")
running = True
paused = False
# INITIALIZE SPRITES
player = Ghost()
all_sprites = pygame.sprite.Group()
all_sprites.add(player)
clock = pygame.time.Clock()
while running:
clock.tick(30)
if not paused:
win.fill(COL_BG)
all_sprites.update()
all_sprites.draw(win)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
player.go_right()
elif keys[pygame.K_LEFT]:
player.go_left()
elif keys[pygame.K_UP]:
player.go_up()
elif keys[pygame.K_DOWN]:
player.go_down()
pygame.display.flip()
pygame.quit()
I do have more sprites I am going to load in, but I would like to resolve the scaling issue first.
I'm wondering if there's a way I can globally scale everything up in my game without either having to scale each sprite up individually [...]"
No there is no way. You have to scale each coordinate, each size and each surface individually. PyGame is made for images (Surfaces) and shapes in pixel units. Anyway up scaling an image will result in either a fuzzy, blurred or jagged (Minecraft) appearance.
Is there a way I could make a separate surface and just put that on top of the base window surface, and just scale that?
Yes of course.
Create a Surface to draw on (win). Use pygame.transform.scale() or pygame.transform.smoothscale() to scale it to the size of the window and blit it to the actual display Surface (display_win):
display_win = pygame.display.set_mode((WINDOW_WIDTH*2, WINDOW_HEIGHT*2))
win = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT))
while running:
# [...]
if not paused:
win.fill(COL_BG)
all_sprites.update()
all_sprites.draw(win)
# [...]
scaled_win = pygame.transform.smoothscale(win, display_win.get_size())
# or scaled_win = pygame.transform.scale(win, display_win.get_size())
display_win.blit(scaled_win, (0, 0))
pygame.display.flip()
Minimal example: repl.it/#Rabbid76/PyGame-UpScaleDisplay

Pygame sprite constantly redrawn to screen and not moving

I can't see what's wrong with the below code. All I want to do is make the frog move across the screen, but it is simply redrawing many, many frogs all one pixel apart. How do I move the frog rather than just draw it again?
import pygame
from pygame.constants import *
pygame.init()
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
class Frog(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.transform.scale(pygame.image.load('frog.png'), (64, 64))
self.rect = self.image.get_rect()
self.dx = 1
def update(self, *args):
self.rect.x += self.dx
running = True
frog = Frog()
entities = pygame.sprite.Group()
entities.add(frog)
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
entities.update()
entities.draw(screen)
That is how you do it in Pygame, you just redraw objects every iteration to give the illusion that they're moving but you must cover up the previous drawn objects by filling your window with a solid color e.g.
screen.fill((255, 255, 255))
This should be at the start of your game loop so you have a fresh canvas for drawing your objects each iteration.
while running:
screen.fill((255,255,255))
for event in pygame.event.get():
if event.type == QUIT:
running = False
entities.update()
entities.draw(screen)
pygame.display.update()
You may have to use the pygame.display.update() function to update the whole screen rather than just your entities.

PyGame Resolution Support [duplicate]

So I'm making a 2D pixel art game in pygame and as you could assume, all my sprite textures appear very small. I'm wondering if there's a way I can globally scale everything up in my game without either having to scale each sprite up individually or messing up the coordinates. Every sprite will move on a grid: one unit is 16x16 pixels and when my player sprite moves, for example, it will just move over in a direction 16 pixels.
Here's my main script:
import sys
from pygame.locals import *
import pygame
from game.sprites import Ghost
pygame.init()
WINDOW_WIDTH = 640
WINDOW_HEIGHT = 640
DES_WIDTH = 64
DES_HEIGHT = 64
COL_BG = (46, 48, 55)
COL_FG = (235, 229, 206)
X = 1000
Y = 1000
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Through The Doors")
running = True
paused = False
# INITIALIZE SPRITES
player = Ghost()
all_sprites = pygame.sprite.Group()
all_sprites.add(player)
clock = pygame.time.Clock()
while running:
clock.tick(30)
if not paused:
win.fill(COL_BG)
all_sprites.update()
all_sprites.draw(win)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
player.go_right()
elif keys[pygame.K_LEFT]:
player.go_left()
elif keys[pygame.K_UP]:
player.go_up()
elif keys[pygame.K_DOWN]:
player.go_down()
pygame.display.flip()
pygame.quit()
I do have more sprites I am going to load in, but I would like to resolve the scaling issue first.
I'm wondering if there's a way I can globally scale everything up in my game without either having to scale each sprite up individually [...]"
No there is no way. You have to scale each coordinate, each size and each surface individually. PyGame is made for images (Surfaces) and shapes in pixel units. Anyway up scaling an image will result in either a fuzzy, blurred or jagged (Minecraft) appearance.
Is there a way I could make a separate surface and just put that on top of the base window surface, and just scale that?
Yes of course.
Create a Surface to draw on (win). Use pygame.transform.scale() or pygame.transform.smoothscale() to scale it to the size of the window and blit it to the actual display Surface (display_win):
display_win = pygame.display.set_mode((WINDOW_WIDTH*2, WINDOW_HEIGHT*2))
win = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT))
while running:
# [...]
if not paused:
win.fill(COL_BG)
all_sprites.update()
all_sprites.draw(win)
# [...]
scaled_win = pygame.transform.smoothscale(win, display_win.get_size())
# or scaled_win = pygame.transform.scale(win, display_win.get_size())
display_win.blit(scaled_win, (0, 0))
pygame.display.flip()
Minimal example: repl.it/#Rabbid76/PyGame-UpScaleDisplay

How do I make an image maintain its location on my window display no matter what size monitor an individual user may have in python? [duplicate]

So I'm making a 2D pixel art game in pygame and as you could assume, all my sprite textures appear very small. I'm wondering if there's a way I can globally scale everything up in my game without either having to scale each sprite up individually or messing up the coordinates. Every sprite will move on a grid: one unit is 16x16 pixels and when my player sprite moves, for example, it will just move over in a direction 16 pixels.
Here's my main script:
import sys
from pygame.locals import *
import pygame
from game.sprites import Ghost
pygame.init()
WINDOW_WIDTH = 640
WINDOW_HEIGHT = 640
DES_WIDTH = 64
DES_HEIGHT = 64
COL_BG = (46, 48, 55)
COL_FG = (235, 229, 206)
X = 1000
Y = 1000
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Through The Doors")
running = True
paused = False
# INITIALIZE SPRITES
player = Ghost()
all_sprites = pygame.sprite.Group()
all_sprites.add(player)
clock = pygame.time.Clock()
while running:
clock.tick(30)
if not paused:
win.fill(COL_BG)
all_sprites.update()
all_sprites.draw(win)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
player.go_right()
elif keys[pygame.K_LEFT]:
player.go_left()
elif keys[pygame.K_UP]:
player.go_up()
elif keys[pygame.K_DOWN]:
player.go_down()
pygame.display.flip()
pygame.quit()
I do have more sprites I am going to load in, but I would like to resolve the scaling issue first.
I'm wondering if there's a way I can globally scale everything up in my game without either having to scale each sprite up individually [...]"
No there is no way. You have to scale each coordinate, each size and each surface individually. PyGame is made for images (Surfaces) and shapes in pixel units. Anyway up scaling an image will result in either a fuzzy, blurred or jagged (Minecraft) appearance.
Is there a way I could make a separate surface and just put that on top of the base window surface, and just scale that?
Yes of course.
Create a Surface to draw on (win). Use pygame.transform.scale() or pygame.transform.smoothscale() to scale it to the size of the window and blit it to the actual display Surface (display_win):
display_win = pygame.display.set_mode((WINDOW_WIDTH*2, WINDOW_HEIGHT*2))
win = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT))
while running:
# [...]
if not paused:
win.fill(COL_BG)
all_sprites.update()
all_sprites.draw(win)
# [...]
scaled_win = pygame.transform.smoothscale(win, display_win.get_size())
# or scaled_win = pygame.transform.scale(win, display_win.get_size())
display_win.blit(scaled_win, (0, 0))
pygame.display.flip()
Minimal example: repl.it/#Rabbid76/PyGame-UpScaleDisplay

Categories