New to pygame, drew a rectangle, why can't I move it? - python

This is my code:
import pygame, sys
from pygame.locals import *
pygame.init()
window = pygame.display.set_mode((800, 600))
pygame.display.set_caption('window')
black = (0,0,0)
white = (255, 255, 255)
logo = pygame.image.load('logo.png').convert_alpha()
clock = pygame.time.Clock()
# Sprites
m1 = pygame.image.load('m1.png').convert_alpha()
m2 = pygame.image.load('m2.png').convert_alpha()
mci = 1
x, y = 0, 0
run = True
while run:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_LEFT:
x -= 10
if event.type == pygame.K_RIGHT:
x += 10
if event.type == pygame.K_UP:
y -= 10
if event.type == pygame.K_DOWN:
y += 10
window.fill(white)
pygame.draw.rect(window, black,(x,y, 50, 50))
pygame.display.flip()
clock.tick(10)
Everything shows up, but I can't move the rectangle with my arrow keys, and I always get an error after I quit out of it, help.. Thanks in advance!
P.S I'm obviously copying from a tutorial, but i'm not sure what I've done wrong?

As you worked out, you need to use event.key == .... You probably also want to watch the nesting of your loop, currently you have:
while running:
for event in list_of_events:
process_event
draw_to_screen
wait_a_while
This caused a problem in another question (https://stackoverflow.com/a/13866804/2372604). What you probably want is something more like:
while running:
for event in list_of_events:
process_event
draw_to_screen
wait_a_while
You might also want to change pygame.quit(); sys.exit() to run = false and then add pygame.quit() at the end of the program.

The mistake what I wrote event.type instead of event.key.

Related

Confused with movement in pygame

I am trying to make a small game in pygame. The player is the left hand red rectangle (if you run it) and I am just trying to make the rocket variable move to the left quickly. Whenever I run the program if I press any key or move my mouse it moves the rocket.
Here is the code:
import pygame,sys,random
pygame.init()
pygame.key.set_repeat(1, 100)
size=width,height=1280,830
screen = pygame.display.set_mode(size)
black = [0, 0, 0]
white = [255, 255, 255]
sky_blue = ((0,255,255))
red = ((255,0,0))
font = pygame.font.SysFont("Arial",14)
rocket=pygame.Rect(1200,350,150,50)
player= pygame.Rect(250,350,250,50)
hull=100
player_speed=100
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type==pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
player_speed=player_speed+100
if event.key == pygame.K_LEFT:
player_speed=player_speed-100
if event.key == pygame.K_UP:
player.top=player.top-50
if event.key == pygame.K_DOWN:
player.top=player.top+50
if player_speed>1000:
player_speed=1000
if player_speed<100:
player_speed=100
if player.top<0:
player.top=0
elif player.bottom>height:
player.bottom=height
#rocket code
if player.colliderect(rocket):
hull=hull-100
if player_speed>99:
rocket.right=rocket.right-5
screen.fill(sky_blue)
pygame.draw.rect(screen,red,player)
pygame.draw.rect(screen,red,rocket)
renderedText = font.render("Speed: "+str(player_speed),1,black)
screen.blit(renderedText, (width/2+50,10))
if hull<1:
renderedText = font.render("GAME OVER",1,black)
screen.blit(renderedText, (width/2+500,500))
pygame.display.flip()
pygame.time.wait(10)
You indentation is incorrect which is causing a logic error.
if player_speed>1000:
...
rocket.right=rocket.right-5
The code between these lines need to be one indent lower. Else this code will only be run when there is a event. Since the for loop will skip execution of any code within if there is no events.

pygame.display.update(); pygame.error: video system not initialized [duplicate]

This question already has answers here:
pygame.error: video system not initialized
(5 answers)
why is the exit window button work but the exit button in the game does not work?
(1 answer)
Closed 1 year ago.
Here is my underdeveloped pygame ping-pong game, but my sprites(player&opponent) ain't moving, on giving a keyboard input. And when I quit the program, it yells an error pygame.error: video system not initialized. My pygame is the latest 1.9.6 version with all the files up-to-daee. However, I am certain that pygame.display is generating this error, but I even tried pygame.display.init() and that too didn't worked :(
import pygame
# Initialization
pygame.init()
# Screen, Caption and Icon
width = 800
height = 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('PyGame')
icon = pygame.image.load('ping-pong.png')
pygame.display.set_icon(icon)
# Create Rects
player = pygame.Rect((5, 230), (10, 120))
opponent = pygame.Rect((785, 230), (10, 120))
# Game Variables
playerY_change = 0
opponentY_change = 0
game_over = False
while not game_over:
# Coloring the Screen
screen.fill((27, 35, 43))
# Draw Rects
pygame.draw.rect(screen, (255,255,255), player)
pygame.draw.rect(screen, (255,255,255), opponent)
# Managing Events
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
pygame.quit()
if event.type == pygame.KEYUP:
if event.type == pygame.K_UP:
opponentY_change -= 3
if event.type == pygame.K_DOWN:
opponentY_change += 3
if event.type == pygame.K_w:
playerY_change -= 3
if event.type == pygame.K_s:
playerY_change += 3
if event.type == pygame.KEYDOWN:
if (event.type == pygame.K_UP) or (event.type == pygame.K_DOWN):
opponentY_change = 0
if (event.type == pygame.K_w) or (event.type == pygame.K_s):
playerY_change = 0
# Moving my sprites
player.y += playerY_change
opponent.y += opponentY_change
# Updating the screen on every iter of loop
pygame.display.update()
Here, you have two different problems :
First the movement is not working because to differentiate the keys, you use event.type to compare where it should be event.key. Try with for example :
if event.key == pygame.K_UP:
opponentY_change -= 3
The other problem is that when the game is over, you use pygame.quit() but later on the loop, you use pygame.display.update(). You should put the display update at the beginning of the loop.

Python 3.2 W/ Pygame Crashes

Well, I was happy starting on Pygame with a bit of knowledge on python, But while i was following some starter tutorials i noticed that, At the moment of running my code the Pygame window didn't see to respond, so i put some "print" commands to see how far did it get, I noticed that it stopped on the Loop, Any ideas on how i can fix it? I will leave the code around here
import pygame
pygame.init()
print("First Fase")
win = pygame.display.set_mode((500,500))
pygame.display.set_caption("Test")
print("Second Fase")
x = 50
y =50
width = 40
height = 60
vel = 7
print("Third Fase")
done = False
while not done:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == KEYDOWN:
if event.key == K_ESC:
done = True
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.display.update()
print("NoErrors")
It has to be pygame.KEYDOWN and pygame.K_ESC rather than KEYDOWN and K_ESC.
But fist of all you have to respect the Indentation. In the following code the loops are not nested:
done = False
while not done:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
The for loop is not in the while, it is a separate loop after the while loop.
You have to format your code like this:
import pygame
pygame.init()
print("First Fase")
win = pygame.display.set_mode((500,500))
pygame.display.set_caption("Test")
print("Second Fase")
x = 50
y =50
width = 40
height = 60
vel = 7
print("Third Fase")
done = False
while not done:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESC:
done = True
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.display.update()
print("NoErrors")

pygame moving left and right issue

I have started making something on pygame but I have encountered an issue when moving left or right. if I quickly change from pressing the right arrow key to pressing the left one and also let go of the right one the block just stops moving. this is my code
bg = "sky.jpg"
ms = "ms.png"
import pygame, sys
from pygame.locals import *
x,y = 0,0
movex,movey=0,0
pygame.init()
screen=pygame.display.set_mode((664,385),0,32)
background=pygame.image.load(bg).convert()
mouse_c=pygame.image.load(ms).convert_alpha()
m = 0
pygame.event.pump()
while 1:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type==KEYDOWN:
if event.key==K_LEFT:
movex =-0.5
m = m + 1
if event.key==K_RIGHT:
movex=+0.5
m = m + 1
elif event.type == KEYUP:
if event.key==K_LEFT and not event.key==K_RIGHT:
movex = 0
if event.key==K_RIGHT and not event.key==K_LEFT:
movex =0
x+=movex
y=200
screen.blit(background, (0,0))
screen.blit(mouse_c,(x,y))
pygame.display.update()
is there a way I can change this so if the right arrow key is pressed and the left arrow key is released that it will go right instead of stopping?
P.S
I am still learning pygame and am very new to the module. I'm sorry if this seems like a stupid question but i couldn't find any answers to it.
Your problem is that when you test the KEYDOWN events with
if event.key==K_LEFT and not event.key==K_RIGHT:
you always get True, because when event.key==K_LEFT is True,
it also always is not event.key==K_RIGHT (because the key of the event is K_LEFT after all).
My approach to this kind of problem is to separate
the intent from the action. So, for the key
events, I would simply keep track of what action
is supposed to happen, like this:
moveLeft = False
moveRight = False
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_LEFT: moveLeft = True
if event.key == K_RIGHT: moveRight = True
elif event.type == KEYUP:
if event.key == K_LEFT: moveLeft = False
if event.key == K_RIGHT: moveRight = False
Then, in the "main" part of the loop, you can
take action based on the input, such as:
while True:
for event in pygame.event.get():
...
if moveLeft : x -= 0.5
if moveRight : x += 0.5
the problem is that you have overlapping key features; If you hold down first right and then left xmove is first set to 1 and then changes to -1. But then you release one of the keys and it resets xmove to 0 even though you are still holding the other key. What you want to do is create booleans for each key. Here is an example:
demo.py:
import pygame
window = pygame.display.set_mode((800, 600))
rightPressed = False
leftPressed = False
white = 255, 255, 255
black = 0, 0, 0
x = 250
xmove = 0
while True:
window.fill(white)
pygame.draw.rect(window, black, (x, 300, 100, 100))
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
rightPressed = True
if event.key == pygame.K_LEFT:
leftPressed = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
rightPressed = False
if event.key == pygame.K_LEFT:
leftPressed = False
xmove = 0
if rightPressed:
xmove = 1
if leftPressed:
xmove = -1
x += xmove
pygame.display.flip()
One way could be to create a queue that keeps track of the button that was pressed last. If we press the right arrow key we'll put the velocity first in the list, and if we then press the left arrow key we put the new velocity first in the list. So the button that was pressed last will always be first in the list. Then we just remove the button from the list when we release it.
import pygame
pygame.init()
screen = pygame.display.set_mode((720, 480))
clock = pygame.time.Clock()
FPS = 30
rect = pygame.Rect((350, 220), (32, 32)) # Often used to track the position of an object in pygame.
image = pygame.Surface((32, 32)) # Images are Surfaces, so here I create an 'image' from scratch since I don't have your image.
image.fill(pygame.Color('white')) # I fill the image with a white color.
velocity = [0, 0] # This is the current velocity.
speed = 200 # This is the speed the player will move in (pixels per second).
dx = [] # This will be our queue. It'll keep track of the horizontal movement.
while True:
dt = clock.tick(FPS) / 1000.0 # This will give me the time in seconds between each loop.
for event in pygame.event.get():
if event.type == pygame.QUIT:
raise SystemExit
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
dx.insert(0, -speed)
elif event.key == pygame.K_RIGHT:
dx.insert(0, speed)
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
dx.remove(-speed)
elif event.key == pygame.K_RIGHT:
dx.remove(speed)
if dx: # If there are elements in the list.
rect.x += dx[0] * dt
screen.fill((0, 0, 0))
screen.blit(image, rect)
pygame.display.update()
# print dx # Uncomment to see what's happening.
You should of course put everything in neat functions and maybe create a Player class.
I know my answer is pretty late but im new to Pygame to and for beginner like me doing code like some previous answer is easy to understand but i have a solution to.I didn`t use the keydown line code, instead i just put the moving event code nested in the main game while loop, im bad at english so i give you guy an example code.
enter code here
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.K_ESCAPE:
run = False
win.blit(bg, (0, 0))
pressed = pygame.key.get_pressed()
if pressed[pygame.K_LEFT]:
x -= 5
if pressed[pygame.K_RIGHT]:
x += 5
if pressed[pygame.K_UP]:
y -= 5
if pressed[pygame.K_DOWN]:
y += 5
win.blit(image,(x,y))
pygame.display.update()
pygame.quit()
This will make the image move rapidly without repeating pushing the key, at long the code just in the main while loop with out inside any other loop.

pygame.key.get_pressed() - doesn't work - pygame.error: video system not initialized

I have two problems with my program:
When I close my program it has error: keys = pygame.key.get_pressed() pygame.error: video system not initialized
Square moves while I'm pressing 'd' and when I press something (or move mouse)
Important part of code is:
import pygame
from pygame.locals import*
pygame.init()
screen = pygame.display.set_mode((1200, 700))
ticket1 = True
# ...
c = 550
d = 100
# ...
color2 = (250, 20, 20)
while ticket1 == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
ticket1 = False
pygame.quit()
pygame.display.quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_d]:
c += 1
# ...
screen.fill((255, 250, 245))
pygame.draw.rect(screen, color2, pygame.Rect(c, d, 50, 75))
pygame.display.flip()
If I write keys = pygame.key.get_pressed() in just while loop it doesn't have error but it seems slower.
I also have another error: pygame.error: display Surface quit, but I always and in all my pygame programs have it and it isn'n so important but other things are important.
1.--------------
After pygame.quit() you don't need pygame.display.quit() but sys.exit().
pygame.quit() doesn't exit program so program still try to call screen.fill() and other function below pygame.quit()
Or you have to put pygame.quit() outside while ticket == True: (and then you don't need sys.exit())
You can use while ticket1: in place of while ticket == True: - it is more pythonic.
while ticket1: # it is more pythonic
for event in pygame.event.get():
if event.type == pygame.QUIT:
ticket1 = False
keys = pygame.key.get_pressed()
if keys[pygame.K_d]:
c += 1
# ...
screen.fill((255, 250, 245))
pygame.draw.rect(screen, color2, pygame.Rect(c, d, 50, 75))
pygame.display.flip()
pygame.quit()
2.--------------
if keys[pygame.K_d]: c += 1 is inside for event loop so it is call only when event is happend - when mouse is moving, when key is pressed or "unpressed". Move it outside of for event loop.
while ticket1: # it is more pythonic
for event in pygame.event.get():
if event.type == pygame.QUIT:
ticket1 = False
keys = pygame.key.get_pressed()
# outside of `for event` loop
if keys[pygame.K_d]:
c += 1
# ...
screen.fill((255, 250, 245))
pygame.draw.rect(screen, color2, pygame.Rect(c, d, 50, 75))
pygame.display.flip()
pygame.quit()
Some people do it without get_pressed()
# clock = pygame.time.Clock()
move_x = 0
while ticket1 == True:
# events
for event in pygame.event.get():
if event.type == pygame.QUIT:
ticket1 = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
ticket1 = False
elif event.key == pygame.K_d:
move_x = 1
elif event.type == pygame.KEYUP:
if event.key == pygame.K_d:
move_x = 0
# variable modification
c += move_x
# ...
# draws
screen.fill((255, 250, 245))
pygame.draw.rect(screen, color2, pygame.Rect(c, d, 50, 75))
pygame.display.flip()
# 60 FPS (Frame Per Second) to make CPU cooler
# clock.tick(60)
pygame.quit()
BTW: use pygame.time.Clock() to get the same FPS on fast and slow computers. Without FPS program refresh screen thousends times per second so CPU is busy and hot.
If you use FPS you have to add to c bigger value to get the same speed then before.

Categories