python - 如何根据前面的 x、y x 方向和 y 方向让 .Rect 跟随另一个?

标签 python pygame

我已经研究蛇代码有一段时间了。它仍然相当原始并且非常非常基本。我已经完成了工作中的碰撞、食物生成和非常基本的运动。我正在努力解决的是弄清楚运动。每当你按下 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/

相关文章:

python - 我将如何在 python 中发送电子邮件?此代码无效

python - 记录 url 重定向

python - 如何在 python (Windows) 上的 openCV dnn 模块上使用 GPU 加速?

class - PYGAME - 使一个对象旋转到自动生成的对象

python - 如何在pygame中将图像置于窗口中间?

python - 游戏错误 : Mpeg video will not play

python - 当正常的 for 循环工作正常时,列表理解不起作用

python 2.7 : Simple 'for' loop implementation

python - 如何在 PyGame 中获取屏幕上每个像素的颜色

python - Pygame - 播放 youtube-dl 下载的 mp3 文件不起作用