I am building an asteroids-like game with python, but I'm running into trouble with keeping within the range of my possibleTurrets array. All I'm doing is iterating through the array, and when the edge cases outside of the array occur, I deal with them through:
if currentTurPos > 8:
currentTurPos = 8
elif currentTurPos < 0:
currenTurPos = 0
This is in reference to this array:
possibleTurrets = [ (x-27,y-2),
(x-26,y-5),
(x-25,y-8),
(x-23,y-12),
(x-20,y-14),
(x-18,y-15),
(x-15,y-17),
(x-13,y-19),
(x-11,y-21)
]
For some reason this code works fine on pygame.K_UP but not on pygame.K_DOWN and I have no idea why.
This seems like it should be really obvious, but I've spent an hour trying to fix it, and am drawing a blank. The issue is with my ufo function, and the currentTurPos variable.
# Libraries
import pygame
import time
import random
import os
# Initialize Pygame
pygame.init()
# Colors
white = (255,255,255)
black = (0,0,0)
red = (200,0,0)
blue = (0,0,255)
green = (34,177,76)
light_green = (0,255,0)
yellow = (200,200,0)
light_yellow = (255,255,0)
light_red = (255,0,0)
# Display
display_width = 800
display_height = 600
gameDisplay = pygame.display.set_mode((display_width,display_height))
#pygame.display.set_caption('Slither')
#icon = pygame.image.load('apple.bmp')
#pygame.display.set_icon(icon)
clock = pygame.time.Clock()
# Sprites
ufoWidth = 40
ufoHeight = 20
turretWidth = 5
turretHeight = 10
fps = 15 # Speed
# Fonts
smallFont = pygame.font.SysFont("comicsansms", 25)
medFont = pygame.font.SysFont("comicsansms", 50)
largeFont = pygame.font.SysFont("comicsansms", 80)
def ufo(x,y,turPos):
x = int(x)
y = int(y)
possibleTurrets = [ (x-27,y-2),
(x-26,y-5),
(x-25,y-8),
(x-23,y-12),
(x-20,y-14),
(x-18,y-15),
(x-15,y-17),
(x-13,y-19),
(x-11,y-21)
]
pygame.draw.circle(gameDisplay, blue, (x,y),int(ufoHeight/2))
pygame.draw.ellipse(gameDisplay, black, (x-ufoHeight, y, ufoWidth, ufoHeight))
pygame.draw.line(gameDisplay,blue,(x,y),possibleTurrets[turPos],turretWidth)
# Font sizes
def text_objects(text, color, size):
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()
# Displays a message: Requires message, color, y-displacement, and size arguments
def message_to_screen(msg, color, y_displace=0, size="small"):
textSurf, textRect = text_objects(msg, color, size)
textRect.center = (int(display_width/2), (int(display_height/2) + y_displace))
gameDisplay.blit(textSurf, textRect)
# Show button text
def text_to_button(msg,color, buttonx,buttony,buttonwidth,buttonheight,size="small"):
textSurf, textRect = text_objects(msg,color,size)
textRect.center = ((buttonx+(buttonwidth/2)), buttony+(buttonheight/2))
gameDisplay.blit(textSurf, textRect)
# On button hover
def button(text,x,y,width,height,inactive_color,active_color,action):
cursor = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + width > cursor[0] > x and y + height > cursor[1] > y:
pygame.draw.rect(gameDisplay,active_color,(x,y,width,height))
if click[0] == 1 and action != None:
if action == "play":
gameLoop()
if action == "controls":
game_controls()
if action == "quit":
pygame.quit()
quit()
else:
pygame.draw.rect(gameDisplay,inactive_color,(x,y,width,height))
text_to_button(text,black,x,y,width,height)
def game_controls():
gcont = True
while gcont:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_c:
intro = False
if event.key == pygame.K_q:
pygame.quit()
quit()
gameDisplay.fill(white)
message_to_screen("Controls", green, -100, size="large")
message_to_screen("Fire: Spacebar", black, -30, size="small")
message_to_screen("Move turret: Up and Down arrows", black, 10, size="small")
message_to_screen("Move UFO: Left and Right arrows", black, 50, size="small")
message_to_screen("Pause: P", black, 90, size="small")
button("Play",150,450,100,50, green, light_green, action="play")
button("Quit",550,450,100,50, red, light_red, action="quit")
pygame.display.update()
clock.tick(fps)
# Pauses game and gives continue and quit options
def pause():
paused = True
message_to_screen("Paused", black, -100, size="large")
message_to_screen("Press P to play, or Q to quit.", black, 25, size="small")
while paused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = False
elif event.key == pygame.K_q:
pygame.quit()
quit()
pygame.display.update()
clock.tick(fps)
# Keeps track of, and displays the score
def score(score):
text = smallFont.render(" Score: " + str(score), True, black)
gameDisplay.blit(text, [0,0])
# Barrier
def barrier():
xlocation = (display_width/2) + random.randint(-0.2*displayWidth,0.2*displayWidth)
# Intro screen - Title and directions
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_c:
intro = False
if event.key == pygame.K_q:
pygame.quit()
quit()
gameDisplay.fill(white)
message_to_screen("Welcome to UFO!", green, -100, size="large")
message_to_screen("The objective of the game is to search and destroy.", black, -30, size="small")
message_to_screen("Destroy your opponent before they destroy you.", black, 10, size="small")
message_to_screen("The more enemies you destroy, the harder they get.", black, 50, size="small")
button("Play",150,450,100,50, green, light_green, action="play")
button("Controls",350,450,100,50, yellow, light_yellow, action="controls")
button("Quit",550,450,100,50, red, light_red, action="quit")
pygame.display.update()
clock.tick(fps)
# Main game loop
def gameLoop():
gameExit = False
gameOver = False
mainUfoX = display_width * 0.9
mainUfoY = display_height * 0.9
ufoMove = 0
currentTurPos = 0
changeTur = 0
# Game over screen and changes for key inputs
while not gameExit:
if gameOver == True:
message_to_screen("Game over!", red, -50, size="large")
message_to_screen("Press C to play again, Q to quit.", black, 50, size="medium")
pygame.display.update()
while gameOver == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
gameOver = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameExit = True
gameOver = False
if event.key == pygame.K_c:
gameLoop()
# Make changes for specific key inputs
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
ufoMove = -5
elif event.key == pygame.K_RIGHT:
ufoMove = 5
elif event.key == pygame.K_UP:
changeTur = 1
elif event.key == pygame.K_DOWN:
changeTur = -1
elif event.key == pygame.K_p:
pause()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
ufoMove = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
changeTur = 0
gameDisplay.fill(white)
mainUfoX += ufoMove
currentTurPos += changeTur
if currentTurPos > 8:
currentTurPos = 8
elif currentTurPos < 0:
currenTurPos = 0
ufo(mainUfoX,mainUfoY,currentTurPos)
pygame.display.update()
clock.tick(fps)
# Quits
pygame.quit()
quit()
# Loads game intro screen
game_intro()
# gameLoop calls itself to begin game
gameLoop()
It was a typo (I'm an idiot).
currentTurPos was currenTurPos.
Lesson learned: complex variable names with repeating letters are dangerous.
Related
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!
This question already has answers here:
Add scrolling to a platformer in pygame
(4 answers)
Closed 5 years ago.
I'm a beginner at python and pygame. What would be a good condensed way to have a camera move with the play? (With the player being in the middle of the screen always) I've tried multiple things but they just don't work the way I want them to. Again I'm new so if it's a dumb question, let me know. Thanks in advance to anyone who bothers answering at all.
import pygame
import random
import time
pygame.init()
display_width = 1200
display_height = 1000
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
player_width = 24
player_height = 42
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Random RPG')
clock = pygame.time.Clock()
PMF = ("PlayerModel_Forward.png")
playerSprt = pygame.image.load(PMF)
def player(x,y):
gameDisplay.blit(playerSprt,(x,y))
def enemy1(enemy1x, enemy1y, enemy1w, enemy1h, color):
pygame.draw.rect(gameDisplay, color, [enemy1x, enemy1y, enemy1w, enemy1h])
def death():
message_display('Game Over')
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', 115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width/2), (display_height/2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
pygame.display.update()
game_loop()
def frames(fps):
font = pygame.font.SysFont(None, 25)
text = font.render(str(fps), True, black)
gameDisplay.blit(text,(0,0))
def xcoord(x_coord):
font = pygame.font.SysFont(None, 25)
text = font.render((str(x_coord)), True, black)
gameDisplay.blit(text,(display_width/2,0))
def ycoord(y_coord):
font = pygame.font.SysFont(None, 25)
text = font.render((str(y_coord)), True, black)
gameDisplay.blit(text,(display_width/2,25))
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def game_loop():
x = (display_width/2)
y = (display_height/2)
x_change = 0
y_change = 0
enemy1_startx = random.randrange(0, display_width)
enemy1_starty = random.randrange (0, display_height)
enemy1_x_change = random.randrange (-5,5)
enemy1_y_change = random.randrange (-5,5)
enemy1_width = 100
enemy1_height = 100
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
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
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
y_change = 5
elif event.key == pygame.K_UP:
y_change = -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN or event.key == pygame.K_UP:
y_change = 0
x+= x_change
y+= y_change
Fps = 30
#Logic
if gameExit == True:
pygame.quit()
quit()
if x > display_width - player_width or x < 0:
death()
if y > enemy1_starty and y < enemy1_starty + enemy1_width or y+player_width > enemy1_starty and y + player_width < enemy1_starty + enemy1_width:
if x > enemy1_startx and x < enemy1_startx + enemy1_width or x+player_width > enemy1_startx and x + player_width < enemy1_startx + enemy1_width:
death()
time.sleep(2)
game_loop()
if enemy1_starty > display_height or enemy1_starty < 0 or enemy1_startx > display_width or enemy1_startx < 0:
enemy1_starty = random.randrange (0, display_height)
enemy1_startx = random.randrange(0, display_width)
enemy1_x_change = random.randrange (-5,5)
enemy1_y_change = random.randrange (-5,5)
#Drawing:
gameDisplay.fill(black)
player(x,y)
enemy1 (enemy1_startx, enemy1_starty, enemy1_width, enemy1_height, red)
enemy1_starty += enemy1_y_change
enemy1_startx += enemy1_x_change
frames((Fps))
xcoord (x)
ycoord (y)
pygame.display.update()
clock.tick(Fps)
game_loop()
pygame.quit()
quit()
You're doing really well! I think you may have taken the wrong approach, because instead of an actual camera moving ( which is insanely difficult to implement), the same effect can be reached, by moving every other element on the screen. So when the user presses right, instead of the player moving right, move the enemy left!: relevant code:
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
enemy1_startx = enemy1_startx+10
elif event.key == pygame.K_RIGHT:
enemy1_startx = enemy1_startx-10
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
enemy1_starty = enemy1_starty - 10
elif event.key == pygame.K_UP:
enemy1_starty = enemy1_starty + 10
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN or event.key == pygame.K_UP:
y_change = 0
My program works fine but I can't update the score. This is for my project; I am on the last part and cant figure it out myself. I pasted the whole code for reference.
import pygame
import random
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
betmoney = 100
pygame.init()
pygame.mixer.init()
clock = pygame.time.Clock()
def menu():
done = True
while done:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
tracks()
elif event.key == pygame.K_F1:
about()
elif event.type == pygame.QUIT:
pygame.quit()
game_S.blit(bg, [0,0])
for i in range (30):
x = random.randrange(0, 700)
y = random.randrange(0, 700)
pygame.draw.circle(game_S, GREEN, [x,y], 5)
pygame.display.update()
game_S.blit(text, [170, 450])
pygame.display.flip()
game_S.blit(betm, [0,0])
pygame.display.flip()
clock.tick(10)
def win():
while True:
game_S.blit(winner, [0,0])
game_S.blit(text, [170, 450])
game_S.blit(betm, [0, 0])
pygame.display.flip()
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
menu()
elif event.type == pygame.QUIT:
pygame.quit()
clock.tick(10)
def loser():
while True:
game_S.blit(lose, [0,0])
game_S.blit(text, [170, 450])
pygame.display.flip()
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
menu()
elif event.type == pygame.QUIT:
pygame.quit()
clock.tick(10)
def tracks ():
pygame.time.wait(1000)
game_S.blit(track3, [0,0])
pygame.display.update()
pygame.time.wait(1000)
game_S.blit(track2, [0,0])
pygame.display.update()
pygame.time.wait(1000)
game_S.blit(track1, [0,0])
pygame.display.update()
pygame.time.wait(1000)
game_S.blit(trackgo, [0,0])
pygame.display.update()
pygame.time.wait(1000)
game_S.fill(WHITE)
game_S.blit(track, [0,0])
pygame.display.update()
game_S.blit(bet, [0, 230])
game_S.blit(en1, [0, 20])
game_S.blit(en2, [0, 80])
game_S.blit(en3, [0, 160])
game_S.blit(en4, [0, 295])
game_S.blit(en5, [0, 360])
game_S.blit(en6, [0, 440])
pygame.display.update
pygame.display.flip()
r1 = random.randrange(1,10)
r2 = random.randrange(1,10)
r3 = random.randrange(1,10)
r4 = random.randrange(1,10)
r5 = random.randrange(1,10)
r6 = random.randrange(1,10)
racemode(r1,r2,r3,r4,r5,r6,0)
def racemode(a,b,c,d,e,f,wow):
move = True
while move:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and wow <= 600:
game_S.blit(bet, [wow, 230])
wow +=5
pygame.display.update()
clock.tick(10)
continue
elif event.type == pygame.QUIT:
pygame.quit()
if a<= 600:
game_S.blit(en1, [a,20])
a += random.randrange(10,15)
pygame.display.update()
clock.tick(30)
if b<= 600:
game_S.blit(en2, [b,80])
b +=random.randrange(10,15)
pygame.display.update()
clock.tick(30)
if c<= 600:
game_S.blit(en3, [c,160])
c += random.randrange(10,15)
pygame.display.update()
clock.tick(30)
if d<= 600:
game_S.blit(en4, [d,295])
d+= random.randrange(10,15)
pygame.display.update()
clock.tick(30)
if e<= 600:
game_S.blit(en5, [e,360])
e+= random.randrange(10,15)
pygame.display.update()
clock.tick(30)
if f<=600:
game_S.blit(en6, [f,440])
f+=random.randrange(10,15)
pygame.display.update()
clock.tick(30)
if wow >= 600 and a <600 and b <600 and c<600 and d<600 and e<600 and f<600:
win()
elif wow < 600 and a>= 600 or b>=600 or c>= 600 or d >= 600 or e >= 600 or f >=600:
loser()
def about():
tan = True
game_S.fill(WHITE)
game_S.blit(ab, [0,0])
pygame.display.update()
texts = pygame.font.SysFont('Arial', 35, True, False)
fonts = pygame.font.SysFont('Calibri', 30, True, False)
tput1 = texts.render("ABOUT THE BETTING SYSTEM", True, BLACK)
tput2 = fonts.render("-> You are given $100 as starting money", True, RED)
tput3 = fonts.render("-> You can get +100 if you win" , True, RED)
tput3b = fonts.render("-> You will lose 100 if you lose", True, RED)
tput4 = fonts.render("-> You beat the game when you reach 1000", True, RED)
tput5 = fonts.render("-> GAME OVER if you got $0 money", True, RED)
back = font.render(" PRESS F1 to go Back", True, BLACK)
game_S.blit(tput1, [120,80])
pygame.display.update()
game_S.blit(tput2, [100,150])
pygame.display.update()
game_S.blit(tput3, [100,200])
pygame.display.update()
game_S.blit(tput3b, [100,250])
pygame.display.update()
game_S.blit(tput4, [100,300])
pygame.display.update()
game_S.blit(tput5, [100,350])
pygame.display.update()
while tan:
game_S.blit(back, [170,450])
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_F1:
menu()
elif event.type == pygame.QUIT:
pygame.quit()
clock.tick(10)
# Set the width and height of the screen [width, height]
size = (700, 500)
game_S = pygame.display.set_mode(size)
pygame.display.set_caption("BET ON YOUR TURTLE")
font = pygame.font.SysFont('Calibri', 34, True, False)
text = font.render("PRESS ENTER TO CONTINUE", True, RED)
betm = font.render(str(betmoney), 1, RED)
#---IMAGES----
bg = pygame.image.load("kim.png")
ab = pygame.image.load("waw.png")
bet = pygame.image.load("witwew.png").convert_alpha()
en1 = pygame.image.load("enemy1.png")
en2 = pygame.image.load("enemy2.png")
en3 = pygame.image.load("enemy3.png")
en4 = pygame.image.load("enemy4.png")
en5 = pygame.image.load("enemy5.png")
en6 = pygame.image.load("enemy6.png")
track = pygame.image.load("TRACK.png")
track3 = pygame.image.load("TRACK3.png")
track2 = pygame.image.load("TRACK2.png")
track1 = pygame.image.load("TRACK1.png")
trackgo = pygame.image.load("TRACKGO.png")
winner = pygame.image.load("winner.png")
lose = pygame.image.load("lose.png")
#--IMAGES (end)--
pygame.mixer.music.load("icecream_8bit.mp3")
pygame.mixer.music.play(-1)
menu()
You can see that I put betmoney as local variable with 100 value and don't know how to add 100 or deduct 100.
There are two ways to go about accessing the "betmoney" variable that come to mind. Firstly, simply pass it into the function that you plan on accessing it as an argument. This is generally the preferred way. Second, simply declare "betmoney" a global variable and it can be accessed from anywhere.
Hope you all are having a great day.
I am trying to detect a collision between my object (the black rectangle) and the food image.
What i want to basically do is whenever my rectangle collides with the food image, the food image is then placed randomly on the screen and the score gets increased by +1.
import pygame
import time
import random
pygame.init()
#Colours
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,155,0)
#Game Display
display_width = 800
display_height = 600
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('KALM Creation')
#Directions
DOWN='down'
UP='up'
LEFT='left'
RIGHT='right'
#Score
score=0
# My food image
foodimg=pygame.image.load("food.png")#.convert_alpha()
foodrect = foodimg.get_rect()
foodrect.centerx = 100
foodrect.centery = 200
#Our Icon For The Game
icon=pygame.image.load('icon1.jpg')
pygame.display.set_icon(icon)
#Clock
clock = pygame.time.Clock()
FPS = 30
cellSize=10
#Font Size
smallfont = pygame.font.SysFont("comicsansms", 25)
medfont = pygame.font.SysFont("comicsansms", 50)
largefont = pygame.font.SysFont("comicsansms", 80)
#The score function - displays the score on top right
def scoredisplay(scoredef=0):
text=smallfont.render("Score :%s" %(scoredef) ,True ,black)
gameDisplay.blit(text,[0,0])
#Starting Of the game
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key ==pygame.K_c:
intro = False
if event.key ==pygame.K_q:
pygame.quit()
quit()
gameDisplay.fill(white)
#Game Initial display message
message_to_screen("Welcome To Eat it Game",
green,
-200,
size="medium")
message_to_screen("Press 'C' to play the game or 'Q' to quit.",
black,
150,
size="small")
pygame.display.update()
clock.tick(15)
#Text Size
def text_objects(text,color, size):
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()
#Message to screen
def message_to_screen(msg,color,y_displace=0,size="small"):
textSurf,textRect=text_objects(msg,color,size)
textRect.center = (display_width / 2),(display_height / 2)+y_displace
gameDisplay.blit(textSurf,textRect)
#Drawing Cells
def drawCell(coords,ccolor):
for coord in coords:
x=coord['x']*cellSize
y=coord['y']*cellSize
makeCell=pygame.Rect(x,y,cellSize,cellSize)
pygame.draw.rect(gameDisplay,ccolor,makeCell)
#The Game run up
def runGame():
score=0
gameExit = False
gameOver = False
#Starting Position of the object
startx=3
starty=3
coords=[{'x':startx,'y':starty}]
direction = RIGHT
while not gameExit:
while gameOver == True:
#Game Over message
gameDisplay.fill(white)
message_to_screen("Game over",
red,
y_displace=-50,
size="large")
message_to_screen("Press C to play again or Q to quit",
black,
y_displace=50,
size="medium")
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameExit = True
gameOver = False
if event.key == pygame.K_c:
gameLoop()
#Game Controls
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
direction = LEFT
elif event.key == pygame.K_RIGHT:
direction = RIGHT
elif event.key == pygame.K_UP:
direction = UP
elif event.key == pygame.K_DOWN:
direction = DOWN
if direction == UP:
newCell={'x':coords[0]['x'],'y':coords[0]['y']-1}
elif direction == DOWN:
newCell={'x':coords[0]['x'],'y':coords[0]['y']+1}
elif direction == LEFT:
newCell={'x':coords[0]['x']-1,'y':coords[0]['y']}
elif direction == RIGHT:
newCell={'x':coords[0]['x']+1,'y':coords[0]['y']}
del coords[-1]
coords.insert(0, newCell)
gameDisplay.fill(white)
drawCell(coords,black)
clock.tick(FPS)
#If object moves outside the screen , game gets over.
if(newCell['x']<0 or newCell['y']<0 or newCell['x']>display_width/cellSize or newCell['y']>display_height):
gameOver= True
#Displays Score
scoredisplay(score)
gameDisplay.blit(foodimg,foodrect)
#pygame.display.flip()
pygame.display.update()
#The game run up
def gameLoop():
clock.tick(FPS)
runGame()
pygame.quit()
quit()
game_intro()
gameLoop()
In the drawcell() call:
if makecell.colliderect(foodrect):
foodrect.x = random.randint(0, sceeenwidth)
foodrect.y = random.randint(0, screenheight)
Should do it.
So I made a Nibbles/Snake remake by following the pygame tutorials on thenewboston youtube channel by sentdex. I made a lot of minor aesthetic changes, but overall, it's the same game. Here's the code for that:
import pygame
import time
import random
pygame.init()
# A few extra colors just for testing purposes.
WHITE = (pygame.Color("white"))
BLACK = ( 0, 0, 0)
RED = (245, 0, 0)
TURQ = (pygame.Color("turquoise"))
GREEN = ( 0, 155, 0)
GREY = ( 90, 90, 90)
SCREEN = (800, 600)
gameDisplay = pygame.display.set_mode(SCREEN)
#Set the window title and picture
pygame.display.set_caption('Slither')
ICON = pygame.image.load("apple10pix.png")
pygame.display.set_icon(ICON)
CLOCK = pygame.time.Clock()
FPS = 20
FONT = pygame.font.SysFont("arial", 25)
SNAKE_SIZE = 10 # The width of the snake in pixels, not the length. Start length is defined in the game loop.
APPLE_SIZE = 10
TINY_FONT = pygame.font.SysFont("candara", 15)
SMALL_FONT = pygame.font.SysFont("candara", 25)
MED_FONT = pygame.font.SysFont("candara", 50)
LARGE_FONT = pygame.font.SysFont("krabbypatty", 75)
HUGE_FONT = pygame.font.SysFont("krabbypatty", 150)
IMG = pygame.image.load("snakehead.png")
APPLE_IMG = pygame.image.load("apple10pix.png")
DIRECTION = "up"
def pause():
paused = True
message_to_screen("Paused",
BLACK,
Y_DISPLACE = -100,
size = "huge")
message_to_screen("Press C to continue or Q to quit.",
BLACK,
Y_DISPLACE = 25)
pygame.display.update()
while paused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key in (pygame.K_c, pygame.K_p):
paused = False
elif event.key in(pygame.K_q, pygame.K_ESCAPE):
pygame.quit()
quit()
CLOCK.tick(5)
def score(score):
text = SMALL_FONT.render("Score: " + str(score), True, BLACK)
gameDisplay.blit(text, [0, 0])
pygame.display.update
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_c:
intro = False
if event.key in (pygame.K_q, pygame.K_ESCAPE):
pygame.quit()
quit()
gameDisplay.fill(WHITE)
message_to_screen("Welcome to",
GREEN,
Y_DISPLACE = -170,
size = "large")
message_to_screen("Block Worm",
GREEN,
Y_DISPLACE = -50,
size = "huge")
message_to_screen("The objective of the game is to eat apples.",
BLACK,
Y_DISPLACE = 36,
size = "tiny")
message_to_screen("The more apples you eat the longer you get.",
BLACK,
Y_DISPLACE = 68,
size = "tiny")
message_to_screen("If you run into yourself or the edges, you die.",
BLACK,
Y_DISPLACE = 100,
size = "tiny")
message_to_screen("Press C to play or Q to quit.",
GREY,
Y_DISPLACE = 210,)
pygame.display.update()
CLOCK.tick(FPS)
def snake(SNAKE_SIZE, SNAKE_LIST):
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)
else:
DIRECTION == "up"
HEAD = IMG
gameDisplay.blit(HEAD, (SNAKE_LIST[-1][0], SNAKE_LIST[-1][1]))
for XnY in SNAKE_LIST[:-1]:
pygame.draw.rect(gameDisplay, GREEN, [XnY[0], XnY[1], SNAKE_SIZE, SNAKE_SIZE])
pygame.display.update
def text_objects(text, color, size):
if size == "tiny":
TEXT_SURFACE = TINY_FONT.render(text, True, color)
elif size == "small":
TEXT_SURFACE = SMALL_FONT.render(text, True, color)
elif size == "medium":
TEXT_SURFACE = MED_FONT.render(text, True, color)
elif size == "large":
TEXT_SURFACE = LARGE_FONT.render(text, True, color)
elif size == "huge":
TEXT_SURFACE = HUGE_FONT.render(text, True, color)
return TEXT_SURFACE, TEXT_SURFACE.get_rect()
def message_to_screen(msg, color, Y_DISPLACE = 0, size = "small"):
TEXT_SURF, TEXT_RECT = text_objects(msg, color, size)
TEXT_RECT.center = (SCREEN[0] / 2), (SCREEN[1] / 2) + Y_DISPLACE
gameDisplay.blit(TEXT_SURF, TEXT_RECT)
def randAppleGen():
randAppleX = random.randrange(0, (SCREEN[0] - APPLE_SIZE), APPLE_SIZE)
randAppleY = random.randrange(0, (SCREEN[1]- APPLE_SIZE), APPLE_SIZE)
return randAppleX, randAppleY
def gameLoop():
global DIRECTION
gameExit = False
gameOver = False
SNAKE_LIST = [] # Where the snake head has been.
SNAKE_LENGTH = 1 #Length that the snake starts.
lead_x = (SCREEN[0] / 2)
lead_y = (SCREEN[1] - (SCREEN[1] / 5))
move_speed = 10
move_speed_neg = move_speed * -1
lead_x_change = 0
lead_y_change = -move_speed
randAppleX, randAppleY = randAppleGen()
while not gameExit:
if gameOver == True:
message_to_screen("Game over",
RED,
Y_DISPLACE = -50,
size = "huge")
message_to_screen("Press C to play again or Q to quit.",
BLACK,
Y_DISPLACE = 50,
size = "small")
pygame.display.update()
while gameOver == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
gameOver = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameOver = False
gameExit = True
elif event.key == pygame.K_c:
gameLoop()
# Handles arrow key and WASD events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
elif event.type == pygame.KEYDOWN:
if event.key in (pygame.K_LEFT, pygame.K_a):
lead_x_change = move_speed_neg
lead_y_change = 0
DIRECTION = "left"
elif event.key in (pygame.K_RIGHT, pygame.K_d):
lead_x_change = move_speed
lead_y_change = 0
DIRECTION = "right"
elif event.key in (pygame.K_UP, pygame.K_w):
lead_y_change = move_speed_neg
lead_x_change = 0
DIRECTION = "up"
elif event.key in (pygame.K_DOWN, pygame.K_s):
lead_y_change = move_speed
lead_x_change = 0
DIRECTION = "down"
elif event.key in (pygame.K_p, pygame.K_ESCAPE):
pause()
# If the snake goes beyond the screen borders the game will end.
if lead_x >= SCREEN[0] or lead_x < 0 or lead_y >= SCREEN[1] or lead_y <0:
gameOver = True
lead_x += lead_x_change
lead_y += lead_y_change
gameDisplay.fill(WHITE)
# Draw the apple on screen
APPLE_RECT = pygame.draw.rect(gameDisplay, RED, [randAppleX, randAppleY, APPLE_SIZE, APPLE_SIZE])
if APPLE_RECT in SNAKE_LIST:
APPLE_RECT #If the apple appears anywhere "under" the snake, it will immediately respawn elsewhere.
# Draw the snake on screen
SNAKE_HEAD = []
SNAKE_HEAD.append(lead_x)
SNAKE_HEAD.append(lead_y)
SNAKE_LIST.append(SNAKE_HEAD)
# If you hit yourself, game over.
if SNAKE_HEAD in SNAKE_LIST[:-1]:
gameOver = True
if len(SNAKE_LIST) > SNAKE_LENGTH:
del SNAKE_LIST[0]
snake(SNAKE_SIZE, SNAKE_LIST)
score(SNAKE_LENGTH - 1)
# If the snake eats the apple
if APPLE_RECT.collidepoint(lead_x, lead_y) == True:
randAppleX, randAppleY = randAppleGen()
SNAKE_LENGTH += 1
pygame.display.update()
CLOCK.tick(FPS)
pygame.quit()
quit()
game_intro()
gameLoop()
It's a pretty solid little game. But I want to make the snake and apple into classes so that I can later spawn other types of snakes (perhaps basic AI?) and other types of apples (maybe ones that are green that grow your snake 3+). I made an attempt at doing this myself with a snake class:
import pygame
import time
import random
pygame.init()
WHITE = (pygame.Color("white"))
BLACK = ( 0, 0, 0)
RED = (245, 0, 0)
TURQ = (pygame.Color("turquoise"))
GREEN = ( 0, 155, 0)
GREY = ( 90, 90, 90)
SCREEN = (800, 600)
gameDisplay = pygame.display.set_mode(SCREEN)
#Set the window title and picture
pygame.display.set_caption('Block Worm')
ICON = pygame.image.load("apple10pix.png")
pygame.display.set_icon(ICON)
CLOCK = pygame.time.Clock()
FPS = 20
FONT = pygame.font.SysFont("arial", 25)
APPLE_SIZE = 10
TINY_FONT = pygame.font.SysFont("candara", 15)
SMALL_FONT = pygame.font.SysFont("candara", 25)
MED_FONT = pygame.font.SysFont("candara", 50)
LARGE_FONT = pygame.font.SysFont("krabbypatty", 75)
HUGE_FONT = pygame.font.SysFont("krabbypatty", 150)
IMG = pygame.image.load("snakehead.png")
APPLE_IMG = pygame.image.load("apple10pix.png")
def pause():
paused = True
message_to_screen("Paused",
BLACK,
Y_DISPLACE = -100,
size = "huge")
message_to_screen("Press C to continue or Q to quit.",
BLACK,
Y_DISPLACE = 25)
pygame.display.update()
while paused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key in (pygame.K_c, pygame.K_p):
paused = False
elif event.key in(pygame.K_q, pygame.K_ESCAPE):
pygame.quit()
quit()
CLOCK.tick(5)
def score(score):
text = SMALL_FONT.render("Score: " + str(score), True, BLACK)
gameDisplay.blit(text, [5, 5])
pygame.display.update
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_c:
intro = False
if event.key in (pygame.K_q, pygame.K_ESCAPE):
pygame.quit()
quit()
gameDisplay.fill(WHITE)
message_to_screen("Welcome to",
GREEN,
Y_DISPLACE = -170,
size = "large")
message_to_screen("Block Worm",
GREEN,
Y_DISPLACE = -50,
size = "huge")
message_to_screen("The objective of the game is to eat apples.",
BLACK,
Y_DISPLACE = 36,
size = "tiny")
message_to_screen("The more apples you eat the longer you get.",
BLACK,
Y_DISPLACE = 68,
size = "tiny")
message_to_screen("If you run into yourself or the edges, you die.",
BLACK,
Y_DISPLACE = 100,
size = "tiny")
message_to_screen("Press C to play or Q to quit.",
GREY,
Y_DISPLACE = 210,)
pygame.display.update()
CLOCK.tick(FPS)
def text_objects(text, color, size):
if size == "tiny":
TEXT_SURFACE = TINY_FONT.render(text, True, color)
elif size == "small":
TEXT_SURFACE = SMALL_FONT.render(text, True, color)
elif size == "medium":
TEXT_SURFACE = MED_FONT.render(text, True, color)
elif size == "large":
TEXT_SURFACE = LARGE_FONT.render(text, True, color)
elif size == "huge":
TEXT_SURFACE = HUGE_FONT.render(text, True, color)
return TEXT_SURFACE, TEXT_SURFACE.get_rect()
def message_to_screen(msg, color, Y_DISPLACE = 0, size = "small"):
TEXT_SURF, TEXT_RECT = text_objects(msg, color, size)
TEXT_RECT.center = (SCREEN[0] / 2), (SCREEN[1] / 2) + Y_DISPLACE
gameDisplay.blit(TEXT_SURF, TEXT_RECT)
def randAppleGen():
randAppleX = random.randrange(0, (SCREEN[0] - APPLE_SIZE), APPLE_SIZE)
randAppleY = random.randrange(0, (SCREEN[1]- APPLE_SIZE), APPLE_SIZE)
return randAppleX, randAppleY
class Snake:
def __init__(self, image, x, y, direction, speed):
self.image = image
self.rect = self.image.get_rect()
self.width = self.rect.width
self.rect.x = x
self.rect.y = y
self.direction = direction
self.speed = speed
self.trail = [] # Where the snake head has been.
self.length = 1 # Length that the snake starts.
def snake_direction_change(direction):
if direction == "right":
self.image = pygame.transform.rotate(self.image, 270)
elif direction == "left":
self.image = pygame.transform.rotate(self.image, 90)
elif direction == "down":
self.image = pygame.transform.rotate(self.image, 180)
else:
direction == "up"
pygame.display.update
def snake_grow(x, y, z):
gameDisplay.blit(self.image, (self.trail[-1][0], self.trail[-1][1]))
for XnY in snake.trail[:-1]:
pygame.draw.rect(gameDisplay, GREEN, [XnY[0], XnY[1], self.width, self.width])
pygame.display.update
def gameLoop():
gameExit = False
gameOver = False
lead_x_change = 0
lead_y_change = -snake.speed
randAppleX, randAppleY = randAppleGen()
gameDisplay.fill(WHITE)
snake = Snake(IMG,
x = (SCREEN[0] / 2),
y =(SCREEN[1] - (SCREEN[1] / 5)),
direction = "up",
speed = 10,)
while not gameExit:
if gameOver == True:
message_to_screen("Game over",
RED,
Y_DISPLACE = -50,
size = "huge")
message_to_screen("Press C to play again or Q to quit.",
BLACK,
Y_DISPLACE = 50,
size = "small")
pygame.display.update()
while gameOver == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
gameOver = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameOver = False
gameExit = True
elif event.key == pygame.K_c:
gameLoop()
# Handles arrow key and WASD events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
elif event.type == pygame.KEYDOWN:
if event.key in (pygame.K_LEFT, pygame.K_a):
lead_x_change = snake.speed * -1
lead_y_change = 0
snake.snake_direction_change("left")
elif event.key in (pygame.K_RIGHT, pygame.K_d):
lead_x_change = snake.speed
lead_y_change = 0
snake.snake_direction_change("right")
elif event.key in (pygame.K_UP, pygame.K_w):
lead_y_change = snake.speed * -1
lead_x_change = 0
snake.snake_direction_change("up")
elif event.key in (pygame.K_DOWN, pygame.K_s):
lead_y_change = snake.speed
lead_x_change = 0
snake.snake_direction_change("down")
elif event.key in (pygame.K_p, pygame.K_ESCAPE):
pause()
# If the snake goes beyond the screen borders the game will end.
if snake.rect.x >= SCREEN[0] or snake.rect.x < 0 or snake.rect.y >= SCREEN[1] or snake.rect.y <0:
gameOver = True
snake.rect.x += lead_x_change
snake.rect.y += lead_y_change
gameDisplay.fill(WHITE)
# Draw the apple on screen
APPLE_RECT = pygame.draw.rect(gameDisplay, RED, [randAppleX, randAppleY, APPLE_SIZE, APPLE_SIZE])
if APPLE_RECT in snake.trail:
APPLE_RECT #If the apple appears anywhere "under" the snake, it will immediately respawn elsewhere.
# Draw the snake on screen
SNAKE_HEAD = []
SNAKE_HEAD.append(snake.rect.x)
SNAKE_HEAD.append(snake.rect.y)
snake.trail.append(SNAKE_HEAD)
# If you hit yourself, game over.
if SNAKE_HEAD in snake.trail[:-1]:
gameOver = True
if len(snake.trail) > snake.length:
del snake.trail[0]
snake.snake_grow(snake.width, snake.trail)
score(snake.length - 1)
# If the snake eats the apple
if APPLE_RECT.collidepoint(snake.rect.x, snake.rect.y) == True:
randAppleX, randAppleY = randAppleGen()
snake.length += 1
pygame.display.update()
CLOCK.tick(FPS)
pygame.quit()
quit()
game_intro()
gameLoop()
This version isn't nearly as cute. In fact, it doesn't work at all. My understanding off classes and functions is elementary at best. A lot of code from the original was changed or completely deleted in my trial and error processes. I spent several hours trying to make this work to no avail. My main goal was to produce a Snake and Apple class that can be reused for later variations of both of them.
So, I've come to you fine folks to assist me! I have two main questions:
1) What do I have to do to make this work properly?
2) How can I clean up my code to make it easier to read and more efficient overall?
"A lot of code from the original was changed or completely deleted in my trial and error processes"
Bingo. You just found the crux of your issue. Software development should be a controlled, thought out process - not trial and error. You need to proceed thoughtfully, and purposefully.
What you are trying to do (or should be trying to do) when introducing classes is refactoring your code.
You should start again with the original, working copy, and proceed to change as little as possible when you introduce a Snake class. The first step would be to simply convert your snake function into a class, and substitute that in. Below is where you might start: replace your snake method with this Snake class, and change the line where you use it
class Snake:
def __init__(self, SNAKE_SIZE, SNAKE_LIST):
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)
else:
DIRECTION == "up" # note: this line does nothing
HEAD = IMG
gameDisplay.blit(HEAD, (SNAKE_LIST[-1][0], SNAKE_LIST[-1][1]))
for XnY in SNAKE_LIST[:-1]:
pygame.draw.rect(gameDisplay, GREEN, [XnY[0], XnY[1], SNAKE_SIZE, SNAKE_SIZE])
pygame.display.update # note: this likely does nothing - I think you want to call it (pygame.display.update())
and change this:
snake(SNAKE_SIZE, SNAKE_LIST)
into:
snake = Snake(SNAKE_SIZE, SNAKE_LIST)
Now at this point, if your code worked before, it should still work (assuming I haven't done anything silly). Is this a good example of a class? No. My Snake class is terrible. Your attempt at a snake class is far, far better. Doing things this way gives you a starting point though. You can then proceed to do things like:
assign the parameters to instance variables
move pretty much all the code into another method
start removing the module-level variables it has access to, and pass in additional arguments
etc.
An alternate way to refactor this module might be to change each of your functions so that none of them rely on module level variables. Pass every variable that each function needs into that function.
The main point I'd like to leave you with is that it is far easier to make working software by writing/changing just a little at a time. Make sure it still works before changing something else. Work on small bits of code & test each change so you'll know exactly where and how your program broke.