Pygame - Странная Змея - PullRequest
       7

Pygame - Странная Змея

0 голосов
/ 18 октября 2018
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, но он не рядом со Змеей и не похож на настоящего змея.Надеюсь, вы сможете решить проблему.Спасибо, Joris (PS: я новичок в Pygame, поэтому я делаю эти простые коды.) Вот изображение моей проблемы:

1 Ответ

0 голосов
/ 18 октября 2018

Хорошее начало, но вы должны немного изменить свой дизайн.

Давайте подумаем о том, кто игрок / змея в вашей игре: в основном это просто список частей тела, поэтому давайте реализуем этознание в коде.Таким образом, у нас должен быть один класс для змеи, который отвечает за отслеживание / рисование / перемещение всех его частей.Это сделает остальную часть кода проще.

Я немного изменил ваш код, чтобы реализовать это, а также удалил некоторые ненужные функции.Вместо того, чтобы менять каждую часть тела каждый раз, когда змея двигается, мы просто создаем новую часть спереди и удаляем последнюю часть в списке.

Я добавил несколько комментариев для дальнейшего объяснения:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...