This question already has an answer here:
How can I move the ball instead of leaving a trail all over the screen in pygame?
(1 answer)
Closed 5 months ago.
This is what is happening:
I need help avoiding this from happening, I'm using an array called snake_position where the x and y coordinates are stored, with AWSD keys I move by adding and substracting by 10 and therefore I'm moving the rect position. I'm triying to only move one rect in the screen and not have this long drawing in the screen.
My Code:
import pygame
import time
import random
WIDTH = 800
HEIGHT = 600
FPS = 30
FramePerSec = pygame.time.Clock()
snake_position = [100, 50]
snake_body = [100, 50]
pygame.init()
wn = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("SNAKE")
direction = 0
change_to = direction
white = pygame.Color(255, 255, 255)
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
change_to = 'UP'
if event.key == pygame.K_s:
change_to = 'DOWN'
if event.key == pygame.K_a:
change_to = 'LEFT'
if event.key == pygame.K_d:
change_to = 'RIGHT'
# If two keys pressed simultaneously
# we don't want snake to move into two
# directions simultaneously
if change_to == 'UP' and direction != 'DOWN':
direction = 'UP'
if change_to == 'DOWN' and direction != 'UP':
direction = 'DOWN'
if change_to == 'LEFT' and direction != 'RIGHT':
direction = 'LEFT'
if change_to == 'RIGHT' and direction != 'LEFT':
direction = 'RIGHT'
# Moving the snake
if direction == 'UP':
snake_position[1] -= 10
if direction == 'DOWN':
snake_position[1] += 10
if direction == 'LEFT':
snake_position[0] -= 10
if direction == 'RIGHT':
snake_position[0] += 10
if event.type == pygame.QUIT:
pygame.quit()
pygame.draw.rect(wn, white,
pygame.Rect(snake_position[0], snake_position[1], 20, 20))
pygame.display.update()
FramePerSec.tick(FPS)
You should see it in every tutorial - you have to clear screen in every loop - ie. wn.fill('black')
wn.fill('black') # <--- clear screen before new drawings
pygame.draw.rect(wn, white,
pygame.Rect(snake_position[0], snake_position[1], 20, 20))
pygame.display.update()
FramePerSec.tick(FPS)
Related
I am making a mini-game that involves movement. I created an object that moves according to the controls, but how do i make it not move if it collides with a wall?
#Imports
import pygame, sys
#Functions
#General Set Up
pygame.init()
clock = pygame.time.Clock()
#Main Window
swid = 1280
shgt = 700
screen = pygame.display.set_mode((swid, shgt))
pygame.display.set_caption("Raid: The Game || Movement Test")
#Game Rectangles
player = pygame.Rect(30, 30, 30, 30)
wall = pygame.Rect(140, 80, 1000, 20)
window = pygame.Rect(300, 400, 220, 20)
door = pygame.Rect(500, 500, 120, 18)
bgcol = (0,0,0)
playercol = (200,0,0)
wallcol = pygame.Color("grey12")
doorcol = pygame.Color("blue")
windowcol = (100,100,100)
xwalkspeed = 0
ywalkspeed = 0
while True:
#Handling Input
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_DOWN:
ywalkspeed += 10
if event.key == pygame.K_UP:
ywalkspeed -= 10
if event.key == pygame.K_LEFT:
xwalkspeed -= 10
if event.key == pygame.K_RIGHT:
xwalkspeed += 10
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
ywalkspeed -= 10
if event.key == pygame.K_UP:
ywalkspeed += 10
if event.key == pygame.K_LEFT:
xwalkspeed += 10
if event.key == pygame.K_RIGHT:
xwalkspeed -= 10
player.x += xwalkspeed
player.y += ywalkspeed
distancebetween = 0
if player.colliderect(wall):
ywalkspeed = 0
xwalkspeed= 0
if player.top <= 0:
player.top = 0
if player.bottom >= shgt:
player.bottom = shgt
if player.left <= 0:
player.left = 0
if player.right >= swid:
player.right = swid
#Visuals
screen.fill(bgcol)
pygame.draw.ellipse(screen, playercol, player)
pygame.draw.rect(screen, wallcol, wall)
pygame.draw.rect(screen, doorcol, door)
pygame.draw.rect(screen, windowcol, window)
#Updating the Window
pygame.display.flip()
clock.tick(60)
Whenever my Object collides upon a wall, it starts moving the opposite way until it is no longer seen in the screen.
I Found the Reason why it kept moving the opposite way when it collides the wall. It is because if I move towards the wall, my ywalkspeed = 10 and when I collided with the wall, it becomes 0, then if I started to let go of the movement key, the ywalkspeed becomes ywalkspeed = -10. I currently don't know a way how to fix this as I am just a noob.
Make a copy of the original player rectangle with copy(). Move the player. If a collision is detected, restore the player rectangle:
copy_of_player_rect = player.copy()
# move player
# [...]
if player.colliderect(wall):
player = copy_of_player_rect
You can watch for the distance between the wall and the player and when the distance according to axis positions reaches zero, just do
xwalkspeed = 0
ywalkspeed = 0
To measure the distance and smooth realistic movement, you can also use equations of motion from Physics.
this is my first game I have created using pygame, it's basically snake.
Please do not mind my hideous comments.
## William's Snake Game
import pygame
import time
import random
pygame.init()
##Global variables
# Colours
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 155, 0)
bground = (204, 204, 0)
# Display vars.
display_width = 800
display_height = 600
# Variables
gameDisplay = pygame.display.set_mode((display_width, display_height)) ##resolution, note that this is a tuple.
pygame.display.set_caption("Snake VS Apple") # Title at the top of the screen
icon = pygame.image.load('logoapple32x32.png') # Loads the icon for the top left
pygame.display.set_icon(icon) # Sets the icon for the top left
snakeHeadImg = pygame.image.load("snakeHead.png") # Loads the image for the snake head
appleImg = pygame.image.load("apple20x20.png") # Loads the image for the apple
appleThickness = 20 # Defines how thick apple will be. Note to self: This is changable
clock = pygame.time.Clock() # Starts clocking the game, used later for FPS
blockSize = 20 # Defines how big the snake will be. Changing this will mess up collision detection.
FPS = 15 # Frames per second. Called at the bottom of script
smallfont = pygame.font.SysFont("arial", 25) ## format: ("font", fontsize)
medfont = pygame.font.SysFont("arial", 40) ##
largefont = pygame.font.SysFont("arial", 80) ##
direction = "right" # Starting direction of snake, used in main gameLoop
##
def pauseGame():
gameisPaused = True
while gameisPaused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
gameisPaused = False
elif event.key == pygame.K_q:
pygame.quit()
quit()
gameDisplay.fill(white)
message_to_screen("Paused",
black,
-100,
size="large")
message_to_screen("Press ESC to continue or Q to quit.",
black,
25,
size="small")
pygame.display.update()
clock.tick(5)
def text_objects(text, color, size): # Function to render text
if size == "small":
textSurface = smallfont.render(text, True, color)
elif size == "medium":
textSurface = medfont.render(text, True, color)
elif size == "large":
textSurface = largefont.render(text, True, color)
return textSurface, textSurface.get_rect()
def message_to_screen(msg, color, y_displace=0, size="medium"): # Function to blit (draw) text to surface
textSurf, textRect = text_objects(msg, color, size)
textRect.center = (display_width / 2), (display_height / 2) + y_displace
gameDisplay.blit(textSurf, textRect)
##
def score(score):
text = smallfont.render("Score: " + str(score), True, black)
gameDisplay.blit(text, [0, 0])
def randAppleGen(): # Function to generate random apples
randAppleX = round(
random.randrange(0, display_width - appleThickness)) # /10.0)*10.0 ##Create another rand X value for new apple
randAppleY = round(
random.randrange(0, display_height - appleThickness)) # /10.0)*10.0 ##Create another rand Y value for new apple
return randAppleX, randAppleY
def gameIntro(): # Function for game menu.
intro = True
while intro: # Event handling during menu
for eachEvent in pygame.event.get():
if eachEvent.type == pygame.QUIT:
pygame.quit()
quit()
if eachEvent.type == pygame.KEYDOWN:
if eachEvent.key == pygame.K_c:
gameLoop()
if eachEvent.key == pygame.K_q:
pygame.quit()
quit()
# Text displayed in menu
gameDisplay.fill(white)
message_to_screen("Welcome to Slither",
green,
-90,
"large")
message_to_screen("The more apples you eat, the longer you are",
black,
100)
message_to_screen("The objective of the game is to eat red apples",
black,
0,
"small")
message_to_screen("If you run into yourself, or the edges, you die!",
black,
30,
"small")
message_to_screen("Press C to play or Q to quit.",
black,
180)
pygame.display.update()
clock.tick(500)
def snake(blockSize, snakeList): # Function to draw snake
if direction == "right":
head = pygame.transform.rotate(snakeHeadImg,
270) # In gameLoop, right,left,up,down are used to change direction of snakeHead
elif direction == "left":
head = pygame.transform.rotate(snakeHeadImg, 90)
elif direction == "up":
head = snakeHeadImg
elif direction == "down":
head = pygame.transform.rotate(snakeHeadImg, 180)
gameDisplay.blit(head, (snakeList[-1][0], snakeList[-1][1])) ##???
for XandY in snakeList[:-1]:
pygame.draw.rect(gameDisplay, green,
[XandY[0], XandY[1], blockSize, blockSize]) ##width height, width height, drawing
##Main Game Loop
def gameLoop():
global direction ## Make direction a global var. Important
# Local variables
gameExit = False
gameOver = False
lead_x = display_width / 2
lead_y = display_height / 2
lead_x_change = 10
lead_y_change = 0
snakeList = []
snakeLength = 3
randAppleX, randAppleY = randAppleGen() # Generate apples. Calls randAppleGen()
# Main Game Loop ##eventHandler
while not gameExit:
snakeHead = [] # Creates list snakeHead
snakeHead.append(lead_x) # Appends snakeHead x value to list
snakeHead.append(lead_y) # Appends snakeHead y value to list
snakeList.append(snakeHead) # Appends coordinates of snakeHead x,y to list
while gameOver == True: # Handles game over
gameDisplay.fill(white)
message_to_screen("Game over",
red,
-50,
size="large")
message_to_screen("Press C to play again or Q to quit",
black,
50,
size="medium")
pygame.display.update()
for event in pygame.event.get(): # eventHandler for loss screen
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameExit = True
gameOver = False
if event.key == pygame.K_c:
direction = "right"
gameLoop()
for event in pygame.event.get(): # eventHandler for keyboard events during game
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == pygame.K_a: # Each of these handles either arrow keys or WASD key events.
lead_x_change = -blockSize
lead_y_change = 0
direction = "left"
elif event.key == pygame.K_RIGHT or event.key == pygame.K_d:
lead_x_change = blockSize
lead_y_change = 0
direction = "right"
elif event.key == pygame.K_UP or event.key == pygame.K_w:
lead_y_change = -blockSize
lead_x_change = 0
direction = "up"
elif event.key == pygame.K_DOWN or event.key == pygame.K_s:
lead_y_change = blockSize
lead_x_change = 0
direction = "down"
elif event.key == pygame.K_ESCAPE:
pauseGame()
# Checks if user has hit screen boundaries.
if lead_x >= display_width or lead_x < 0 or lead_y >= display_height or lead_y < 0: # If user hits display boundaries
gameOver = True # They lose
lead_x += lead_x_change # Ensures continous movement of the snake
lead_y += lead_y_change
# Drawing
gameDisplay.fill(bground) # Fills the display background with predefined bground colour (defined at the top)
gameDisplay.blit(appleImg,
(randAppleX, randAppleY)) ##Draws the apple using the appleImg, at random coordinates.
if len(
snakeList) > snakeLength: # If the length of the list of snake body coordinates is greater than the length
del snakeList[0] # Delete the oldest value in the list (as the snake is constantly moving)
for eachSegment in snakeList[:-1]: # For each coordinate in snakeList
if eachSegment == snakeHead: # If the segment touches the snakeHead
## gameDisplay.fill(bground)
## snake(blockSize, snakeList)
##
## pygame.display.update
time.sleep(0.3)
gameOver = True # Game over
snake(blockSize, snakeList) ##Creates snake using function snake
score(snakeLength - 3) # Displays score (it minuses 3 because the snake starts at 3)
pygame.display.update() ##Updates to screen
## COLLISION DETECTION
if lead_x + blockSize > randAppleX and lead_x < randAppleX + appleThickness:
if lead_y + blockSize > randAppleY and lead_y < randAppleY + appleThickness:
randAppleX, randAppleY = randAppleGen()
snakeLength += 1
clock.tick(FPS)
pygame.quit()
quit()
##update screen
##
gameIntro()
gameLoop()
##Code goes above.
I have a problem where if my snake is going right, and then it turns left, my snake will crash onto itself and the game will end.
I want to design this so when my snake is going right, it cannot simply turn left, crash into itself and end the game. So when it turns right, it can only turn up, down, or keep going right. So simply, I want to make it so it cannot run backwards into itself.
I have tried coding this in myself, and I have tried many methods but nothing has worked.
Please help!!
Without altering your code too much (and without testing), an easy way to get what you want is to add another condition to your key checks. If you alter the relevant code section as follows, all should be fine:
for event in pygame.event.get(): # eventHandler for keyboard events during game
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if (event.key == pygame.K_LEFT or event.key == pygame.K_a) and direction != "right": # Each of these handles either arrow keys or WASD key events.
lead_x_change = -blockSize
lead_y_change = 0
direction = "left"
elif (event.key == pygame.K_RIGHT or event.key == pygame.K_d) and direction != "left":
lead_x_change = blockSize
lead_y_change = 0
direction = "right"
elif (event.key == pygame.K_UP or event.key == pygame.K_w) and direction != "down":
lead_y_change = -blockSize
lead_x_change = 0
direction = "up"
elif (event.key == pygame.K_DOWN or event.key == pygame.K_s) and direction != "up":
lead_y_change = blockSize
lead_x_change = 0
direction = "down"
elif event.key == pygame.K_ESCAPE:
pauseGame()
Mind the parentheses around the or'd key checks!
I just wrote a snake game using pygame module.
After testing, I found that when I rapidly change the snake direction. E.g. pressing two arrow keys very fast to move snake body to next line or change to opposite direction, the snake doesn't respond accurately. Most of the time it will work, but there are few times snake doesn't move. I believe this is because of the low FPS, but if I increase it, the snake will move so fast.
Here is the code:
# snake game
import pygame, sys, random, time
# game initialization
check_errors = pygame.init()
if check_errors[1] > 0:
print('(!) Got {0} errors during initializing pygame \
exiting...'.format(check_errors[1]))
sys.exit(-1)
else:
print('(+) pygame successfully initialized.')
# game screen
screen_width = 750
screen_height = 495
game_screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Snake game')
# colors
red = pygame.Color(255, 0, 0) # game over
green = pygame.Color(0, 255, 0) # snake body
black = pygame.Color(0, 0, 0) # player score
white = pygame.Color(255, 255, 255) # game background
brown = pygame.Color(165, 42, 42) # food
# FPS controller
fps_controller = pygame.time.Clock()
# game variables
start_x = 300
start_y = 150
step = 15 # block width is 10
initial_body_length = 3
snake_head = [start_x, start_y] # snake start position [x, y]
# initialize snake body, index 0 contains the snake head
snake_body = [[start_x - i * step, start_y] for i in range(initial_body_length)]
score = 0
level = 1
food_pos = [random.randrange(2, screen_width / step - 1) * step, \
random.randrange(2, screen_height / step - 1) * step] # don't put food at the border of the screen
food_spawn = True
direction = 'RIGHT'
next_direction = direction # new direction after user hits keyboard
def draw_game_menu():
count = 3
my_font = pygame.font.SysFont('monaco', 60)
while True:
game_screen.fill(white)
start_surface = my_font.render('Start in {0} seconds.'.format(count), True, black)
start_rect = start_surface.get_rect()
start_rect.midtop = (screen_width / 2, 80)
game_screen.blit(start_surface, start_rect)
esc_surface = my_font.render('''Press Esc to exit during game.''', True, black)
esc_rect = esc_surface.get_rect()
esc_rect.midtop = (screen_width / 2, 150)
game_screen.blit(esc_surface, esc_rect)
pause_surface = my_font.render('''Press Space to pause the game.''', True, black)
pause_rect = pause_surface.get_rect()
pause_rect.midtop = (screen_width / 2, 220)
game_screen.blit(pause_surface, pause_rect)
pygame.display.flip() # update the game screen
time.sleep(1)
fps_controller.tick()
count -= 1
if count == 0: break
def draw_game_pause():
my_font = pygame.font.SysFont('monaco', 40)
while True:
pause_surface = my_font.render('Press Space to continue.', True, black)
pause_rect = pause_surface.get_rect()
pause_rect.midtop = (screen_width / 2, 150)
game_screen.blit(pause_surface, pause_rect)
pygame.display.flip()
fps_controller.tick()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE: return
def show_score(game_over=False):
my_font = pygame.font.SysFont('monaco', 40)
score_surface = my_font.render('Score: {0}'.format(score), True, black)
score_rect = score_surface.get_rect()
if game_over == False:
score_rect.midtop = (75, 10)
else:
score_rect.midtop = (screen_width / 2, 130)
game_screen.blit(score_surface, score_rect)
# game over function
def draw_game_over():
my_font = pygame.font.SysFont('monaco', 60)
GO_surface = my_font.render('Game Over !', True, red)
GO_rect = GO_surface.get_rect()
GO_rect.midtop = (screen_width/2, 60)
game_screen.blit(GO_surface, GO_rect)
show_score(game_over=True)
pygame.display.flip() # update the game screen
time.sleep(4)
pygame.quit() # quit the game
sys.exit() # exit the console
def get_food(food_pos, snake_body):
for block in snake_body:
if block[0] == food_pos[0] and block[1] == food_pos[1]:
return True
return False
# game start menu
draw_game_menu()
# main logic of the game
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN: # if user press any button
if event.key == pygame.K_RIGHT or event.key == ord('d'):
next_direction = 'RIGHT'
elif event.key == pygame.K_LEFT or event.key == ord('a'):
next_direction = 'LEFT'
elif event.key == pygame.K_UP or event.key == ord('w'):
next_direction = 'UP'
elif event.key == pygame.K_DOWN or event.key == ord('s'):
next_direction = 'DOWN'
elif event.key == pygame.K_ESCAPE: # if user choose to quit the game
pygame.event.post(pygame.event.Event(pygame.QUIT))
elif event.key == pygame.K_SPACE:
draw_game_pause()
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# validation of direction
if next_direction == 'RIGHT' and direction != 'LEFT':
direction = 'RIGHT'
elif next_direction == 'LEFT' and direction != 'RIGHT':
direction = 'LEFT'
elif next_direction == 'DOWN' and direction != 'UP':
direction = 'DOWN'
elif next_direction == 'UP' and direction != 'DOWN':
direction = 'UP'
# move snake head
if direction == 'RIGHT':
snake_head[0] += step
elif direction == 'LEFT':
snake_head[0] -= step
elif direction == 'DOWN':
snake_head[1] += step
elif direction == 'UP':
snake_head[1] -= step
# move snake body mechanism
# 1. insert a new block at the beginning of the body
# 2. check if snake has reached a food
# 2.1 if yes, then keep the modified body
# 2.2 if not, then delete the end of the body
snake_body.insert(0, list(snake_head))
if snake_head[0] == food_pos[0] and snake_head[1] == food_pos[1]:
food_spawn = False
score += 1
else:
snake_body.pop()
while food_spawn == False:
food_pos = [random.randrange(2, screen_width / step - 1) * step,
random.randrange(2, screen_height / step - 1) * step]
if get_food(food_pos, snake_body) == True:
food_spawn = False
else:
food_spawn = True
# fill game background
game_screen.fill(white)
# draw snake body
for pos in snake_body:
pygame.draw.rect(game_screen, green, pygame.Rect(pos[0], pos[1], step, step))
# draw food
pygame.draw.rect(game_screen, brown, pygame.Rect(food_pos[0], food_pos[1], step, step))
# check if snake hits the border
if (snake_head[0] > screen_width - step) or (snake_head[0] < 0) or \
(snake_head[1] > screen_height - step) or (snake_head[1] < 0):
draw_game_over()
# check if snake hits itself
for block in snake_body[1:]:
if snake_head[0] == block[0] and snake_head[1] == block[1]:
draw_game_over()
level = score//5 + 1
if level > 3:
level = 3
show_score(game_over=False)
pygame.display.flip()
if level == 1:
fps_controller.tick(8)
elif level == 2:
fps_controller.tick(10)
elif level == 3:
fps_controller.tick(12)
Please help to see if there is a way to improve, thanks.
First of all, you should try to use a single main loop.
While you're rendering the start or end screen, you can't interact with the window because no event loop runs. It's very annoying that you can't move or close the window during that time. Maybe take a look here for an example of how to handle this.
Second, really use a higher framerate, and don't tie the speed of your game objects to the frame rate.
There are several ways to handle this, an example is to use an event that signals when the snake should move. Here's an example I wrote for another question.
Here's a simple implementation for your current code:
MOVE_SNAKE = pygame.USEREVENT
pygame.time.set_timer(MOVE_SNAKE, 300)
# main logic of the game
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN: # if user press any button
if event.key == pygame.K_RIGHT or event.key == ord('d'):
next_direction = 'RIGHT'
elif event.key == pygame.K_LEFT or event.key == ord('a'):
next_direction = 'LEFT'
elif event.key == pygame.K_UP or event.key == ord('w'):
next_direction = 'UP'
elif event.key == pygame.K_DOWN or event.key == ord('s'):
next_direction = 'DOWN'
elif event.key == pygame.K_ESCAPE: # if user choose to quit the game
pygame.event.post(pygame.event.Event(pygame.QUIT))
elif event.key == pygame.K_SPACE:
draw_game_pause()
elif event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == MOVE_SNAKE:
# move snake head
if direction == 'RIGHT':
snake_head[0] += step
elif direction == 'LEFT':
snake_head[0] -= step
elif direction == 'DOWN':
snake_head[1] += step
elif direction == 'UP':
snake_head[1] -= step
# move snake body mechanism
# 1. insert a new block at the beginning of the body
# 2. check if snake has reached a food
# 2.1 if yes, then keep the modified body
# 2.2 if not, then delete the end of the body
snake_body.insert(0, list(snake_head))
if snake_head[0] == food_pos[0] and snake_head[1] == food_pos[1]:
food_spawn = False
score += 1
else:
snake_body.pop()
# validation of direction
if next_direction == 'RIGHT' and direction != 'LEFT':
direction = 'RIGHT'
elif next_direction == 'LEFT' and direction != 'RIGHT':
direction = 'LEFT'
elif next_direction == 'DOWN' and direction != 'UP':
direction = 'DOWN'
elif next_direction == 'UP' and direction != 'DOWN':
direction = 'UP'
while food_spawn == False:
food_pos = [random.randrange(2, screen_width / step - 1) * step,
random.randrange(2, screen_height / step - 1) * step]
if get_food(food_pos, snake_body) == True:
food_spawn = False
else:
food_spawn = True
# fill game background
game_screen.fill(white)
# draw snake body
for pos in snake_body:
pygame.draw.rect(game_screen, green, pygame.Rect(pos[0], pos[1], step, step))
# draw food
pygame.draw.rect(game_screen, brown, pygame.Rect(food_pos[0], food_pos[1], step, step))
# check if snake hits the border
if (snake_head[0] > screen_width - step) or (snake_head[0] < 0) or \
(snake_head[1] > screen_height - step) or (snake_head[1] < 0):
draw_game_over()
# check if snake hits itself
for block in snake_body[1:]:
if snake_head[0] == block[0] and snake_head[1] == block[1]:
draw_game_over()
new_level = score//5 + 1
if new_level != level:
pygame.time.set_timer(MOVE_SNAKE, 300 / new_level)
if new_level <= 3:
level = new_level
show_score(game_over=False)
pygame.display.flip()
fps_controller.tick(60)
See how easy it is now to control the speed of the snake: it moves now every 300ms.
I wrote this simple program on Raspberry Pi from the user guide. The problem is, that when I run it, Python says that video system not declared in line 29 (for event in pygame.event.get():). I tried initializing pygame twice, but it didn't work. Any suggestions how can I fix it?
#!/usr/bin/env python
import pygame, sys, time, random
from pygame.locals import *
pygame.init()
fpsClock = pygame.time.Clock()
playSurface = pygame.display.set_mode((640, 480))
pygame.display.set_caption('Raspberry Snake')
redColour = pygame.Color(255, 0, 0)
blackColour = pygame.Color(0, 0, 0)
whiteColour = pygame.Color(255, 255, 255)
greyColour = pygame.Color(150, 150, 150)
snakePosition = [100,100]
snakeSegments = [[100,100],[80,100],[60,100]]
raspberryPosition = [300,300]
raspberrySpawned = 1
direction = 'right'
changeDirection = direction
def gameOver():
gameOveerFont = pygame.font.Font('freesansbold.ttf', 72)
gameOverSurf = gameOverFont.render('Game Over', True, greyColour)
gameOverRect = gameOverSurf.get_rect()
gameOverRect.midtop = (320, 10)
playSurface.blit(gameOverSurf, gameOverRect)
pygame.display.flip()
time.sleep(5)
pygame.quit()
sys.exit()
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
elif event.type == KEYDOWN:
if event.key == K_RIGHT or event.key == ord('d'):
changeDirection = 'right'
if event.key == K_LEFT or event.key == ord('a'):
changeDirection = 'left'
if event.key == K_UP or event.key == ord('w'):
changeDirection = 'up'
if event.key == K_DOWN or event.key == ord('s'):
changeDirection = 'down'
if event.key == K_ESCAPE:
pygame.event.post(pygame.event.Event(QUIT))
if changeDirection == 'right' and not direction == 'left':
direction = changeDirection
if changeDirection == 'left' and not direction == 'right':
direction = changeDirection
if changeDirection == 'up' and not direction == 'down':
direction = changeDirection
if changeDirection == 'down' and not direction == 'up':
direction = changeDirection
if direction == 'right':
snakePosition[0] += 20
if direction == 'left':
snakePosition[0] -= 20
if direction == 'up':
snakePosition[1] -= 20
if direction == 'down':
snakePosition[1] += 20
snakeSegments.insert(0,list(snakePosition))
if snakePosition[0] == raspberryPosition[0] and snakePosition[1] == raspberryPosition[1]:
raspberrySpawned = 0
else:
snakeSegments.pop()
if raspberrySpawned == 0:
x = random.randrange(1,32)
y = random.randrange(1,24)
raspberryPosition = [int(x*20),int(y*20)]
raspberrySpawned = 1
playSurface.fill(blackColour)
for position in snakeSegments:
pygame.draw.rect(playSurface,whiteColour,Rect (position[0], position[1], 20, 20))
pygame.draw.rect(playSurface,redColour,Rect (raspberryPosition[0], raspberryPosition[1], 20, 20))
pygame.display.flip()
if snakePosition[0] > 620 or snakePosition[0] < 0:
gameOver()
if snakePosition[1] > 460 or snakePosition[1] < 0:
gameOver()
for snakeBody in snakeSegments[1:]:
if snakePosition[0] == snakeBody[0] and snakePosition[1] == snakeBody[1]:
gameOver()
fpsClock.tick(20)}
1) Have you installed PyGame correctly?
2) If so... explore around with the locals. See if there's a specific pygame.video initilization.
3) Or, try using another IDE, like IDLE
I hope I helped!
I'm making a game using the default Python IDLE and Pygame. I am creating a simple cat animation but there is a problem when I try to run the module. A black screen just appears and the heading just says 'Animation NOT RESPONDING', below I have listed the code used for this animation. Thanks for the help!
Thanks, just edited it, does this look better?
import pygame, sys
from pygame.locals import *
pygame.init()
FPS = 30
fpsClock = pygame.time.Clock()
# set up the window
DISPLAYSURF = pygame.display.set_mode((400, 300), 0, 32)
pygame.display.set_caption('Animation')
WHITE = (255, 255, 255)
catImg = pygame.image.load('cat.png')
catx = 10
caty = 10
direction = 'right'
while True: # the main game loop
DISPLAYSURF.fill(WHITE)
if direction == 'right':
catx += 5
if catx == 280:
direction = 'down'
elif direction == 'down':
caty += 5
if caty == 220:
direction = 'left'
elif direction == 'left':
catx -= 5
if caty == 10:
direction = 'up'
elif direction == 'up':
caty -= 5
if caty == 10:
direction = 'right'
DISPLAYSURF.blit(catImg, (catx, caty))
for event in pygame.eventget():
if event.type == QUIT:
pygame.exit()
sys.exit()
pygame.display.update()
fpsClock.tick(FPS)
You can re-edit your posts for typos, there's a link at the end.
The problem is event handling never is ran, unless both direction == 'up' and caty == 10. The window then stops responding, since it can't get messages.
while True: # the main game loop
# events
for event in pygame.event.get():
if event.type == QUIT:
pygame.exit()
sys.exit()
# movement
# ... snip ...
# drawing
DISPLAYSURF.fill(Color("white"))
DISPLAYSURF.blit(catImg, (catx, caty))
pygame.display.update()
fpsClock.tick(FPS)