I have created a class which defines and creates a snake using pygame. When I make one instance of the snake class, one snake will be correctly created, but when I try to make two instances, my code will not make the second snake. I'm not sure if this is because I used pygame wrongly, or because I'm doing something wrong in the classes.
Here's my code; it's a little bit long, but I've included it all because I don't know where the problem is. I'm quite sure that I'm handling all the variables and arguments correctly, and handling the keypresses is correct as well. If you copy and paste this code into the interpreter, it works fine if you say you want one snake, but doesn't work when you want to create two snakes.
import os
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"; import pygame
import random
import time
import copy
black = pygame.Color(0, 0, 0)
class Snake():
def __init__(self, game_window, controls, color, position, speed, window_specs,can_touch=True,respawn=True):
self.game_window = game_window
self.color = color
self.window_x = window_specs[0]
self.window_y = window_specs[1]
self.can_touch = can_touch
self.respawn = respawn
self.snake_position = position.copy()
self.snake_body = [position.copy()]
self.speed = speed
self.controls = controls.copy()
self.direction = 'RIGHT'
self.change_to = self.direction
self.moving = True
self.fps = pygame.time.Clock()
self.start_moving()
def start_moving(self):
#Handles the controls and movement. Control first snake with 'wasd'. Control second snake with arrow keys.
while self.moving == True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == self.controls[0]:
self.change_to = 'UP'
if event.key == self.controls[1]:
self.change_to = 'LEFT'
if event.key == self.controls[2]:
self.change_to = 'DOWN'
if event.key == self.controls[3]:
self.change_to = 'RIGHT'
if self.change_to == 'UP' and self.direction != 'DOWN':
self.direction = 'UP'
if self.change_to == 'DOWN' and self.direction != 'UP':
self.direction = 'DOWN'
if self.change_to == 'LEFT' and self.direction != 'RIGHT':
self.direction = 'LEFT'
if self.change_to == 'RIGHT' and self.direction != 'LEFT':
self.direction = 'RIGHT'
if self.direction == 'UP':
self.snake_position[1] -= 10
if self.direction == 'LEFT':
self.snake_position[0] -= 10
if self.direction == 'DOWN':
self.snake_position[1] += 10
if self.direction == 'RIGHT':
self.snake_position[0] += 10
self.snake_body.insert(0, list(self.snake_position))
self.snake_body.pop()
self.game_window.fill(black)
for pos in self.snake_body:
pygame.draw.rect(self.game_window,self.color,pygame.Rect(pos[0],pos[1],10,10))
#Toggles whether snake will die if touching itself
if self.can_touch == False:
for block in self.snake_body[1:]:
if self.snake_position[0] == block[0] and self.snake_position[1] == block[1]:
self.die()
#Kills snake if snake touches the edge of the window
if self.snake_position[0] < 0 or self.snake_position[0] > (self.window_x - 10):
self.die()
if self.snake_position[1] < 0 or self.snake_position[1] > (self.window_y - 10):
self.die()
pygame.display.update()
self.fps.tick(self.speed)
def die(self):
#Reset the snake
self.moving = False
self.game_window.fill(black)
self.snake_body = []
self.position = []
pygame.display.update()
time.sleep(1)
#Makes the snake respawn in a random location
if self.respawn == True:
self.direction = 'RIGHT'
self.change_to = self.direction
self.snake_position = [random.randrange(1, (self.window_x//100)) * 10,
random.randrange(1, (self.window_y//100)) * 10]
self.snake_body = [self.snake_position.copy()]
self.moving = True
self.start_moving()
class App():
def __init__(self,num_players,can_touch=True,respawn=True):
self.controls = [[pygame.K_w, pygame.K_a, pygame.K_s, pygame.K_d],
[pygame.K_UP,pygame.K_LEFT,pygame.K_DOWN,pygame.K_RIGHT]]
self.starting_positions = [[100,50], [200, 100]]
self.speed = 15
self.window_specs = [720,480]
self.num_players = num_players
self.can_touch = can_touch
self.respawn = respawn
self.players = {}
#Start up pygame
pygame.init()
pygame.display.set_caption('Snake Game')
self.game_window = pygame.display.set_mode((self.window_specs[0], self.window_specs[1]))
self.get_players()
def get_players(self):
#Let the players choose what color they want
player_color = []
for i in range(self.num_players):
player_color.append(input(f'Player {i+1}, what color do you want your snake to be? '))
if player_color[i] == 'red':
player_color[i] = pygame.Color(255,0,0)
elif player_color[i] == 'green':
player_color[i] = pygame.Color(0,255,0)
elif player_color[i] == 'blue':
player_color[i] = pygame.Color(0,0,255)
else:
player_color[i] = pygame.Color(255,255,255)
#Create the Snakes, this is the bit that does not work.
for i in range(self.num_players):
self.players[f'player{i+1}'] = Snake(self.game_window,self.controls[i],player_color[i],self.starting_positions[i],self.speed,self.window_specs)
if __name__ == "__main__":
num_players = int(input('1 or 2 players: '))
App(num_players)
