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的新手,所以我编写了这些简单的代码。) 这是我的问题的图片:
答案 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)