The following code works to a certain extent. You can move the snake body around in any direction but the pellet or apple that it is supposed to eat won't draw on the screen. I would love any advice on how to fix this problem, or how to improve the game.
import sys, pygame, random, itertools, time
blu = (37,102,151)
red = (175,31,36)
bla = (0,0,0)
whi = (255, 255, 255)
pygame.mixer.init()
pygame.mixer.music.load('opening.wav')
pygame.mixer.music.play(-1)
class Board(object):
def __init__(self, screen):
self.screen = screen
self.size = screen.get_size()
self.bit = 32
self.keys= []
self.setStart()
#sets snake in initial position and put pellet in random position
def setStart(self):
width = self.size
height = self.size
self.sStart = [20, 20]
self.snake = Snake(self.sStart)
self.pellet = Pellet(self.newPelletPosition())
#runs game and sets snake speed
def run(self):
running = time.time()
pygame.mixer.init()
pygame.mixer.music.load('FU2.wav')
pygame.mixer.music.play(-1)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
self.move()
now = time.time()
if now >= running + .20:
running = now
self.update()
if self.boardBoundary() or self.snake.collision():
pygame.mixer.music.load('crash.wav')
pygame.mixer.music.play()
break
self.draw()
#allows us to use arrows for playing
def move(self):
keys = pygame.key.get_pressed()
if sum(keys) != 0:
self.keys = keys
#redraws pellet if appears where snake currently is
def update(self):
pelletCollision = self.pellet.position == self.snake.positions[0]
if pelletCollision:
self.pellet.position = self.newPelletPosition()
self.snake.update(self.directionKeys(), pelletCollision)
#allows us to use arrows while playing
def directionKeys(self):
if self.keys[pygame.K_LEFT]:
return [-self.bit, 0]
elif self.keys[pygame.K_RIGHT]:
return [self.bit, 0]
elif self.keys[pygame.K_UP]:
return [0, -self.bit]
elif self.keys[pygame.K_DOWN]:
return [0, self.bit]
else:
return [0, 0]
#gives pellet random position and avoids overlap with snake
def newPelletPosition(self):
x = self.randomPosition(0)
y = self.randomPosition(1)
for pos in self.snake.positions:
if [x, y] == pos:
return self.newPelletPosition()
return [x, y]
This following 3 lines of code doesn't work and I want it to. I rewrote it and somehow managed to get that one to not mess up the game display. Neither def randomPosition 's will draw a pellet on the game screen though.
#def randomPosition(self, coordinate):
#amount_bits = (self.size[coordinate] / self.bit - 1) /
#return random.randint(bit, max_size / bit) * self.bit
#!!!random position(this doesn't work)
def randomPosition(self, coordinate):
amount_bits = (self.size[coordinate] / self.bit - 1)
return random.randint(-500, 500) * self.bit
#see if snakehead hits edge of screen !!
def boardBoundary(self):
head_pos_x, head_pos_y = self.snake.positions[0]
return head_pos_x < 0 or head_pos_x > self.size[0] - self.bit or head_pos_y < 0 or head_pos_y > self.size[1] - self.bit
#draws screen, pellet, snake
def draw(self):
self.screen.fill((bla))
self.pellet.draw(self.screen)
self.snake.draw(self.screen)
pygame.display.flip()
class Snake(object):
def __init__(self, position, speed = [0,0]):
self.positions = [position]
self.speed = speed
#sets the position as long as the snake hasn't collided (.pop() removes and then returns)
def update(self, speed, pelletCollision = False):
self.set_speed(speed)
head_pos = self.newHeadPosition()
self.positions.insert(0, head_pos)
if not pelletCollision:
self.positions.pop()
#updates snake head position
def newHeadPosition(self):
current = self.positions[0]
return [current[0] + self.speed[0], current[1] + self.speed[1]]
#sets speed
def set_speed(self, speed):
if speed == [0, 0]:
pass
elif self.speed == [0, 0]:
self.speed = speed
elif abs(self.speed[0]) != abs(speed[0]):
self.speed = speed
#determines if snake collides with itself
def collision(self):
head_pos = self.positions[0]
for position in self.positions[1:]:
if position == head_pos:
return True
return False
#draws snake
def draw(self, screen):
bit = pygame.Surface((32, 32))
bit.fill((whi))
for position in self.positions:
screen.blit(bit, position)
class Pellet(object):
def __init__(self, position):
self.bit = pygame.Surface((32, 32))
self.position = position
def draw(self,screen):
self.bit.fill((blu))
screen.blit(self.bit, self.position)
class Menu(object):
def __init__(self, screen, items, background_color = (bla), font_size = 32, font_color = (whi)):
self.screen = screen
self.screen_width = screen.get_rect().width
self.screen_height = screen.get_rect().height
self.background_color = background_color
self.font = pygame.font.SysFont("comicsanms", 32)
self.font_color = font_color
self.items = []
#enumerate makes loop clearer, returns an iterator
#for i in range(len(items)):
#for index, item in enumerate(items):
for index, item in enumerate(items):
words = self.font.render(item, 1, font_color)
width = words.get_rect().width
height = words.get_rect().height
pos_x = (self.screen_width / 2) - (width / 2)
lol = len(items) * height
pos_y = (self.screen_height / 2) - (lol / 2) + (index * height)
self.items.append([item, words, (width, height), (pos_x, pos_y)])
#runs options at the start and end of game
def run(self):
loop = True
while loop:
for event in pygame.event.get():
if event.type == pygame.QUIT:
loop = False
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
loop = False
elif event.key == pygame.K_q:
loop = False
sys.exit()
self.screen.fill(self.background_color)
for name, label, (width, height), (pos_x, pos_y) in self.items:
self.screen.blit(label, (pos_x, pos_y))
pygame.display.flip()
#shows us stuff to do on game menu
def whilerun():
screen = pygame.display.set_mode((500, 500))
start_menu_stuff = ['ENTER to play', 'Q to quit']
end_menu_stuff = ['You Dead, Bro!','ENTER to play again','Q to quit'];
start_menu = Menu(screen, start_menu_stuff)
end_menu = Menu(screen, end_menu_stuff)
game = Board(screen)
while True:
start_menu.run()
game.run()
game.setStart()
end_menu.run()
if __name__ == "__main__":
pygame.init()
whilerun()
Any help or direction would be greatly appreciated, this is my first CS class so the code is very, very basic. I just don't know how to get the pellet to actually appear on the screen.
Your def newPelletPosition was always returning [x,y] and also randomPosition returned indexes out of your game world range. You can change the upper limits of the randint function to be more general to accommodate different world sizes.
Changed:
def newPelletPosition(self):
x = self.randomPosition(0)
y = self.randomPosition(1)
for pos in self.snake.positions:
if [x, y] == pos:
return self.newPelletPosition()
else:
return [x,y]
#!!!random position(this doesn't work)
def randomPosition(self, coordinate):
amount_bits = (self.size[coordinate] / self.bit - 1)
return random.randint(0, 500 -32)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.