This question already has answers here:
How do I detect collision in pygame?
(5 answers)
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Closed 2 years ago.
So I've been trying to make a simple maze game in pygame. Currently, I'm having problems with wall collision: The current collision system I'm using is buggy and doesn't work as intended:
import pygame
import random
# mazes
mazes = [
[
"wwwwwwwwwwwwwwwwwwwwwww",
"w w",
"w D",
"w D",
"w w",
"wwwwwwwwwwwwwwwwwwwwwww"
]
,
[
"wwwwwwwwwwwwwwwwwwwwwww",
"w w w",
"w w wwwwwwwwwwwwwwwww w",
"w w wD w w",
"w w wwwwwwwwwwwwwww w w",
"w w w w",
"w wwwwwwwwwwwwwwwwwww w",
"w w",
"wwwwwwwwwwwwwwwwwwwwwww"
]
]
pygame.init()
# Asset and text properties
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
blue = (0, 0, 255)
# Display properties
FPS = 30
display_width = 800
display_height = int(display_width * 2 / 3)
clock = pygame.time.Clock()
block_size = display_width / 40
level = 0
def message_to_screen(msg, color, fontSize, x_axis, y_axis):
font = pygame.font.SysFont(None, fontSize)
screen_text = font.render(msg, True, color)
gameDisplay.blit(screen_text, [x_axis, y_axis])
# Create a game display
gameDisplay = pygame.display.set_mode([display_width, display_height])
pygame.display.set_caption("Mazer - Use arrow keys to move")
def gameloop(): # main function
global level
wall_maze, door_maze = buildMaze(mazes[1])
gameExit = False
gameOver = False
movementSpeed_x = 0
movementSpeed_y = 0
player_x = display_width / 10
player_y = display_height / 1.2
speed = block_size / 2
while not gameExit: #running game loop
while gameOver:
gameDisplay.fill(white)
message_to_screen("Press Q to quit",
red, 40, display_width / 7, display_height / 3 )
message_to_screen("Press N for next level", red, 40,
display_width / 7, display_height / 3 + 40)
pygame.display.update()
for event in pygame.event.get():
if event == pygame.QUIT:
gameExit = True
gameOver = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameExit = True
gameOver = False
elif event.key == pygame.K_n:
level += 1
gameOver = False
gameloop()
# Event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
# Movement control
if movementSpeed_y == 0:
if event.key == pygame.K_LEFT:
movementSpeed_x = -speed
if event.key == pygame.K_RIGHT:
movementSpeed_x = speed
if movementSpeed_x == 0:
if event.key == pygame.K_DOWN:
movementSpeed_y = speed
if event.key == pygame.K_UP:
movementSpeed_y = -speed
if event.type == pygame.KEYUP and event.type != pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == pygame.K_DOWN or \
event.key == pygame.K_UP or event.key == pygame.K_RIGHT:
movementSpeed_x = 0
movementSpeed_y = 0
if movementSpeed_x > 0:
if pygame.sprite.spritecollideany(mazer, wall_maze):
movementSpeed_x = 0
player_x -= speed
elif movementSpeed_x < 0:
if pygame.sprite.spritecollideany(mazer, wall_maze):
movementSpeed_x = 0
player_x += speed
if movementSpeed_y > 0:
if pygame.sprite.spritecollideany(mazer, wall_maze):
movementSpeed_y = 0
player_y -= speed
elif movementSpeed_y < 0:
if pygame.sprite.spritecollideany(mazer, wall_maze):
movementSpeed_y = 0
player_y += speed
player_x += movementSpeed_x
player_y += movementSpeed_y
# Movement control
# Rendering
gameDisplay.fill(white)
mazer = player(block_size, player_x, player_y)
movingSprites = pygame.sprite.Group()
movingSprites.add(mazer)
wall_maze.draw(gameDisplay)
door_maze.draw(gameDisplay)
movingSprites.draw(gameDisplay)
pygame.display.update()
clock.tick(FPS) # FPS tick
if pygame.sprite.spritecollideany(mazer, door_maze):
gameOver = True
pygame.quit()
quit()
class asset(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class player(asset): # Class for player
def __init__(self, size, x, y):
# Image properties for player
super().__init__()
self.image = pygame.Surface([size, size])
self.image.fill(red)
self.rect = self.image.get_rect()
# Player's position
self.rect.x = x
self.rect.y = y
class wall(asset): # Class for wall blocks
def __init__(self, size, x , y):
# Image properties for wall
super().__init__()
self.image = pygame.Surface([size, size])
self.image.fill(black)
self.rect = self.image.get_rect()
# Wall's position
self.rect.x = x
self.rect.y = y
class door(asset):
def __init__(self, size, x, y):
super().__init__()
self.image = pygame.Surface([size, size])
self.image.fill(blue)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def buildMaze(Maze):
wall_list = pygame.sprite.Group()
door_list = pygame.sprite.Group()
pos_x = display_width / 10 - block_size
pos_y = display_height / 1.2 + block_size
for row in Maze:
for space in row:
if space == "w":
wall_maze = wall(block_size, pos_x, pos_y)
wall_list.add(wall_maze)
elif space == "D":
door_maze = door(block_size, pos_x, pos_y)
door_list.add(door_maze)
pos_x += block_size
pos_y -= block_size
pos_x = display_width / 10 - block_size
return wall_list, door_list
gameloop()
If you try to run the code and play around with the game, you'll notice that when you move toward a wall, the player will usually stay inside the wall and the control is inverted (move right when pressing left). I suspected that it has to do with how I constructed my collision detector:
if movementSpeed_x > 0:
if pygame.sprite.spritecollideany(mazer, wall_maze):
movementSpeed_x = 0
player_x -= speed
elif movementSpeed_x < 0:
if pygame.sprite.spritecollideany(mazer, wall_maze):
movementSpeed_x = 0
player_x += speed
if movementSpeed_y > 0:
if pygame.sprite.spritecollideany(mazer, wall_maze):
movementSpeed_y = 0
player_y -= speed
elif movementSpeed_y < 0:
if pygame.sprite.spritecollideany(mazer, wall_maze):
movementSpeed_y = 0
player_y += speed
One more thing, I thought that by having this code before pygame.display.update(), it wouldn't show the player hitting the wall because the position is supposed to be updated before that but somehow it doesn't work as intended. Thank you for looking at my code.
Related
I implemented a pause feature in my game in the while loop at the end of my code, but the problem is that only my car sprite pauses. I have tried a bunch of different ways setting up my pause code but none of the ways I arrange it seems to pause the whole game.
I want to be able to pause my whole game when I press the p key on my keyboard, not just my car sprite. Can someone please tell me how I can fix this code? The code that will pause the whole game will be nice. Please, the rearranged code that will pause the whole game will help. Also I don't just want the answer, I want a quick explanation of why only my car sprite would pause instead of the whole game.
My code:
import random
import pygame
import pygame.freetype
pygame.init()
#screen settings
WIDTH = 1000
HEIGHT = 400
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("AutoPilot")
screen.fill((255, 255, 255))
#fps
FPS = 120
clock = pygame.time.Clock()
#load images
bg = pygame.image.load('background/street.png').convert_alpha() # background
bullets = pygame.image.load('car/bullet.png').convert_alpha()
debris_img = pygame.image.load('debris/cement.png')
#define game variables
shoot = False
#player class
class Player(pygame.sprite.Sprite):
def __init__(self, scale, speed):
pygame.sprite.Sprite.__init__(self)
self.bullet = pygame.image.load('car/bullet.png').convert_alpha()
self.bullet_list = []
self.speed = speed
#self.x = x
#self.y = y
self.moving = True
self.frame = 0
self.flip = False
self.direction = 0
self.score = 0
#load car
self.images = []
img = pygame.image.load('car/car.png').convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width()) * scale, (int(img.get_height()) * scale)))
self.images.append(img)
self.image = self.images[0]
self.rect = self.image.get_rect()
self.update_time = pygame.time.get_ticks()
self.movingLeft = False
self.movingRight = False
self.rect.x = 465
self.rect.y = 325
#draw car to screen
def draw(self):
screen.blit(self.image, (self.rect.centerx, self.rect.centery))
#move car
def move(self):
#reset the movement variables
dx = 0
dy = 0
#moving variables
if self.movingLeft and self.rect.x > 33:
dx -= self.speed
self.flip = True
self.direction = -1
if self.movingRight and self.rect.x < 900:
dx += self.speed
self.flip = False
self.direction = 1
#update rectangle position
self.rect.x += dx
self.rect.y += dy
#shoot
def shoot(self):
bullet = Bullet(self.rect.centerx + 18, self.rect.y + 30, self.direction)
bullet_group.add(bullet)
#check collision
def collision(self, debris_group):
for debris in debris_group:
if debris.health > 0 and pygame.sprite.spritecollide(debris, bullet_group, True):
debris.health -= 1
if debris.health <= 0:
self.score += 1
#player stats/score
def stats(self):
myfont = pygame.font.SysFont('comicsans', 30)
scoretext = myfont.render("Score: " + str(self.score), 1, (0,0,0))
screen.blit(scoretext, (100,10))
#bullet class
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.speed = 5
self.image = bullets
self.rect = self.image.get_rect()
self.rect.center = (x,y)
self.direction = direction
def update(self):
self.rect.centery -= self.speed
#check if bullet has gone off screen
if self.rect.centery < 1:
self.kill()
#debris class
class Debris(pygame.sprite.Sprite):
def __init__(self,scale,speed):
pygame.sprite.Sprite.__init__(self)
self.scale = scale
self.x = random.randrange(100,800)
self.speed_y = 10
self.y = 15
self.speed = speed
self.vy = 0
self.on_ground = True
self.move = True
self.health = 4
self.max_health = self.health
self.alive = True
self.velocity = random.randrange(1,2)
self.speed_x = random.randrange(-3,3)
self.moving_down = True
self.is_destroyed = False
#load debris
self.image = debris_img
self.rect = self.image.get_rect()
self.rect.x = random.randrange(100, 800)
self.rect.y = random.randrange(-150, -100)
self.rect.center = (self.x,self.y)
#load explosion
self.img_explosion_00 = pygame.image.load('explosion/0.png').convert_alpha()
self.img_explosion_00 = pygame.transform.scale(self.img_explosion_00, (self.img_explosion_00.get_width() * 2,
self.img_explosion_00.get_height() * 2))
self.img_explosion_01 = pygame.image.load('explosion/1.png').convert_alpha()
self.img_explosion_01 = pygame.transform.scale(self.img_explosion_01, (self.img_explosion_01.get_width() * 2,
self.img_explosion_01.get_height() * 2))
self.img_explosion_02 = pygame.image.load('explosion/2.png').convert_alpha()
self.img_explosion_02 = pygame.transform.scale(self.img_explosion_02, (self.img_explosion_02.get_width() * 2,
self.img_explosion_02.get_height() * 2))
self.img_explosion_03 = pygame.image.load('explosion/3.png').convert_alpha()
self.img_explosion_03 = pygame.transform.scale(self.img_explosion_03, (self.img_explosion_03.get_width() * 2,
self.img_explosion_03.get_height() * 2))
#explosion list
self.anim_explosion = [self.img_explosion_00,
self.img_explosion_01,
self.img_explosion_02,
self.img_explosion_03]
self.anim_index = 0
self.frame_len = 20 #frames before explosion animation disappears
#spawn new debris
def spawn_new_debris(self):
self.rect.x = random.randrange(100, 800)
self.rect.y = random.randrange(-150, -100)
self.velocity = random.randrange(1, 2)
self.speed_x = random.randrange(-3, 3)
#respawn debris when they go of the screen
def boundaries(self):
if self.rect.left > WIDTH + 10 or self.rect.right < -10 or self.rect.top > HEIGHT + 10:
self.spawn_new_debris()
#update image
def update(self):
self.rect.y += self.velocity
self.rect.x += self.speed_x
self.boundaries()
if self.health <= 0:
max_index = len(self.anim_explosion) - 1
if self.anim_index > max_index:
self.kill()
else:
if self.frame_len == 0:
self.image = self.anim_explosion[self.anim_index]
self.anim_index += 1
self.frame_len = 20
else:
self.frame_len -= 1
#make debris fall down
def falldown(self):
self.rect.centery += self.velocity
if self.moving_down and self.rect.y > 350:
self.kill()
######################CAR/DEBRIS##########################
player = Player(1,5)
##########################################################
#groups
bullet_group = pygame.sprite.Group()
debris_group = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
for x in range(100):
d = Debris(1, 5)
debris_group.add(d)
all_sprites.add(d)
#game runs here
run = True
paused = False
while run:
#draw street
screen.blit(bg, [0, 0])
#update groups
bullet_group.update()
bullet_group.draw(screen)
debris_group.update()
debris_group.draw(screen)
#draw car
player.draw()
player.move()
player.collision(debris_group)
player.stats()
#update all sprites
all_sprites.update()
all_sprites.draw(screen)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#pause game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = not paused
if paused == True:
continue
#check if key is down
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.key == pygame.K_a:
player.movingLeft = True
if event.key == pygame.K_d:
player.movingRight = True
if event.key == pygame.K_SPACE:
player.shoot()
shoot = True
#check if key is up
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player.movingLeft = False
if event.key == pygame.K_d:
player.movingRight = False
#update the display
pygame.display.update()
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
Move your
for event in pygame.event.get():
right below the while loop, and move your
if paused:
continue
below the for loop, like so:
run = True
paused = False
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#pause game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = not paused
#check if key is down
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.key == pygame.K_a:
player.movingLeft = True
if event.key == pygame.K_d:
player.movingRight = True
if event.key == pygame.K_SPACE:
player.shoot()
shoot = True
#check if key is up
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player.movingLeft = False
if event.key == pygame.K_d:
player.movingRight = False
if paused:
continue
#draw street
screen.blit(bg, [0, 0])
#update groups
bullet_group.update()
bullet_group.draw(screen)
debris_group.update()
debris_group.draw(screen)
#draw car
player.draw()
player.move()
player.collision(debris_group)
player.stats()
#update all sprites
all_sprites.update()
all_sprites.draw(screen)
#update the display
pygame.display.update()
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
The reason only your car sprite paused when you pressed the q key is because, as you can see in your original code here:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#pause game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = not paused
if paused == True:
continue
you put the
if paused == True:
continue
inside the for loop, not the while loop, so the lines that move the car would be blocked, but the rest of the code within the while loop will still get executed.
This question already has an answer here:
How do I get the snake to grow and chain the movement of the snake's body?
(1 answer)
Closed 1 year ago.
I'm new to python and only now the basics, I'm trying to make a snake game but I can't seem to figure out how to make my snake grow 1 extra square each time it eats an apple. My reasoning is that I keep a list of all the old positions but only show the last one on the screen, and each time the snakes eats another apple it shows 1 extra old positions making the snake 1 square longer.
This is my code:
import pygame
from random import randint
WIDTH = 400
HEIGHT = 300
dis = pygame.display.set_mode((WIDTH,HEIGHT))
white = (255,255,255)
BACKGROUND = white
blue = [0,0,255]
red = [255,0,0]
class Snake:
def __init__(self):
self.image = pygame.image.load("snake.bmp")
self.rect = self.image.get_rect()
self.position = (10,10)
self.direction = [0,0]
self.positionslist = [self.position]
self.length = 1
pygame.display.set_caption('Snake ')
def draw_snake(self,screen):
screen.blit(self.image, self.position)
def update(self):
self.position = (self.position[0] + self.direction[0],self.position[1] + self.direction[1])
self.rect = (self.position[0],self.position[1],5, 5 )
self.positionslist.append(self.position)
if self.position[0]< 0 :
self.position = (WIDTH,self.position[1])
elif self.position[0] > WIDTH:
self.position = (0,self.position[1])
elif self.position[1] > HEIGHT:
self.position = (self.position[0],0)
elif self.position[1] < 0 :
self.position = (self.position[0],HEIGHT)
class Food:
def __init__(self):
self.image = pygame.image.load("appel.png")
self.rect = self.image.get_rect()
apple_width = -self.image.get_width()
apple_height = -self.image.get_height()
self.position = (randint(0,WIDTH+apple_width-50),randint(0,HEIGHT+apple_height-50))
self.rect.x = self.position[0]
self.rect.y = self.position[1]
def draw_appel(self,screen):
screen.blit(self.image, self.position)
def eat_appel (self, snake):
if self.rect.colliderect(snake.rect) == True:
self.position = (randint(0,WIDTH),randint(0,HEIGHT))
self.rect.x = self.position[0]
self.rect.y = self.position[1]
snake.length += 1
def main():
game_over = False
while not game_over:
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
snake = Snake()
food = Food()
while True:
screen.fill(BACKGROUND)
font = pygame.font.Font('freesansbold.ttf', 12)
text = font.render(str(snake.length), True, red, white)
textRect = text.get_rect()
textRect.center = (387, 292)
screen.blit(text,textRect)
snake.update()
#snake.update_list()
snake.draw_snake(screen)
food.draw_appel(screen)
food.eat_appel(snake)
pygame.display.flip()
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
snake.direction = [0,1]
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
snake.direction = [1,0]
if event.key == pygame.K_LEFT:
snake.direction = [-1,0]
if event.key == pygame.K_UP:
snake.direction = [0,-1]
if event.key == pygame.K_DOWN:
snake.direction = [0,1]
if __name__ == "__main__":
main()
This can have multiple reasons. Firstly, I saw you tried to increase the length of the snake by typing snake.length += 1, which may work (probably won't because the module pygame allows the snake to hover around, but not like the loop or conditional statements). One of my tips would be, to increase the length of the snake by using the idea of adding the score with your present snake.length every time (because once your score is 1 by eating an apple, your snake.length would be 2. And it increases with the score). This is my code (a few modifications might be needed):
import pygame
import time
import random
pygame.init()
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
orange = (255, 165, 0)
width, height = 600, 400
game_display = pygame.display.set_mode((width, height))
pygame.display.set_caption("Snake Mania")
clock = pygame.time.Clock()
snake_size = 10
snake_speed = 15
message_font = pygame.font.SysFont('ubuntu', 30)
score_font = pygame.font.SysFont('ubuntu', 25)
def print_score(score):
text = score_font.render("Score: " + str(score), True, orange)
game_display.blit(text, [0,0])
def draw_snake(snake_size, snake_pixels):
for pixel in snake_pixels:
pygame.draw.rect(game_display, white, [pixel[0], pixel[1], snake_size, snake_size])
def run_game():
game_over = False
game_close = False
x = width / 2
y = height / 2
x_speed = 0
y_speed = 0
snake_pixels = []
snake_length = 1
target_x = round(random.randrange(0, width - snake_size) / 10.0) * 10.0
target_y = round(random.randrange(0, height - snake_size) / 10.0) * 10.0
while not game_over:
while game_close:
game_display.fill(black)
game_over_message = message_font.render("Game Over!", True, red)
game_display.blit(game_over_message, [width / 3, height / 3])
print_score(snake_length - 1)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
game_over = True
game_close = False
if event.key == pygame.K_2:
run_game()
if event.type == pygame.QUIT:
game_over = True
game_close = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_speed = -snake_size
y_speed = 0
if event.key == pygame.K_RIGHT:
x_speed = snake_size
y_speed = 0
if event.key == pygame.K_UP:
x_speed = 0
y_speed = -snake_size
if event.key == pygame.K_DOWN:
x_speed = 0
y_speed = snake_size
if x >= width or x < 0 or y >= height or y < 0:
game_close = True
x += x_speed
y += y_speed
game_display.fill(black)
pygame.draw.rect(game_display, orange, [target_x, target_y, snake_size, snake_size])
snake_pixels.append([x, y])
if len(snake_pixels) > snake_length:
del snake_pixels[0]
for pixel in snake_pixels[:-1]:
if pixel == [x, y]:
game_close = True
draw_snake(snake_size, snake_pixels)
print_score(snake_length - 1)
pygame.display.update()
if x == target_x and y == target_y:
target_x = round(random.randrange(0, width - snake_size) / 10.0) * 10.0
target_y = round(random.randrange(0, height - snake_size) / 10.0) * 10.0
snake_length += 1
clock.tick(snake_speed)
pygame.quit()
quit()
run_game()
This question already has answers here:
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Why is my collision test always returning 'true' and why is the position of the rectangle of the image always wrong (0, 0)?
(1 answer)
How do I detect collision in pygame?
(5 answers)
Closed 2 years ago.
I want to make it kind of like a life system so that if it collides with the enemy 3 times it will quit
pygame.init()
screen_width = 800
screen_height = 600
window = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Test')
time = pygame.time.Clock()
bg_color1 = (135, 142, 142) # MAIN BG COLOR
bg_color2 = (255, 0, 0) # red
bg_color3 = (255, 255, 0) # yellow
UFO = pygame.image.load('ufo.png')
bg_pic = pygame.image.load('Letsgo.jpg')
clock = pygame.time.Clock()
playerImg = pygame.image.load('enemy.png')
playerX = random.randrange(0, screen_width)
playerY = -50
playerX_change = 0
player_speed = 5
def player(x, y):
window.blit(playerImg, (playerX, playerY))
crashed = False
rect = UFO.get_rect()
obstacle = pygame.Rect(400, 200, 80, 80)
menu = True
playerY = playerY + player_speed
if playerY > screen_height:
playerX = random.randrange(0, screen_width)
playerY = -25
def ufo(x, y):
window.blit(UFO, (x, y))
while menu:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
menu = False
window.fill((0, 0, 0))
time.tick(30)
window.blit(bg_pic, (0, 0))
pygame.display.update()
x = (screen_width * 0.45)
y = (screen_height * 0.8)
x_change = 0
car_speed = 0
y_change = 0
while not crashed:
x += x_change
if x < 0:
x = 0
elif x > screen_width - UFO.get_width():
x = screen_width - UFO.get_width()
y += y_change
if y < 0:
y = 0
elif y > screen_height - UFO.get_height():
y = screen_height - UFO.get_height()
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
############SIDE TO SIDE################
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -5
elif event.key == pygame.K_RIGHT:
x_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
###########UP AND DOWN#################
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_change = -5
elif event.key == pygame.K_DOWN:
y_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
if playerY > screen_height:
playerX = random.randrange(0, screen_width)
playerY = 0
playerY += 10
##
window.fill(bg_color1)
ufo(x, y)
player(playerX, playerY)
pygame.display.update()
clock.tick(100)
pygame.quit()
quit()
im thinking of using a collide.rect but cant figure it out any help is appreciated
I want the "playerImg" to be the enemy ...................................................................................
Create a variable that stores the number of lives. Create pygme.Rect objects of the player and the UFO with the method get_rect. Set the location of the rectangles by keyword arguments. Use colliderect to test the collision and decrease the number of lives when a collision is detected and create a new random starting position:
lives = 3
while not crashed:
# [...]
player_rect = playerImg.get_rect(topleft = (playerX, playerY))
ufo_rect = UFO.get_rect(topleft = (x, y))
if player_rect.colliderect(ufo_rect):
lives -= 1
print(lives)
playerX = random.randrange(0, screen_width)
playerY = 0
if lives == 0:
crashed = True
# [...]
This question already has answers here:
How do I detect collision in pygame?
(5 answers)
Pygame how to let balls collide
(2 answers)
pygame Get the balls to bounce off each other
(1 answer)
Closed 2 years ago.
ltcImgI am making a simple game where a car dodges some objects, all of which I am importing using pictures from the internet. What would be the best way to configure circular hitboxes that would work well when running into the square box of my car?
CarImg
Right now I have them put into length and width parameters, since that is all I really know how to do. For some reason, my hitboxes are ending the game good on the left side of my "ltc" circle, but when I cross the boundaries of the circle on the right side, even though I do not actually "hit" the circle, it is causing me to crash and ending the game.
I have tried adjusting my ltcw and ltch to see if it makes it better, but I can only seem to make it worse overall. I couldn't find anything online referencing specifically circular hitboxes when using imported pictures when running into square hitboxes.
import pygame
import time
import random
pygame.init()
display_width = 800
display_height = 600
car_width = 60
car_height = 113
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('TRX: FuD Racer')
clock = pygame.time.Clock()
carImg = pygame.image.load('RaceCar2.png')
ltcImg = pygame.image.load('LtcLogo.png')
xlmImg = pygame.image.load('Stell_Logo.png')
def car(x, y):
gameDisplay.blit(carImg, (x, y))
def ltc(x, y):
gameDisplay.blit(ltcImg, (x, y))
def stell(x, y):
gameDisplay.blit(xlmImg, (x, y))
def text_objects(text, font):
textSurface = font.render(text, True, BLACK)
return (textSurface, textSurface.get_rect())
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf', 75)
(textSurf, textRect) = text_objects(text, largeText)
textRect.center = (display_width / 2, display_height / 2)
gameDisplay.blit(textSurf, textRect)
pygame.display.update()
time.sleep(3)
game_loop()
def crash():
message_display('You Sold Your Tron!')
def game_loop():
x = display_width * 0.45
y = display_height * 0.8
x_change = 0
y_change = 0
# I should adjust each coins speed in game in accordance with their transaction speeds
ltc_startx = random.randrange(0, display_width)
ltc_starty = -300
ltc_speed = 2
ltcw = 222
ltch = 200
stell_startx = random.randrange(0, display_width)
stell_starty = -600
stell_speed = 6
stellw = 300
stellh = 450
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -6
elif event.key == pygame.K_RIGHT:
x_change = 6
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_change = -6
elif event.key == pygame.K_DOWN:
y_change = 6
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key \
== pygame.K_DOWN:
y_change = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key \
== pygame.K_RIGHT:
x_change = 0
x += x_change
y += y_change
gameDisplay.fill(WHITE)
ltc(ltc_startx, ltc_starty)
ltc_starty += ltc_speed
car(x, y)
stell(stell_startx, stell_starty)
stell_starty += stell_speed
car(x, y)
if x > display_width - car_width or x < -15:
crash()
if ltc_starty > display_height:
ltc_starty = 0 - ltch
ltc_startx = random.randrange(0, display_width - ltcw)
if stell_starty > display_height:
stell_starty = 0 - stellh
stell_startx = random.randrange(0, display_width - stellw)
if y < 0:
crash()
if y < ltc_starty + ltch:
print 'y crossover'
if x > ltc_startx and x < ltc_startx + ltcw or x \
+ car_width > ltc_startx and x + car_width < ltc_startx \
+ ltcw:
print 'x crossover'
crash()
pygame.display.update()
clock.tick(60)
game_loop()
pygame.quit()
quit()
i have a snake game i made in python and i want to add him boulders that will appear every 10 "apples" he gets, so can you help me please? this is the code right now
import pygame
import random
__author__ = 'Kfir_Kahanov'
init = pygame.init()
def quit_game():
"""
this function will quit the game
:return:
"""
pygame.quit()
quit()
# this will set a nice sound when the player gets an apple
BLOP = pygame.mixer.Sound("Blop.wav")
pygame.mixer.Sound.set_volume(BLOP, 1.0)
volume = pygame.mixer.Sound.get_volume(BLOP)
# making colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 155, 0)
BLUE = (0, 0, 255)
YELLOW = (217, 217, 0)
SNAKE_RED = (152, 2, 2)
def display_fill():
"""
this will fill the screen with a color of my choice
:return:
"""
game_display.fill(GREEN)
def mute():
"""
this will mute the game or unmute it
:return:
"""
if volume == 1.0:
pygame.mixer.Sound.set_volume(BLOP, 0.0)
else:
pygame.mixer.Sound.set_volume(BLOP, 10.0)
# all the pygame stuff for the display
DISPLAY_WIDTH = 800
DISPLAY_HEIGHT = 600
game_display = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
pygame.display.set_caption("The hungry Cobra")
ICON = pygame.image.load("apple_icon.png")
pygame.display.set_icon(ICON)
pygame.display.update()
# deciding on FPS, the size of the snake, apples, and making the fonts for the text
CLOCK = pygame.time.Clock()
BLOCK_SIZE = 20
APPLE_THICKNESS = 30
fps = 15
# BOULDER_THICKNESS = 30
direction = "right" # deciding the starting direction
tiny_font = pygame.font.SysFont("comicsansms", 10)
small_font = pygame.font.SysFont("comicsansms", 25)
med_font = pygame.font.SysFont("comicsansms", 50)
large_font = pygame.font.SysFont("comicsansms", 80)
def text_objects(text, color, size):
"""
defining the text
:param text:
:param color:
:param size:
:return:
"""
global text_surface
if size == "tiny":
text_surface = tiny_font.render(text, True, color)
if size == "small":
text_surface = small_font.render(text, True, color)
if size == "medium":
text_surface = med_font.render(text, True, color)
if size == "large":
text_surface = large_font.render(text, True, color)
return text_surface, text_surface.get_rect()
# loading apple and snake img
IMG = pygame.image.load("snake_head.png")
APPLE_IMG = pygame.image.load("apple_icon.png")
# BOULDER_IMG = pygame.image.load("boulder.png")
def rand_apple_gen():
"""
making apple function
:return:
"""
rand_apple_x = round(random.randrange(10, DISPLAY_WIDTH - APPLE_THICKNESS)) # / 10.0 * 10.0
rand_apple_y = round(random.randrange(10, DISPLAY_HEIGHT - APPLE_THICKNESS)) # / 10.0 * 10.0
return rand_apple_x, rand_apple_y
"""
def rand_boulder_gen():
making the boulder parameters
:return:
rand_boulder_x = round(random.randrange(10, DISPLAY_WIDTH - BOULDER_THICKNESS))
rand_boulder_y = round(random.randrange(10, DISPLAY_WIDTH - BOULDER_THICKNESS))
return rand_boulder_x, rand_boulder_y
"""
def message(msg, color, y_displace=0, size="small"):
"""
making a function for the making of the text
:param msg:
:param color:
:param y_displace:
:param size:
:return:
"""
text_surf, text_rect = text_objects(msg, color, size)
text_rect.center = ((DISPLAY_WIDTH / 2), (DISPLAY_HEIGHT / 2) + y_displace)
game_display.blit(text_surf, text_rect)
def intro_message():
"""
making the intro
:return:
"""
intro = True
while intro:
display_fill()
message("Welcome to ", BLACK, -200, "large")
message("The hungry Cobra!", BLACK, -100, "large")
message("Eat apples to grow, but be care full", BLACK)
message("if you run into yourself or outside the screen", BLACK, 30)
message("you gonna have a bad time", BLACK, 60)
message("Press S to start or E to exit", BLACK, 90)
message("Created by Kfir Kahanov", BLACK, 200, "tiny")
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
display_fill()
pygame.display.update()
quit_game()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
mute()
if event.key == pygame.K_s:
intro = False
if event.key == pygame.K_e:
display_fill()
pygame.display.update()
quit_game()
score_edit = 0
def score_f(score):
"""
making a score_f on the top left
:param score:
:return:
"""
text = small_font.render("Score:" + str(score + score_edit), True, YELLOW)
game_display.blit(text, [0, 0])
def pause_f():
"""
making a pause_f screen
:return:
"""
pause = True
if pause:
message("Paused", RED, -50, "large")
message("Press R to start over, E to exit or C to continue", BLACK)
pygame.display.update()
while pause:
for event in pygame.event.get():
if event.type == pygame.QUIT:
display_fill()
pygame.display.update()
quit_game()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
mute()
if event.key == pygame.K_c or pygame.K_ESCAPE or pygame.K_p:
pause = False
if event.key == pygame.K_r:
global score_edit, direction, cheat1, cheat4, cheat3, cheat2
direction = "right"
score_edit = 0
cheat1 = 16
cheat2 = 16
cheat3 = 16
cheat4 = 16
game_loop()
if event.key == pygame.K_e:
display_fill()
pygame.display.update()
quit_game()
CLOCK.tick(5)
# making cheats
cheat1 = 16
cheat2 = 16
cheat3 = 16
cheat4 = 16
def snake(snake_list):
"""
defining the snake head
:param snake_list:
:return:
"""
global head
if direction == "right":
head = pygame.transform.rotate(IMG, 270)
elif direction == "left":
head = pygame.transform.rotate(IMG, 90)
elif direction == "down":
head = pygame.transform.rotate(IMG, 180)
elif direction == "up":
head = IMG
game_display.blit(head, (snake_list[-1][0], snake_list[-1][1]))
for x_n_y in snake_list[:-1]:
pygame.draw.rect(game_display, SNAKE_RED, [x_n_y[0], x_n_y[1], BLOCK_SIZE, BLOCK_SIZE])
def game_loop():
"""
this will be the game itself
:return:
"""
global cheat1
global cheat2
global cheat3
global cheat4
global direction
global fps
game_exit = False
game_over = False
global score_edit
lead_x = DISPLAY_WIDTH / 2
lead_y = DISPLAY_HEIGHT / 2
# rand_boulder_x, rand_boulder_y = -50, -50
lead_x_change = 10
lead_y_change = 0
snake_list = []
snake_length = 1
rand_apple_x, rand_apple_y = rand_apple_gen()
while not game_exit:
if game_over:
message("Game over!", RED, -50, "large")
message("Press E to exit or R to retry.", BLACK, 20, "medium")
pygame.display.update()
while game_over:
fps = 15
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_exit = True
game_over = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
mute()
if event.key == pygame.K_e:
game_exit = True
game_over = False
if event.key == pygame.K_r:
direction = "right"
score_edit = 0
cheat1 = 16
cheat2 = 16
cheat3 = 16
cheat4 = 16
game_loop()
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_exit = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
mute()
if event.key == pygame.K_LEFT and lead_x_change is not BLOCK_SIZE and direction is not "right":
lead_x_change = -BLOCK_SIZE
lead_y_change = 0
direction = "left"
elif event.key == pygame.K_RIGHT and lead_x_change is not -BLOCK_SIZE and direction is not "left":
lead_x_change = BLOCK_SIZE
lead_y_change = 0
direction = "right"
elif event.key == pygame.K_UP and lead_y_change is not BLOCK_SIZE and direction is not "down":
lead_y_change = -BLOCK_SIZE
lead_x_change = 0
direction = "up"
elif event.key == pygame.K_DOWN and lead_y_change is not -BLOCK_SIZE and direction is not "up":
lead_y_change = BLOCK_SIZE
lead_x_change = 0
direction = "down"
elif event.key == pygame.K_p:
pause_f()
elif event.key == pygame.K_ESCAPE:
pause_f()
elif event.key == pygame.K_k: # the cheat
cheat1 = 0
elif event.key == pygame.K_f:
cheat2 = 4
elif event.key == pygame.K_i:
cheat3 = 0
elif event.key == pygame.K_r:
cheat4 = 3
elif cheat1 == 0 and cheat2 == 4 and cheat3 == 0 and cheat4 == 3:
score_edit = 10000
if lead_x >= DISPLAY_WIDTH or lead_x < 0 or lead_y >= DISPLAY_HEIGHT or lead_y < 0:
game_over = True
lead_x += lead_x_change
lead_y += lead_y_change
display_fill()
game_display.blit(APPLE_IMG, (rand_apple_x, rand_apple_y))
snake_head = [lead_x, lead_y]
snake_list.append(snake_head)
if len(snake_list) > snake_length:
del snake_list[0]
for eachSegment in snake_list[:-1]:
if eachSegment == snake_head:
game_over = True
snake(snake_list)
score_f(snake_length * 10 - 10)
pygame.display.update()
if rand_apple_x < lead_x < rand_apple_x + APPLE_THICKNESS or rand_apple_x < lead_x + BLOCK_SIZE < rand_apple_x \
+ APPLE_THICKNESS:
if rand_apple_y < lead_y < rand_apple_y + APPLE_THICKNESS or rand_apple_y < lead_y + BLOCK_SIZE < \
rand_apple_y + APPLE_THICKNESS:
pygame.mixer.Sound.play(BLOP)
rand_apple_x, rand_apple_y = rand_apple_gen()
snake_length += 1
fps += 0.15
"""
if snake_length * 10 - 10 == 20:
rand_boulder_x, rand_boulder_y = rand_boulder_gen()
game_display.blit(BOULDER_IMG, (rand_boulder_x, rand_boulder_y))
elif rand_boulder_x < lead_x < rand_boulder_y + BOULDER_THICKNESS or rand_boulder_x < lead_x + BLOCK_SIZE < \
rand_boulder_x + BOULDER_THICKNESS:
if rand_boulder_x < lead_y < rand_boulder_y + BOULDER_THICKNESS or rand_boulder_y < lead_y + BLOCK_SIZE < \
rand_boulder_y + BOULDER_THICKNESS:
game_over = True
"""
CLOCK.tick(fps)
display_fill()
pygame.display.update()
quit_game()
intro_message()
game_loop()
Maybe try explaining what you have tried and why it isn't working. You would get better help that way.
From what I can see from your code though....
You seem to be on the right track in your commented out code. Evaluating the snake length or score variable during your game loop, then generating a random boulder to the screen. The next step is just handling the collision logic for all the boulders, which I see two ways of doing. First way is creating a lists of the boulder attributes like the x,y positions, similar to how you did the snake list. The second way would be to create a class for boulders, then when the score, or snake length, reaches 10, create a new boulder object. Using a class may make the collision logic much easier to handle.