How can I add a sprite when no keys are pressed? - python
How can I add a sprite when no keys are pressed? I have each four directions covered when the arrow keys are pressed but when they are released the sprite goes obviously but cant think of how to add it. I tried adding else statements and other things best thing i got was the standing forward sprite being underneath the others but cant seem to get it to go when one of the arrow keys is pressed and return when they are relased.
Any help appreciated. Thanks in advance.
my code:
import pygame
pygame.init()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (200, 0, 0)
GREEN = (0, 200, 0)
BLUE = (0, 0, 200)
# background
background = pygame.image.load('Playing Game state 2.png')
# character
standingforward = pygame.image.load('standingforward.png')
standingdownward = pygame.image.load('standingdownwards.png')
standingleft = pygame.image.load('standingleft.png')
standingright = pygame.image.load('standingright.png')
# player variables
x = 375
y = 525
w = 50
h = 50
vel = 0.5
screenWidth = 800
screenHeight = 575
screen = pygame.display.set_mode((screenWidth, screenHeight))
pygame.display.set_caption("FROGGER")
sprite = pygame.draw.rect
running = True
while running:
# sprites
screen.blit(background, (0, 0))
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
screen.blit(standingleft, (x, y))
if keys[pygame.K_RIGHT]:
screen.blit(standingright, (x, y))
if keys[pygame.K_DOWN]:
screen.blit(standingdownward, (x, y))
if keys[pygame.K_UP]:
screen.blit(standingforward, (x, y))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.flip()
# controls
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if x < 0:
x = 0
if keys[pygame.K_RIGHT]:
x += vel
if x > screenWidth-w:
x = screenWidth-w
if keys[pygame.K_UP]:
y -= vel
if y < 0:
y = 0
if keys[pygame.K_DOWN]:
y += vel
if y > screenHeight-h:
y = screenHeight-h
pygame.quit()
Add a variable that refers to the current image. Change the variable when a key is pressed. Draw the current image in the application loop:
current_image = standingright
running = True
while running:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
current_image = standingleft
if keys[pygame.K_RIGHT]:
current_image = standingright
if keys[pygame.K_DOWN]:
current_image = standingdownward
if keys[pygame.K_UP]:
current_image = standingforward
screen.blit(background, (0, 0))
screen.blit(current_image, (x, y))
# [...]
Related
How do I make a bullet shoot and hit system? [duplicate]
This question already has answers here: How can i shoot a bullet with space bar? (1 answer) How do I detect collision in pygame? (5 answers) How do I stop more than 1 bullet firing at once? (1 answer) Closed 1 year ago. This program currently makes two squares appear on the screen when you press start, the one on the left is controlled using WASD whilst the one on the right is controlled using the arrow keys. I want to make it so that when you click spacebar, the square on the left shoots a red rectangle (the bullet) to the right of the screen and if it hits the other square, then the health goes down by one. If it doesn't hit the other square, the bullet hits the edge of the screen and disappears (I would also like the other square to do this too but the other way around and instead of pressing space you press right control). The health variable for both squares is on lines 9 and 10. Can somebody please tell me how to do this? Full Code (The two key presses that I would like to make the chosen character shoot are lines 60 and 72): import pygame import sys import os pygame.init() FPS = 60 HEALTH_L = 3 HEALTH_R = 3 start_smallfont = pygame.font.SysFont('Corbel', 45) start_text = start_smallfont.render('Start', True, (255, 255, 255)) rect_smallfont = pygame.font.SysFont('Corbel', 33) rect_text = rect_smallfont.render('You', True, (255, 255, 255)) x = 630 y = 325 x2 = 170 y2 = 325 vel = 0.1 startWIDTH, startHEIGHT = 170, 80 screenWIDTH, screenHEIGHT = 800, 720 WIN = pygame.display.set_mode((screenWIDTH, screenHEIGHT)) pygame.display.set_caption(":D") def main(): clock = pygame.time.Clock() run = True while run: clock.tick(FPS) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False pygame.quit() if event.type == pygame.MOUSEBUTTONDOWN: if 800/2-85 <= mouse[0] <= 800/2-85+startWIDTH and 720/2-40 <= mouse[1] <= 720/2-40+startHEIGHT: clock.tick(FPS) run = False while True: global x, y, x2, y2, movingx for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() WIN.fill((0, 0, 0)) keys = pygame.key.get_pressed() if keys[pygame.K_LEFT] and x > vel: x -= vel if keys[pygame.K_RIGHT] and x < screenWIDTH - 50 - vel: x += vel if keys[pygame.K_UP] and y > vel: y -= vel if keys[pygame.K_DOWN] and y < screenHEIGHT - 50 - vel: y += vel if keys[pygame.K_SPACE]: #PUT BULLET FUNCTION HERE if keys[pygame.K_a] and x2 > vel: x2 -= vel if keys[pygame.K_d] and x2 < screenWIDTH - 50 - vel: x2 += vel if keys[pygame.K_w] and y2 > vel: y2 -= vel if keys[pygame.K_s] and y2 < screenHEIGHT - 50 - vel: y2 += vel if keys[pygame.K_RCTRL]: #PUT BULLET FUNCTION HERE pygame.draw.rect(WIN, (255, 0, 0), (x, y, 50, 50)) pygame.draw.rect(WIN, (255, 0, 0), (x2, y2, 50, 50)) pygame.display.update() mouse = pygame.mouse.get_pos() if 800/2-85 <= mouse[0] <= 800/2-85+startWIDTH and 720/2-40 <= mouse[1] <= 720/2-40+startHEIGHT: pygame.draw.rect(WIN, (255, 91, 91), (800/2-85, 720/2-40, startWIDTH, startHEIGHT)) else: pygame.draw.rect(WIN, (255, 0, 0), (800/2-85, 720/2-40, startWIDTH, startHEIGHT)) WIN.blit(start_text, (800/2-85+42,720/2-40+20)) pygame.display.update() if __name__ == "__main__": main()
Collision for Pygame Game Map
I am trying to make a maze game in Pygame but am unable to achieve collision for the 1 (maze wall) in the array. I tried to put the collision detection in the loop creating the map but it is not working. I also put the collision detection in the main loop but only the top left rect detected the collision, not all the 1 rects. How would I go about fixing this? Thank you! import pygame pygame.init() screen = pygame.display.set_mode((700,700)) pygame.display.set_caption("Game") speed = 20 x = 200 y = 600 def game_map(): global rect_one surface = pygame.Surface((100, 100), pygame.SRCALPHA) rect_one = pygame.draw.rect(surface, (0, 0, 255), (0, 0, 50, 50)) global rect_two surface_one = pygame.Surface((80, 80), pygame.SRCALPHA) rect_two = pygame.draw.rect(surface_one, (255, 255, 255), (0, 0, 50, 50)) tileX = 0 tileY = 0 global tile_list tile_list = [] map = [ [1,1,1,1,1,1,1,1,1,1,1,1,1], [1,0,0,0,1,0,1,0,0,0,0,0,1], [1,0,1,0,0,0,1,0,1,1,1,0,1], [1,0,0,0,1,1,1,0,0,0,0,0,1], [1,0,1,0,0,0,0,0,1,1,1,0,1], [1,0,1,0,1,1,1,0,1,0,0,0,1], [1,0,1,0,1,0,0,0,1,1,1,0,1], [1,0,1,0,1,1,1,0,1,0,1,0,1], [1,0,0,0,0,0,0,0,0,0,1,0,1], [1,1,1,1,1,1,1,1,1,1,1,1,1] ] for y, row in enumerate(map): tileX = 0 for x, cell in enumerate(row): image = surface if cell == 1 else surface_one screen.blit(image, [x*50, y*50]) tile_list.append(rect_one) pygame.display.update() def player(): player = pygame.draw.rect(screen, (255,0,0), (x, y, 20, 20)) for i in tile_list: if player.colliderect(i): print("hello") loop = True while loop: pygame.time.delay(100) for event in pygame.event.get(): if event.type == pygame.QUIT: loop = False #player controls keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: x -= speed if keys[pygame.K_RIGHT]: x += speed if keys[pygame.K_UP]: y -= speed if keys[pygame.K_DOWN]: y += speed screen.fill((255,255,255)) game_map() player() pygame.display.update() pygame.quit()
Your tile_list only contains one Rect multiple times. I simplified your code a little bit and use a Rect with the correct coordinates for each 1 in your map. Also note the comments: import pygame pygame.init() screen = pygame.display.set_mode((700,700)) pygame.display.set_caption("Game") speed = 10 player_x = 200 player_y = 600 # Use a constant. There's not need to make big Surfaces and then draw a smaller rect on them to create the map. TILESIZE = 50 tile_list = [] map = [ [1,1,1,1,1,1,1,1,1,1,1,1,1], [1,0,0,0,1,0,1,0,0,0,0,0,1], [1,0,1,0,0,0,1,0,1,1,1,0,1], [1,0,0,0,1,1,1,0,0,0,0,0,1], [1,0,1,0,0,0,0,0,1,1,1,0,1], [1,0,1,0,1,1,1,0,1,0,0,0,1], [1,0,1,0,1,0,0,0,1,1,1,0,1], [1,0,1,0,1,1,1,0,1,0,1,0,1], [1,0,0,0,0,0,0,0,0,0,1,0,1], [1,1,1,1,1,1,1,1,1,1,1,1,1] ] # let's create a single Surface for the map and reuse that grid = pygame.Surface((len(map[0]) * TILESIZE, len(map) * TILESIZE), pygame.SRCALPHA) for y, row in enumerate(map): for x, cell in enumerate(row): # if we want a wall, we draw it on the new Surface # also, we store the Rect in the tile_list so collision detection works if cell: rect = pygame.draw.rect(grid, 'blue', (x*TILESIZE, y*TILESIZE, TILESIZE, TILESIZE)) tile_list.append(rect) loop = True clock = pygame.time.Clock() while loop: clock.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: loop = False #player controls keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: player_x -= speed if keys[pygame.K_RIGHT]: player_x += speed if keys[pygame.K_UP]: player_y -= speed if keys[pygame.K_DOWN]: player_y += speed screen.fill((255,255,255)) # draw the map surface to the screen screen.blit(grid, (0 ,0)) player = pygame.draw.rect(screen, (255,0,0), (player_x, player_y, 20, 20)) # now collision detection works because for each 1 in the map # there's a Rect in tile_list with the correct coordinates for i in tile_list: if player.colliderect(i): print("colliding") break else: print('not colliding') pygame.display.update() pygame.quit()
Save the position of the player before moving it: pos = x, y Compute the row and column after the player has moved: row = y // 50 column = x // 50 Reset the player's position if the new position is on a wall: if map[row][column] == 1: x, y = pos Additionally you have to move the map variable to global namespace. The speed should a integral divider of the tile size. Change the starting position to a position in the grid: speed = 25 x = 50 y = 50 Complete code: import pygame pygame.init() screen = pygame.display.set_mode((700,700)) pygame.display.set_caption("Game") speed = 25 x = 50 y = 50 map = [ [1,1,1,1,1,1,1,1,1,1,1,1,1], [1,0,0,0,1,0,1,0,0,0,0,0,1], [1,0,1,0,0,0,1,0,1,1,1,0,1], [1,0,0,0,1,1,1,0,0,0,0,0,1], [1,0,1,0,0,0,0,0,1,1,1,0,1], [1,0,1,0,1,1,1,0,1,0,0,0,1], [1,0,1,0,1,0,0,0,1,1,1,0,1], [1,0,1,0,1,1,1,0,1,0,1,0,1], [1,0,0,0,0,0,0,0,0,0,1,0,1], [1,1,1,1,1,1,1,1,1,1,1,1,1] ] def game_map(): global rect_one surface = pygame.Surface((100, 100), pygame.SRCALPHA) rect_one = pygame.draw.rect(surface, (0, 0, 255), (0, 0, 50, 50)) global rect_two surface_one = pygame.Surface((80, 80), pygame.SRCALPHA) rect_two = pygame.draw.rect(surface_one, (255, 255, 255), (0, 0, 50, 50)) tileX = 0 tileY = 0 for y, row in enumerate(map): tileX = 0 for x, cell in enumerate(row): image = surface if cell == 1 else surface_one screen.blit(image, [x*50, y*50]) pygame.display.update() def player(): player = pygame.draw.rect(screen, (255,0,0), (x, y, 25, 25)) loop = True while loop: pygame.time.delay(100) for event in pygame.event.get(): if event.type == pygame.QUIT: loop = False #player controls keys = pygame.key.get_pressed() pos = x, y if keys[pygame.K_LEFT]: x -= speed if keys[pygame.K_RIGHT]: x += speed if keys[pygame.K_UP]: y -= speed if keys[pygame.K_DOWN]: y += speed row = y // 50 column = x // 50 if map[row][column] == 1: x, y = pos screen.fill((255,255,255)) game_map() player() pygame.display.update() pygame.quit()
How to change my ball direction by clicking keys in pygame?
I have question. My ball is allways moving in 1 of 8 directions but when i click LEFT or RIGHT arrow I want to change direction and turn in smooth arc. I need advice what should I write to conditions for keys. I'm beginner but this is my code: import pygame pygame.init() import random win = pygame.display.set_mode((1280,720)) x = random.randint(150,1130) y = random.randint(150,570) vel = 1 x_direction = random.randint(-vel, vel) y_direction = random.randint(-vel, vel) while True: x += x_direction y += y_direction pygame.time.delay(10) keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: pass if keys[pygame.K_RIGHT]: pass win.fill((0,0,0)) pygame.draw.circle(win, (255,0,0), (x, y), 6) pygame.display.update() pygame.quit()
I recommend to store the direction in a pygame.math.Vector2 object: direction = pygame.math.Vector2(x_direction, y_direction) Change the the direction by rotating the vector with rotate_ip(): if keys[pygame.K_LEFT]: direction.rotate_ip(-1) if keys[pygame.K_RIGHT]: direction.rotate_ip(1) x += direction.x y += direction.y Not you can use rotate to create a vector with a random direction: direction = pygame.math.Vector2(1, 0).rotate(random.randint(0, 360)) See also Motion and movement. Complete example: import pygame import random pygame.init() win = pygame.display.set_mode((1280,720)) background = pygame.Surface(win.get_size(), pygame.SRCALPHA) background.fill((0, 0, 0, 1)) clock = pygame.time.Clock() x = random.randint(150,1130) y = random.randint(150,570) direction = pygame.math.Vector2(1, 0).rotate(random.randint(0, 360)) run = True while run: clock.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: direction.rotate_ip(-1) if keys[pygame.K_RIGHT]: direction.rotate_ip(1) x = max(0, min(direction.x + x, win.get_width())) y = max(0, min(direction.y + y, win.get_height())) win.blit(background, (0, 0)) pygame.draw.circle(win, (255,0,0), (round(x), round(y)), 6) pygame.display.update() pygame.quit()
Pygame display not working under If condition
I am trying to make my code display a text in the middle of the screen once a square goes past right by 500 pixels, but it does seem to be displaying with my If condition. I dont know what I am doing wrong. import pygame pygame.init() displaywidth=500 displayheight=500 gameDisplay = pygame.display.set_mode((displaywidth, displayheight)) pygame.display.set_caption("First Game") red = (0,255,0) font=pygame.font.Font(None, 20) #Class def Message(msg, color): screen_text=font.render(msg,True,color) gameDisplay.blit(screen_text,[displaywidth/2,displayheight/2]) win = pygame.display.set_mode((displaywidth, displayheight)) x = 50 y = 50 width = 40 height = 40 vel = 5 x1 = 0 y1 = 0 width1 = 40 height1 = 40 vel2 = 100 vel3=100 x2 = 100 y2 = 100 pygame.draw.rect(win, (0, 255, 0), (x, y, width, height)) run = True while run: pygame.time.delay(100) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: x -= vel2 elif keys[pygame.K_RIGHT]: x += vel2 elif keys[pygame.K_UP]: y1-=vel3 elif keys[pygame.K_DOWN]: y1+=vel3 if x > 500: Message("meow", red) pygame.display.update() print("pew") elif x < 0: x = 50 elif y1 > 500: y1 = 450 elif y1 < 0: y1 = 50 print(x) print(y) win.fill((0, 0, 0)) meow = pygame.draw.rect(win, (0, 255, 0), (x, y1, width, height)) pygame.draw.rect(win, (160, 0, 0), (x1, y1, width1, height1)) pygame.display.update() pygame.quit() My print command appears to be working but I dont know why its not displaying.
The issue is that you've 2 calls to pygame.display.update() in your code, but the display is cleared immediately after the first one: if x > 500: Message("meow", red) pygame.display.update() # <---- print("pew") # [...] win.fill((0, 0, 0)) # <---- Clear the display before anything is drawn and do a single pygame.display.update() at the end of the main application loop: run = True while run: pygame.time.delay(100) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: x -= vel2 elif keys[pygame.K_RIGHT]: x += vel2 elif keys[pygame.K_UP]: y1-=vel3 elif keys[pygame.K_DOWN]: y1+=vel3 if x < 0: x = 50 elif y1 > 500: y1 = 450 elif y1 < 0: y1 = 50 # clear dispaly win.fill((0, 0, 0)) # draw scene if x > 500: Message("meow", red) print("pew") meow = pygame.draw.rect(win, (0, 255, 0), (x, y1, width, height)) pygame.draw.rect(win, (160, 0, 0), (x1, y1, width1, height1)) # update display pygame.display.update()
How do i make continuous player movement in pygame?
I've been watching a pygame tutorial on youtube on player movement, and by using this code below, the guy making the video was able to hold down a key and the character would keep moving, but when i hold down a key the character will move once and then stop. Any ideas on how to fix this? Code: import pygame pygame.init() win = pygame.display.set_mode((500, 500)) pygame.display.set_caption("huge honkabonkaros") x = 50 y = 440 width = 40 height = 60 vel = 5 run = True while run: pygame.time.delay(50) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: x -= vel if keys[pygame.K_RIGHT]: x += vel if keys[pygame.K_UP]: y -= vel if keys[pygame.K_DOWN]: y += vel win.fill((0, 0, 0)) pygame.draw.rect(win, (255, 0, 0), (x, y, width, height)) pygame.display.update() pygame.quit()
It is a matter of Indentation. The continuous movement must be in the application loop and not in the event loop. The application loop runs once per frame, but the event loop only runs once per event. When a key is pressed a KEYDOWN event occurs and when a key is released a KEYUP event occurs, but there is no event when a key is held down: import pygame pygame.init() win = pygame.display.set_mode((500, 500)) pygame.display.set_caption("huge honkabonkaros") x = 50 y = 440 width = 40 height = 60 vel = 5 run = True while run: pygame.time.delay(50) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False # INDENTATION #<--| keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: x -= vel if keys[pygame.K_RIGHT]: x += vel if keys[pygame.K_UP]: y -= vel if keys[pygame.K_DOWN]: y += vel win.fill((0, 0, 0)) pygame.draw.rect(win, (255, 0, 0), (x, y, width, height)) pygame.display.update() pygame.quit()