如何让一个矩形跟随另一个基于x,yx方向和y方向在前面的一个?

2024-09-27 00:15:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经为一个蛇代码工作了很长一段时间了。它仍然是相当原始和非常基本的。我已经得到了工作的碰撞,食物生成和非常基本的运动。我在努力弄清楚这个动作。每当你按下WASD或箭头键,它就会移动头部,蛇的“身体”就会跟随它前面的部分。所以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()

Tags: keygetlenifscreenglobalpygamepressed
1条回答
网友
1楼 · 发布于 2024-09-27 00:15:55

人体模块不需要知道方向。您只需在列表中添加一个新的头块(带有下一个x,y坐标)并删除最后一个块。你知道吗

您还可以使用collections.deque,发音为“deck”,这是一个双端队列,允许在两端快速追加和弹出(虽然这里并不需要效率,但代码看起来更好)。你知道吗

还有一些建议,您应该看看函数、类和Pygame精灵是如何工作的。有一本关于Python和Pygame的免费好书叫做Program Arcade Games。另外,您不应该对所有内容都使用全局变量,因为它们会使代码变得很难理解(使用类)。你知道吗

编辑:强调我上面的回答:不要直接通过更改矩形的x和y值来移动列表中的矩形(蛇的部分)。只需弹出或删除最后一个矩形和附加一个新的头部矩形。这会产生移动的错觉,但矩形实际上都保持在同一位置。你知道吗

我提到了deque,因为它有在左端弹出和附加的有效方法。对于列表来说,这是非常低效的,但我认为这对你来说无关紧要,因为列表不会增长太多,而且现在的计算机非常强大。你知道吗

一些代码检查(这应该在https://codereview.stackexchange.com/中进行):

第132行:您没有调用pop,因为您忘记了括号。但如果你真的打电话给它,蛇口名单会缩小,游戏会崩溃。你知道吗

首先处理事件循环,然后是游戏逻辑(例如碰撞),然后是绘图。在游戏类中,您可以对程序的这些部分使用不同的方法。你知道吗

你给pygame.key.get_pressed()打了好几次电话。相反,将keys列表分配给变量keys = pygame.key.get_pressed(),然后在循环的后面使用这个变量。你知道吗

time.sleep通常不在Pygame中使用(游戏控件似乎没有响应)。有一个pygame.time.Clock类,你可以用它来限制帧速率,你可以用一个定时器变量来跟踪蛇什么时候可以移动。在主循环clock = pygame.time.Clock()之前实例化一个时钟,在循环中每一帧调用clock.tick(enter_max_fps_here)。你知道吗

相关问题 更多 >

    热门问题