我已经研究蛇代码有一段时间了。它仍然相当原始并且非常非常基本。我已经完成了工作中的碰撞、食物生成和非常基本的运动。我正在努力解决的是弄清楚运动。每当你按下 WASD 或箭头键时,它就会移动头部,而蛇的“ body ”会跟随它前面的部分。所以snakecol[1] 跟随snakecol[0] 等等。
预先感谢您提供有关如何改进我的代码的任何提示和指示。
#W to move up, A to move to the left, S to move down, D to move right.
#Snake by Juan Jaramillo
import pygame
import sys
import random
import math
import time
pygame.init()
screen=pygame.display.set_mode((500,500))
point=3
def collision():
global foodx
global foody
global x
global y
global xd
global yd
global point
global snakecol
if snakecol[0].colliderect(foodcol):
foodx=random.randint(0,24)*20
foody=random.randint(0,24)*20
point+=1
snakecol.append(snakecol[len(snakecol)-1])
if xd==20:
snakecol[len(snakecol)-1].x-=20
if xd==-20:
snakecol[len(snakecol)-1].x+=20
if yd==20:
snakecol[len(snakecol)-1].y-=20
if yd==-20:
snakecol[len(snakecol)-1].y==20
print "Snake is",point,"long."
red=(255,0,0)
blue=(0,0,255)
green=(0,255,0)
black=(0,0,0)
block1=0
block2=1
count=0
screen.fill(black)
randFood=random.randint(0,24)
x=60
y=0
foodx=randFood*20
foody=randFood*20
snakecol=list()
snakecol.append(pygame.Rect(x,y,20,20))
snakecol.append(pygame.Rect(x-20,y,20,20))
snakecol.append(pygame.Rect(x-40,y,20,20))
foodcol=pygame.Rect(foodx,foody,20,20)
xd=[20]
yd=[0]
##snakecol=pygame.Rect(x,y,20,20)
foodcol=pygame.Rect(foodx,foody,20,20)
done=False
while not done:
screen.fill(black)
collision()
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
#controls
if block1==1:
if(pygame.key.get_pressed()[pygame.K_a]) or (pygame.key.get_pressed()[pygame.K_LEFT]):
yd[0]=0
xd[0]=-20
block1=0
block2=1
if block1==1:
if(pygame.key.get_pressed()[pygame.K_d]) or (pygame.key.get_pressed()[pygame.K_RIGHT]):
yd[0]=0
xd[0]=20
block1=0
block2=1
if block2==1:
if(pygame.key.get_pressed()[pygame.K_w]) or (pygame.key.get_pressed()[pygame.K_UP]):
xd[0]=0
yd[0]=-20
block1=1
block2=0
if block2==1:
if(pygame.key.get_pressed()[pygame.K_s]) or (pygame.key.get_pressed()[pygame.K_DOWN]):
xd[0]=0
yd[0]=20
block1=1
block2=0
#stop moving paddle
for m in range(0,len(snakecol)):
if snakecol[m].x<-20:
snakecol[m].x=500
if snakecol[m].x>500:
snakecol[m].x=-20
if snakecol[m].y<-20:
snakecol[m].y=500
if snakecol[m].y>500:
snakecol[m].y=-20
for m in range(0,len(snakecol)):
snakecol.pop
pygame.draw.rect(screen,(255,255,255),snakecol[m],0)
pygame.draw.rect(screen,(0,0,0),snakecol[m],1)
snakecol[m].x+=xd[0]
snakecol[m].y+=yd[0]
foodcol.x=foodx
foodcol.y=foody
pygame.draw.rect(screen,(255,255,255),(foodx,foody,20,20),0)
pygame.draw.rect(screen,(0,0,0),(foodx,foody,20,20),1)
pygame.display.flip()
time.sleep(0.4)
count+=1
pygame.quit()
最佳答案
body block 不需要知道方向。您只需将一个新的头 block (带有下一个 x、y 坐标)添加到列表中并删除最后一个 block 即可。
您还可以使用collections.deque
,发音为“deck”,这是一个双端队列,允许在任一端快速追加和弹出(尽管这里并不真正需要效率,代码只是看起来更好一点)。
还有一些建议,您应该查看函数、类和 Pygame sprites 的工作原理。有一本关于 Python 和 Pygame 的免费好书,名为 Program Arcade Games 。另外,您不应该对所有内容都使用全局变量,因为它们会使代码非常难以理解(使用类)。
编辑:强调我上面的回答:不要通过更改 x 和 y 值来直接移动列表中的矩形(蛇的部分)。只需弹出或删除最后一个矩形并附加一个新的头部矩形。这会产生运动的错觉,但矩形实际上都停留在同一位置。
我提到了双端队列,因为它具有在左端弹出和追加的有效方法。对于列表来说,这是非常低效的,但我认为这对你来说并不重要,因为列表不会增长太多,而且现在的计算机非常强大。
一些代码审查(这应该在 https://codereview.stackexchange.com/ 中):
第 132 行:您没有调用 pop
因为您忘记了括号。但如果你真的调用了它,snakecol 列表就会缩小,游戏就会崩溃。
首先处理事件循环,然后是游戏逻辑(例如碰撞),最后是绘图。在游戏类中,您将为程序的这些部分使用不同的方法。
您多次调用pygame.key.get_pressed()
。而是将按键列表分配给变量 keys = pygame.key.get_pressed()
并稍后在循环中使用该变量。
time.sleep
通常在 Pygame 中不使用(游戏控件似乎没有响应)。您可以使用 pygame.time.Clock 类来限制帧速率,并且可以使用计时器变量来跟踪蛇何时可以移动。在主循环clock = pygame.time.Clock()
之前实例化一个时钟,并在循环中每帧调用clock.tick(enter_max_fps_here)
。
关于python - 如何根据前面的 x、y x 方向和 y 方向让 .Rect 跟随另一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37573871/