import pygame
#initialize the screen
pygame.init()
#create the screen
screen = pygame.display.set_mode((800, 700))
#tile and icon
pygame.display.set_caption("Space Invaders")
icon = pygame.image.load("spaceship.png")
pygame.display.set_icon(icon)
#Player
playerImg = pygame.image.load("player.png")
playerx = 370
playery = 600
playerx_change = 0.1
def player(x,y):
screen.blit(playerImg, (x,y))
running = True
while running:
screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#keystroke
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerx_change = -0.1
if event.type == pygame.K_RIGHT:
playerx_change = 0.1
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerx_change = 0
playerx += playerx_change
player(playerx,playery)
pygame.display.update()
my spaceship won't move towards right side when i press the riht key. but it will move towards the left side if i press the left key and no error is displayed in the terminal. i use the community version of visual studio 2019.
You need to change this:
if event.type == pygame.K_RIGHT:
to this ("type" --> "key"):
if event.key == pygame.K_RIGHT:
Related
Im working on this flappy bird pygame tutorial and when I tested the code the pipes spawned in too fast. I'm using a tutorial since I'm fairly new to python and would appreciate any help. Thanks. Here is the link to the tutorial website: https://github.com/clear-code- projects/FlappyBird_Python/blob/master/flappy.py
Here is the code I have so far.
import pygame
import sys
import os
from random import randint
def draw_floor():
screen.blit(floor_surface,(floor_x_pos,750))
screen.blit(floor_surface,(floor_x_pos + 576,750))
def create_pipe():
new_pipe = pipe_surface.get_rect(midtop = (288,375))
return new_pipe
def move_pipes(pipes):
for pipe in pipes:
pipe.centerx -= 5
return pipes
def draw_pipes(pipes):
for pipe in pipes:
if pipe.bottom >= 750:
screen.blit(pipe_surface,pipe)
pygame.init()
screen = pygame.display.set_mode((576,855))
clock = pygame.time.Clock()
# Game variables
gravity = 0.25
bird_movement = 0
bg_surface = pygame.transform.scale2x(pygame.image.load(os.path.join('imgs','bg.png')).convert_alpha())
floor_surface = pygame.transform.scale2x(pygame.image.load(os.path.join('imgs','base.png')).convert_alpha())
floor_x_pos = 0
bird_surface = pygame.transform.scale2x(pygame.image.load(os.path.join('imgs','bird2.png')).convert_alpha())
bird_rect = bird_surface.get_rect(center = (100,427))
pipe_surface = pygame.transform.scale2x(pygame.image.load(os.path.join('imgs','pipe.png')))
pipe_list = []
SPAWNPIPE = pygame.USEREVENT
pygame.time.set_timer(SPAWNPIPE,5000)
pipe_height = [300,500,700]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bird_movement = 0
bird_movement -= 12
if event.type == SPAWNPIPE:
pipe_list.extend(create_pipe())
# bird
screen.blit(bg_surface,(0,0))
bird_movement += gravity
bird_rect.centery += int(bird_movement)
screen.blit(bird_surface,bird_rect)
# pipes
pipe_list = move_pipes(pipe_list)
draw_pipes(pipe_list)
floor_x_pos -= 1
draw_floor()
if floor_x_pos <= -576:
floor_x_pos = 0
pygame.display.update()
clock.tick(120)`
Indent the SPAWNPIPE check:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bird_movement = 0
bird_movement -= 12
if event.type == SPAWNPIPE: # indent this
pipe_list.extend(create_pipe())
The issue is that once you get the first SPAWNPIPE event, the event.type condition for adding a new pipe becomes True.
However, due to improper indentation, that condition is repeatedly checked every frame until the next event is received. This means the code is continually spawning pipes every frame during this time.
Fix the indentation, to bring the pipe-event check back inside the event for-loop:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bird_movement = 0
bird_movement -= 12
if event.type == SPAWNPIPE: # <<-- HERE
pipe_list.extend(create_pipe()) # <<-- AND HERE
Which makes the SPAWNPIPE check be performed only when the event is actually received.
I have written a code for a game where you slide 15 tiles to set them in order. At the end of the game, I want the screen to just wait for 5 seconds before closing (also want to give a message but that later).
When the game ends, it first pauses and then shows the last move and then closes out. Is there a lag in the display. How do I make it complete the display, and then wait. I tried reading similar posts, but couldn't quite understand.
Here is the relevant code.
> def run_game(self):
"""Start the main loop for the game"""
self._shuffle_grid()
self._show_board()
game_over = False
while True:
change = self._check_events()
if change:
self._show_board()
game_over = self.end_of_game()
if game_over:
pygame.time.wait(5000)
sys.exit()
def _check_events(self):
# Watch for keyboard and mouse events
change = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
key = "U"
elif event.key == pygame.K_DOWN:
key = "D"
elif event.key == pygame.K_LEFT:
key = "L"
elif event.key == pygame.K_RIGHT:
key = "R"
if key == "U" or "D" or "L" or "R":
change = self.key_check(key)
return(change)
I actually tried this and it worked. I still don't know how to show a message and then wait 5 seconds. Working on it.
def celebrate(self):
""" does end of game thing"""
game_clock = pygame.time.Clock()
time_passed = pygame.time.get_ticks()
self._show_board()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
sys.exit()
if pygame.time.get_ticks() > time_passed + 5000:
sys.exit()
def run_game(self):
"""Start the main loop for the game"""
self._shuffle_grid()
self._show_board()
game_over = False
while True:
change = self._check_events()
if change:
game_over = self.end_of_game()
if not game_over:
self._show_board()
else:
self.celebrate()
When I run the following code, a white screen appears and then quickly disappears. I installed pygame on the VSCode terminal with pip3 (I am on mac) and now that I finally got it to import pygame, I get multiple errors for every function called such as "clock" or "pygame.KEYDOWN". They say "Module 'pygame' has no 'KEYDOWN' member" [E1101]. I also get an error with the "init" member.
I've seen other posts that tell me to copy and paste something into the json settings, but when I tried that I got even more errors.
#Game
#By Robert Smith
#Initialize python
import pygame
pygame.init()
#Set the screen
screen = pygame.display.set_mode((640, 480))
background = pygame.Surface(screen.get_size())
background.fill((255,255,255))
background = background.convert()
screen.blit(background, (0 , 0))
#Make the window exitable
for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop == False #close the window
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
mainloop = False
#Set the framerate
milliseconds = clock.tick(60)#DO NOT GO FASTER THAN THIS FRAMERATE
Try this:
keys = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop == False #close the window
elif event.type == keys[pygame.K_DOWN]:
if event.key == keys[pygame.K_ESCAPE]:
mainloop = False
And this:
milliseconds = pygame.time.Clock.tick(60)
I know it has been asked before but I couldn't get it to work, I'm using idle 3.6 and PyGame.
Here is the code.(I just started I have been watching some tutorials but apart from that I'm new to PyGame)
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
location += 1
You can use a boolean flag to keep track of which key was pressed and released. Something like:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
pressedRight = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
pressedRight = False
# Now in your game loop
if pressedRight:
location += 1
Basically, this code emulates a way to check if the key is pressed at the current time or not, allowing you to use continuous movement.
This code should make it so the black rectangle does continous movement while the K_LEFT or K_RIGHT are being pressed, but what happens instead is it just moves once it is pressed, and then once that happens, while the mouse is in motion over the window, it moves (when it shouldnt, it should only move when a key is being pressed).
So here's the code, hopefully you can help:
import pygame
pygame.init()
red = (255,0,0)
white = (255,255,255)
black = (0,0,0)
gameDisplay = pygame.display.set_mode((800,600))
pygame.display.set_caption('Slither')
gameExit = False
lead_x = 300
lead_y = 300
lead_x_change = 0
clock = pygame.time.Clock()
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
lead_x_change = -10
if event.key == pygame.K_RIGHT:
lead_x_change = 10
lead_x += lead_x_change
gameDisplay.fill(white)
pygame.draw.rect(gameDisplay, black, [lead_x, lead_y,10,10])
pygame.display.update()
clock.tick(30)
pygame.quit()
quit()
The reason is because you have indented all your code inside the event loop, meaning that you're only updating the screen and position of the rect when there are events in the event loop (such as moving the mouse, pressing a button, etc.).
Make sure you have your indention correct, like this:
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
lead_x_change = -10
if event.key == pygame.K_RIGHT:
lead_x_change = 10
# All code below was indented to much.
lead_x += lead_x_change
gameDisplay.fill(white)
pygame.draw.rect(gameDisplay, black, [lead_x, lead_y, 10, 10])
pygame.display.update()
clock.tick(30)
Also, it is usually good practice to be consistent when you're naming your variables. Preferably, gameDisplayand gameExit could be named game_display and game_exit for more continuity.