Pygame Snake Game,让课程画在屏幕上

时间:2016-11-19 21:06:48

标签: python class pygame

以下代码在一定程度上起作用。你可以向任何方向移动蛇体,但应该吃的颗粒或苹果不会在屏幕上画画。我很想知道如何解决这个问题,或者如何改进游戏。

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]

以下3行代码不起作用,我想要它。我重写了它,并以某种方式设法得到那个不搞乱游戏显示。虽然def randomPosition也不会在游戏画面上画一个弹丸。

    #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()

非常感谢任何帮助或方向,这是我的第一个CS课程,因此代码非常非常基础。我只是不知道如何让颗粒实际出现在屏幕上。

1 个答案:

答案 0 :(得分:0)

你的def newPelletPosition总是返回[x,y],并且randomPosition也会返回游戏世界范围之外的索引。您可以将randint函数的上限更改为更一般,以适应不同的世界大小。

已更改:

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)