I'm trying to make the snake game in python, but sadly my snake and my apples aren't appearing on the screen, all i see is a gray screen with nothing on it, can you help me out? thanks!
P.S - i would like an explanation as well about why my current code isn't working so i would avoid it in the future, thanks again.
import pygame, sys, random, time
from pygame.locals import *
pygame.init()
mainClock = pygame.time.Clock()
windowWidth = 500
windowHeight = 500
windowSurface = pygame.display.set_mode((windowWidth, windowHeight), 0, 32)
red = (255, 0, 0)
green = (0, 255, 0)
color = (100, 100, 100)
snakeHead = [250, 250]
snakePosition = [[250, 250],[240, 250],[230, 250]]
applePosition = [random.randrange(1,50)*10,random.randrange(1,50)*10]
def collisionBoundarias(snakeHead):
if snakeHead[0] >= 500 or snakeHead[0] < 0 or snakeHead[1] >= 500 or snakeHead[1] < 0:
return 1
else:
return 0
def collisionSelf(SnakePosition):
snakeHead = snakePosition[0]
if snakeHead in snakePosition[1:]:
return 1
else:
return 0
while True:
windowSurface.fill(color)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_RIGHT or event.key == pygame.K_d:
snakeHead[0] += 10
if event.type == pygame.K_LEFT or event.key == pygame.K_a:
snakeHead[0] -= 10
if event.type == pygame.K_UP or event.type == pygame.K_w:
snakeHead[1] += 10
if event.type == pygame.K_DOWN or event.type == pygame.K_s:
snakeHead[1] -= 10
def displaySnake(snakePosition):
for position in snakePosition:
pygame.draw.rect(windowSurface ,red,pygame.Rect(position[0],position[1],10,10))
def display_apple(windowSurface, applePosition, apple):
windowSurface.blit(apple ,(applePosition[0], applePosition[1]))
snakePosition.insert(0,list(snakeHead))
snakePosition.pop()
def displayFinalScore(displayText, finalScore):
largeText = pygame.font.Font('freesansbold.ttf',35)
TextSurf = largeText.render(displayText, True, (255, 255, 255))
TextRect = TextSurf.get_rect()
TextRect.center = ((windowWidth/2),(windowHeight/2))
windowSurface.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
def collisionApple(applePosition, score):
applePosition = [random.randrange(1,50)*10,random.randrange(1,50)*10]
score += 1
return applePosition, score
if snakeHead == applePosition:
applePosition, score = collisionApple(applePosition, score)
snakePosition.insert(0,list(snakeHead))
pygame.display.update()
clock = pygame.time.Clock()
clock.tick(20)
As mentioned in the comments, the objects don't appear because you never draw them by calling the displaySnake and display_apple functions. It also makes no sense to define these functions in the while loop again and again.
Here's a fixed version of the code. I've changed the movement code, so that the snake moves continually each frame. (It could still be improved, but I tried to keep it simple.)
import pygame, sys, random, time
from pygame.locals import *
pygame.init()
mainClock = pygame.time.Clock()
windowWidth = 500
windowHeight = 500
windowSurface = pygame.display.set_mode((windowWidth, windowHeight), 0, 32)
clock = pygame.time.Clock()
red = (255, 0, 0)
green = (0, 255, 0)
color = (100, 100, 100)
snakeHead = [250, 250]
snakePosition = [[250, 250],[240, 250],[230, 250]]
applePosition = [random.randrange(1,50)*10,random.randrange(1,50)*10]
apple = pygame.Surface((10, 10))
apple.fill(green)
score = 0
speed = 10
# Define a velocity variable (a list or better a pygame.Vector2).
velocity = pygame.Vector2(speed, 0)
def collisionBoundarias(snakeHead):
return snakeHead[0] >= 500 or snakeHead[0] < 0 or snakeHead[1] >= 500 or snakeHead[1] < 0
def collisionApple(applePosition, score):
applePosition = [random.randrange(1,50)*10,random.randrange(1,50)*10]
score += 1
return applePosition, score
def displaySnake(snakePosition):
for position in snakePosition:
pygame.draw.rect(windowSurface, red, pygame.Rect(position[0], position[1], 10, 10))
def display_apple(windowSurface, applePosition, apple):
windowSurface.blit(apple, (applePosition[0], applePosition[1]))
while True:
# Event handling.
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
# Replace `type` with `key`.
if event.key == pygame.K_RIGHT or event.key == pygame.K_d:
velocity.x = speed
velocity.y = 0
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
velocity.x = -speed
velocity.y = 0
if event.key == pygame.K_UP or event.key == pygame.K_w:
velocity.x = 0
velocity.y = -speed
if event.key == pygame.K_DOWN or event.key == pygame.K_s:
velocity.x = 0
velocity.y = speed
# Game logic.
snakeHead[0] += velocity.x # Update the x-position every frame.
snakeHead[1] += velocity.y # Update the y-position every frame.
snakePosition.insert(0, snakeHead)
snakePosition.pop()
if snakeHead == applePosition:
applePosition, score = collisionApple(applePosition, score)
snakePosition.insert(0, snakeHead)
# Drawing.
windowSurface.fill(color)
displaySnake(snakePosition)
display_apple(windowSurface, applePosition, apple)
pygame.display.update()
clock.tick(20)
Related
I am having problems with making a homing algorithm to move an enemy towards a player in a game. For some reason, the algorithm works sometimes, but as you move the player around, the enemy gets to points where it just stops even though there is still a difference between the player x and y variables and the enemy x and y variables (which the code should be applying to the enemy at all times). If you run the code you'll see what I mean.
Here is my code:
import pygame
import sys, os, random
from pygame.locals import *
from pygame import mixer
import math
clock = pygame.time.Clock()
screen_width = 700
screen_height = 700
screen = pygame.display.set_mode((screen_width, screen_height))
player_rect = pygame.Rect(200, 200, 10, 10)
moving_left = False
moving_right = False
moving_down = False
moving_up = False
hunter_rect = pygame.Rect(500, 500, 48, 60)
player_rect.x = 300
player_rect.y = 200
while True:
screen.fill((50, 50, 50))
#screen.blit(player, (player_rect.x, player_rect.y))
#screen.blit(hunter, (hunter_rect.x, hunter_rect.y))
pygame.draw.rect(screen, (255, 255, 255), player_rect)
pygame.draw.rect(screen, (255, 0, 0), hunter_rect)
#### getting the change in y and the change in x from enemy to player ###
ychange = (hunter_rect.y - player_rect.y)/100
xchange = (hunter_rect.x - player_rect.x)/100
hunter_rect.x -= xchange
hunter_rect.y -= ychange
if moving_left:
player_rect.x -= 4
if moving_right:
player_rect.x += 4
if moving_up:
player_rect.y -= 4
if moving_down:
player_rect.y += 4
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
pygame.quit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == K_a:
moving_left = True
if event.key == K_d:
moving_right = True
if event.key == K_s:
moving_down = True
if event.key == K_w:
moving_up = True
if event.type == KEYUP:
if event.key == K_a:
moving_left = False
if event.key == K_d:
moving_right = False
if event.key == K_w:
moving_up = False
if event.key == K_s:
moving_down = False
pygame.display.update()
clock.tick(60)
Since pygame.Rect is supposed to represent an area on the screen, a pygame.Rect object can only store integral data.
The coordinates for Rect objects are all integers. [...]
The fraction part of the movement gets lost when the movement is add to the position of the rectangle.
If you want to store object positions with floating point accuracy, you have to store the location of the object in separate variables and to synchronize the pygame.Rect object. round the coordinates and assign it to the location (e.g. .topleft) of the rectangle:
hunter_rect = pygame.Rect(500, 500, 48, 60)
hunter_x, hunter_y = hunter_rect.topleft
# [...]
while True:
# [...]
hunter_x -= xchange
hunter_y -= ychange
hunter_rect.topleft = round(hunter_x), round(hunter_y)
# [...]
Here is my code below. Every time when I try to increase the length, It does not seem to increase and when I run the game.
When I run the game, It sometimes makes the head of the snake flicker/blink certain times and when snake eats the food, still it does not increase the length instead of blinking little at certain times
I have attached code with my applied logic. Please is there any solution to this problem?
Here is my code with what I applied as the increase length logic:
Here is my logic:
import pygame
import time
import sys
import random
a = print("1) Easy")
b = print("2) Medium")
c = print("3) Hard")
while True:
difficulty = input("Enter Difficulty Level: ")
if difficulty == "1":
speed = 5
break
elif difficulty == "2":
speed = 6
break
elif difficulty == "3":
speed = 8
else:
print("Choose from Above Options Only!")
# Initialise Game
pygame.init()
clock = pygame.time.Clock()
# Screen and Window Size:
screen_width = 800
screen_height = 700
screen = pygame.display.set_mode((screen_width, screen_height))
caption = pygame.display.set_caption("Snake Game")
icon = pygame.image.load("snake.png")
pygame.display.set_icon(icon)
# Colors
red = (255, 0, 0)
blue = (0, 0, 255)
green = (0, 255, 0)
white = (255, 255, 255)
# Snake Editing
x1 = 350
y1 = 300
snake = pygame.Rect([x1, y1, 20, 20])
x1_change = 0
y1_change = 0
snake_size = 15
snk_list = []
snk_length = 1
# Snake Food
food_x = random.randint(30, screen_width - 40)
food_y = random.randint(30, screen_height - 40)
food_height = 15
food_width = 15
# Game State
game_over = True
# Game over
font = pygame.font.SysFont("freelansbold.tff", 64)
# Score Counter
score = 0
score_font = pygame.font.SysFont("chiller", 50)
# TO INCREASE SNAKE LENGTH LOGIC:
def plot_snake(gameWindow, color, snk_list, snake_size):
for x, y in snk_list:
pygame.draw.rect(gameWindow, color, [x, y, snake_size, snake_size])
def game_over_text(text, color):
x = font.render(text, True, (240, 0, 0))
screen.blit(x, [screen_width//2 - 135, screen_height//2 - 25])
def score_show():
text = score_font.render("Score: " + str(score), True, (255, 255, 255))
screen.blit(text, (20, 10))
def main_loop():
global x1, y1, x1_change, y1_change, game_over, food_x, food_y, score, speed, snk_list, snake_size, snk_length
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# User Input
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
x1_change = speed * -1
y1_change = 0
elif event.key == pygame.K_RIGHT or event.key == pygame.K_d:
x1_change = speed
y1_change = 0
elif event.key == pygame.K_UP or event.key == pygame.K_w:
y1_change = speed * -1
x1_change = 0
elif event.key == pygame.K_DOWN or event.key == pygame.K_s:
y1_change = speed
x1_change = 0
# Game Over Checking
if x1 >= screen_width or x1 < 0 or y1 >= screen_height or y1 < 0:
game_over = False
x1 += x1_change
y1 += y1_change
if abs(x1 - food_x) < 7 and abs(y1 - food_y) < 7:
score += 1
food_x = random.randint(30, screen_width - 40)
food_y = random.randint(30, screen_height - 40)
speed += 0.2
snk_length += 5
# Drawing On Screen
screen.fill((0, 0, 0))
pygame.draw.rect(screen, red, [x1, y1, 15, 15])
pygame.draw.rect(screen, green, [food_x, food_y, food_width, food_height])
score_show()
pygame.display.flip()
#SNAKE LENGTH LOGIC
head = []
head.append(x1)
head.append(y1)
snk_list.append(head)
if len(snk_list) > snk_length:
del snk_list[0]
plot_snake(screen, red, snk_list, snake_size)
# Final Initialisation
pygame.display.flip()
clock.tick(70)
# Main Game Loop
while game_over:
main_loop()
# Game_Over
screen.fill((0, 0, 0))
game_over_text("Game Over!!!", (255, 0, 0))
pygame.display.flip()
time.sleep(2)
pygame.quit()
quit()
The moving distance of the snake must be "snake_size":
def main_loop():
# [...]
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# User Input
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
x1_change = -snake_size
y1_change = 0
elif event.key == pygame.K_RIGHT or event.key == pygame.K_d:
x1_change = snake_size
y1_change = 0
elif event.key == pygame.K_UP or event.key == pygame.K_w:
y1_change = -snake_size
x1_change = 0
elif event.key == pygame.K_DOWN or event.key == pygame.K_s:
y1_change = snake_size
x1_change = 0
But use pygame.time.Clock to control the frames per second and thus the game speed.
def main_loop():
# [...]
clock.tick(speed)
Use pygame.Rect and collidrect to find the collision of the snake and the food. See also How to detect collisions between two rectangular objects or images in pygame. Increment snk_length, when a collision is detected:
def main_loop():
# [...]
global snk_length
# [...]
snake_rect = pygame.Rect(x1, y1, snake_size, snake_size)
food_rect = pygame.Rect(food_x, food_y, snake_size, snake_size)
if snake_rect.colliderect(food_rect):
snk_length += 1
score += 1
food_x = random.randint(30, screen_width - 40)
food_y = random.randint(30, screen_height - 40)
speed += 1
Follow the instructions of How do I chain the movement of a snake's body?. Put the new head position of the snake at the head of snk_list, but delete the elements at the tail:
def main_loop():
# [...]
#SNAKE LENGTH LOGIC
snk_list.insert(0, [x1, y1])
if len(snk_list) > snk_length:
del snk_list[-1]
Complete main_loop:
def main_loop():
global x1, y1, x1_change, y1_change, game_over, food_x, food_y, score, speed, snk_list, snake_size
global snk_length
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# User Input
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
x1_change = -snake_size
y1_change = 0
elif event.key == pygame.K_RIGHT or event.key == pygame.K_d:
x1_change = snake_size
y1_change = 0
elif event.key == pygame.K_UP or event.key == pygame.K_w:
y1_change = -snake_size
x1_change = 0
elif event.key == pygame.K_DOWN or event.key == pygame.K_s:
y1_change = snake_size
x1_change = 0
# Game Over Checking
if x1 >= screen_width or x1 < 0 or y1 >= screen_height or y1 < 0:
game_over = False
x1 += x1_change
y1 += y1_change
snake_rect = pygame.Rect(x1, y1, snake_size, snake_size)
food_rect = pygame.Rect(food_x, food_y, snake_size, snake_size)
if snake_rect.colliderect(food_rect):
snk_length += 1
score += 1
food_x = random.randint(30, screen_width - 40)
food_y = random.randint(30, screen_height - 40)
speed += 1
# Drawing On Screen
screen.fill((0, 0, 0))
pygame.draw.rect(screen, red, [x1, y1, 15, 15])
pygame.draw.rect(screen, green, [food_x, food_y, food_width, food_height])
score_show()
pygame.display.flip()
#SNAKE LENGTH LOGIC
snk_list.insert(0, [x1, y1])
if len(snk_list) > snk_length:
del snk_list[-1]
plot_snake(screen, red, snk_list, snake_size)
# Final Initialisation
pygame.display.flip()
clock.tick(speed)
I'm working on the basics of a game right now, but for some reason I cannot get my sprite to move. I know that it's registering when I'm pressing the key down, but the sprite for some reason just stays still.
import pygame
import sys
from pygame.locals import *
import time
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("RADICAL")
screen.fill(black)
imga = pygame.image.load('coina.png')
imgb = pygame.image.load('coinb.png')
sound = pygame.mixer.Sound('coin.mp3')
FPS = 80
imgx = 10
imgy = 10
pixMove = 10
steps = 0
x1 = 0
y1 = 0
keystate = pygame.key.get_pressed()
GameOver = False
while not GameOver:
screen.fill(white)
points = (steps)
font = pygame.font.SysFont(None, 30)
text = font.render('Score: '+str(points), True, black)
screen.blit(text, (0,0))
if steps % 2 == 0:
screen.blit(imga, (imgx, imgy))
else:
screen.blit(imgb, (imgx, imgy))
for event in pygame.event.get():
print event
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if keystate[pygame.K_UP]:
y1 -= pixMove
elif keystate[pygame.K_DOWN]:
y1 += pixMove
elif keystate[pygame.K_LEFT]:
x1 -= pixMove
elif keystate[pygame.K_RIGHT]:
x1 += pixMove
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x1 = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y1 = 0
steps +=1
if event.type == K_SPACE:
sound.play()
time.sleep(1)
sound.stop()
pygame.display.update()
fpsTime.tick(FPS)
Generally you blit() images on to the screen (pygame.display.set_mode()), for the changes to to reflect on the screen we call pygame.display.update(), In your case the game never comes the statement, which is out of while loop.
I have been coding a program, a survival game, on Python. I seem to have an issue with adding Images/Sprites. I am noticing the images blink. Any way to fix this?
import os
import pygame
import time
import random
from pygame.locals import *
launchLog = pygame.init()
print(launchLog)
white = (255,255,255)
black = (0,0,0)
red=(255,0,0)
blue=(0,0,255)
green=(0,255,0)
skin = (236,227,100)
size = 10
dependant = (green)
rate = 0.0018
weight = 100
bound_x = 600
bound_x2 = bound_x-size
bound_y = 600
bound_y2 = bound_y-size
screen = pygame.display.set_mode((bound_x,bound_y))
pygame.display.set_caption("Survival: EfEs Edition")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None,25)
x = 300
y = 300
roundX = x
roundY = y
img=pygame.image.load("pewds.png")
def hmn(x,y,size):
clothes = pygame.draw.rect(screen,skin,[x,y,size,size-size*2])
snake = pygame.draw.rect(screen, red, [x,y,size,size])
def mesg(msg,color):
txt = font.render(msg, True, color)
screen.blit(txt, [x,y-30])
display.flip(img)
def gameLoop():
global x
global y
jump = 1
quitted = False
starved = 100
eaten = False
restart = False
lead_change = 0
lead_y = 0
randF_x = random.randrange(0,bound_x)
randF_y = random.randrange(0,bound_y)
didX2=round(randF_x/10.0)*10.0
didY2=round(randF_y/10.0)*10.0
while not quitted:
screen.blit(img,(x,y -15))
screen.blit(img,(x,y -15))
pygame.display.update()
hmn(x,y,size)
starved=starved-rate
#print(starved)
if starved<0:
screen.fill(white)
mesg("You died of hunger! Press R to restart.",red)
pygame.display.flip()
time.sleep(0.3)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
starved = 100
pygame.display.update()
rate = 0.0018
x=300
y=300
for event in pygame.event.get():
#print(event)
if event.type == pygame.QUIT:
pygame.display.update()
quitted = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
lead_change = -.2
elif event.key == pygame.K_d:
lead_change = .2
elif event.key == pygame.K_w:
lead_y = .2
elif event.key == pygame.K_s:
lead_y = -0.2
if event.type == pygame.KEYUP:
if event.key == pygame.K_d or event.key == pygame.K_a:
lead_change = 0
#print(x)
#print(y)
elif event.key == pygame.K_ESCAPE:
#print("Quitting")
quitted = True
elif event.key == pygame.K_w or event.key == pygame.K_s:
#print(y)
lead_y=0
x += lead_change
y -= lead_y
roundX = x
roundY = y
global roundX
global roundY
didX=round(roundX/10)*10
didY=round(roundY/10)*10
screen.fill(white)
s = pygame.draw.rect(screen, red, [bound_x2/15,bound_y2/20, starved * 2, 50])
pygame.draw.rect(screen, dependant, [didX2,didY2,10,10])
pygame.display.update()
#boundary script
if x>bound_x2:
x=bound_x2
elif x<-1:
x=-1
elif y<2:
y=2
elif y>590:
y=590
hmn(x,y,size)
pygame.display.flip()
if didX == didX2 and didY==didY2:
didX2 = round(random.randrange(0,bound_x)/10)*10
didY2 = round(random.randrange(0,bound_y)/10)*10
global dependant
dependant = green
global starved
starved = starved +0.01
global weight
weight = weight + 3
elif weight>150:
mesg("Weight increased! You now get hungry faster.",black)
pygame.display.update()
global rate
rate = rate+0.0008
pygame.display.update()
clock.tick(55)
mesg("Leaving game", black)
screen.blit(img,(x,y-15))
pygame.display.update()
time.sleep(2)
pygame.quit()
quit()
gameLoop()`
Please excuse the bad coding, the game is only in it's earliest state.
The correct sequence is to:
draw everything you want to show on a frame (all the blit()s, draw()s), etc.
do only one of display.update() with a list of all the changed regions OR display.flip() to update the whole screen once you've drawn everything
tl;dr - don't mix draw()s with update()s.
I am following a youtube tutorial series, and I came across this problem with my pygame game. I made a function called messagetoscreen, and it works fine in the video, but it doesn't work for me.
Here is my code:
#Imports
import pygame
pygame.init()
pygame.font.init()
import sys
import random
import cx_Freeze
import time
#Variables
playerhealth = 100
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0 ,255, 0)
windowtitle = "Climber"
sizex = 1000
sizey = 700
rect1x = 500
rect1y = 350
rect1sizex = 50
rect1sizey = 50
rect1xchange = 0
rect1ychange = 0
clock = pygame.time.Clock()
fps = 600
font = pygame.font.SysFont(None, 25)
#Functions
def messagetoscreen (msg,color):
screentext = font.render(msg, True, color)
gamedisplay.blit(screentext , [sizex / 2, sizey / 2])
#Initialization
gamedisplay = pygame.display.set_mode((sizex, sizey))
pygame.display.set_caption(windowtitle)
#Game Loop
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
rect1ychange -= 1
elif event.key == pygame.K_a:
rect1xchange -= 1
elif event.key == pygame.K_s:
rect1ychange += 1
elif event.key == pygame.K_d:
rect1xchange += 1
if event.type == pygame.KEYUP:
if event.key == pygame.K_w:
rect1ychange = 0
elif event.key == pygame.K_a:
rect1xchange = 0
elif event.key == pygame.K_s:
rect1ychange = 0
elif event.key == pygame.K_d:
rect1xchange = 0
if rect1y > 650:
rect1y = 650
if rect1x > 950:
rect1x = 950
if rect1y < 0:
rect1y = 0
if rect1x < 0:
rect1x = 0
rect1x += rect1xchange
rect1y += rect1ychange
messagetoscreen("HAPPY", red)
gamedisplay.fill(white)
pygame.draw.rect(gamedisplay, green, (rect1x, rect1y, rect1sizex, rect1sizey))
pygame.display.update()
clock.tick(fps)
I would like to know how to fix my function, and anything else that could cause an error.
The answer is that I blitted the text to the screen before I filled gamedisplay with white. Remember to blit text after drawing a background.
Here is the code that draw graphics
in the while loop:
gamedisplay.fill(white)
pygame.draw.rect(gamedisplay, green, (rect1x, rect1y, rect1sizex, rect1sizey))
messagetoscreen("HAPPY", red)