Pygame-怪蛇

时间:2018-10-18 04:27:47

标签: python pygame

import random
import sys
import pygame
from pygame.locals import *

pygame.init()

pygame.mouse.set_visible(False)

grid = list(range(0, 581, 20))

screenW, screenH = 600, 600
fodrawn_snake = False

wn = pygame.display.set_mode((screenW, screenH))
pygame.display.set_caption("Snake @codingeagle")

class player(object):
    def __init__(self, x, y, w, h):
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.xvel = 20
        self.yvel = 0
        self.l = 0
    def move(self):
        self.x += self.xvel
        self.y += self.yvel

        if self.x >= 600:
            self.x = 0
        elif self.x < 0:
            self.x = 580
        if self.y >= 600:
            self.y = 0
        elif self.y < 0:
            self.y = 580
    def draw(self, wn):
        pygame.draw.rect(wn, (5, 125, 125), (self.x, self.y, self.w, self.h), 1)

class enemy(object):
    def __init__(self, x, y, w, h):
        self.x = x
        self.y = y
        self.w = w
        self.h = h
    def draw(self, wn):
        pygame.draw.rect(wn, (255, 0, 0), (self.x, self.y, self.w, self.h), 1)

def snakeCreate():
    global fodrawn_snake

    if not(fodrawn_snake):
        snakes.append(player(screenW/2, screenH/2, 20, 20))
        fodrawn_snake = True
    for snake in snakes:
        if snake.l > len(snakes):
            snakes.append(player(snake.x - snake.xvel, snake.y - snake.yvel, 20, 20))

def eatFood():
    global food
    for snake in snakes:
        if snake.x == food.x and snake.y == food.y:
            snake.l += 1
            food = enemy(grid[random.randint(0, 30)], grid[random.randint(0, 30)], 20, 20)

def fps():
    pygame.time.Clock().tick(10)

def events():
    for ev in pygame.event.get():
        if ev.type == QUIT:
            pygame.quit()
            sys.exit()
        if ev.type == KEYDOWN:
            if ev.key == K_LEFT:
                for snake in snakes:
                    snake.xvel = -20
                    snake.yvel = 0
            if ev.key == K_RIGHT:
                for snake in snakes:
                    snake.xvel = 20
                    snake.yvel = 0
            if ev.key == K_UP:
                for snake in snakes:
                    snake.xvel = 0
                    snake.yvel = -20
            if ev.key == K_DOWN:
                for snake in snakes:
                    snake.xvel = 0
                    snake.yvel = 20

def drawing():
    food.draw(wn)
    for snake in snakes:
        snake.move()
        snake.draw(wn)
    pygame.display.update()
    wn.fill((0, 0, 0))

## Anouncements ##
snakes = []
food = enemy(grid[random.randint(0, 30)], grid[random.randint(0, 30)], 20, 20)

while True:
    fps()
    events()
    eatFood()
    snakeCreate()
    drawing()

因此,当我的蛇吃了食物时,它会创建一个新的蛇,但它会在一个虚无的地方,而不是紧邻蛇的地方。它像x和y vel一样移动,但它并不靠近Snake,也不像真正的蛇那样。希望您能解决问题。谢谢乔里斯 (PS:我是pygame的新手,所以我编写了这些简单的代码。) 这是我的问题的图片:

1 个答案:

答案 0 :(得分:0)

一个好的开始,但是您应该稍微改变一下设计。

让我们考虑一下游戏中的玩家/蛇是什么:基本上,它只是身体部位的列表,因此让我们将这些知识实现到代码中。因此,对于蛇,我们应该有一个类来负责跟踪/绘制/移动其所有部分。这将使其余代码更简单。

我稍微修改了您的代码以实现此目的,并且还删除了一些不必要的功能。无需每次蛇移动时都更改每个身体部位,我们只需在前面创建一个新部位并从列表中删除最后一个部位即可。

我添加了一些评论以进一步解释:

import random
import sys
import pygame
from pygame.locals import *

pygame.init()

pygame.mouse.set_visible(False)

grid = list(range(0, 581, 20))

screenW, screenH = 600, 600

wn = pygame.display.set_mode((screenW, screenH))
pygame.display.set_caption("Snake @codingeagle")

class player(object):

    def __init__(self, x, y, w, h):
        # list of all body parts
        self.body = [] 

        # let's keep track of where the first (the head) part is
        # so we can easily move and check if we eat food
        # since each part is a coordinate and a size, we simply use pygame's Rect class
        self.head = pygame.Rect(x, y, w, h)
        self.body.append(self.head)

        self.xvel = 20
        self.yvel = 0

    def draw(self, wn):
        # drawing is easy
        # we have a bunch of body parts, and we draw them all
        for part in self.body:
            # since we use pygame's Rect class, we can pass it directly to the draw function
            pygame.draw.rect(wn, (5, 125, 125), part, 1)

    def grow(self):
        # when we want to grow, we just create a new body part before our head
        new_part = pygame.Rect(self.head.x + self.xvel, self.head.y + self.yvel, 20, 20)

        # check if out of screen
        if new_part.x >= 600: new_part.x = 0
        elif new_part.x < 0: new_part.x = 580
        if new_part.y >= 600: new_part.y = 0
        elif new_part.y < 0: new_part.y = 580

        # and add the new part to the front
        self.body.insert(0, new_part)

        # the new part is also the new head
        self.head = new_part

    def move(self):
        # now moving is also easy
        # we just grow and remove the last part in the list
        self.grow()
        self.body.pop()

    def try_eat(self, food):
        # check if your head is in the same place as the food
        # Note: that only works because the Rects have the same size
        if self.head == food:
            self.grow()
            # we return True if we eat the fruit so the game knows that we need a new one
            return True


snake = player(screenW/2, screenH/2, 20, 20)

# the food is just a rectangle, so let's use pygame's Rect class also here
food = pygame.Rect(grid[random.randint(0, 30)], grid[random.randint(0, 30)], 20, 20)

while True:
    # simple standard 3-step main loop:
    # 1. handle events
    # 2. update the game state
    # 3. draw everything

    # events
    for ev in pygame.event.get():
        if ev.type == QUIT:
            pygame.quit()
            sys.exit()
        if ev.type == KEYDOWN:
            if ev.key == K_LEFT:
                snake.xvel = -20
                snake.yvel = 0
            if ev.key == K_RIGHT:
                snake.xvel = 20
                snake.yvel = 0
            if ev.key == K_UP:
                snake.xvel = 0
                snake.yvel = -20
            if ev.key == K_DOWN:
                snake.xvel = 0
                snake.yvel = 20

    # game logic
    snake.move()
    if snake.try_eat(food):
        food = pygame.Rect(grid[random.randint(0, 30)], grid[random.randint(0, 30)], 20, 20)

    # drawing
    wn.fill((0, 0, 0))
    pygame.draw.rect(wn, (255, 0, 0), food, 1)
    snake.draw(wn)
    pygame.display.update()

    pygame.time.Clock().tick(10)

enter image description here