【问题标题】:How to fix coordinates doubling up?如何修复坐标加倍?
【发布时间】:2020-03-31 10:31:12
【问题描述】:

我目前正在 Pygame 中制作 Snake。我想让 ir 成长的想法是,我会列出他所有的位置,每当他吃苹果时,我会附加另一个 pygame.Surface 并在最后一个位置后面的坐标上粘贴它。我遇到了一个奇怪的错误,它使蛇的速度是以前的两倍。你能帮助我吗? 这是我的代码:

import pygame, math, random

pygame.init()

screen = pygame.display.set_mode((640,640))
pygame.display.set_caption('Snake')

score = 0

x, y = 320,320
dx,dy = 32,32
running = True
dirUp, dirDown = False, False
dirLeft, dirRight = False, True
body = [(x,y)]
pos = []


squares = []
for i in range(640):
    if i % 32 == 0:
        squares.append(i)
food = pygame.image.load('fruit.png')
foodx,foody = random.choice(squares), random.choice(squares)

def isCollision(obsX, obsY, x, y):
    return math.sqrt(math.pow(obsX - x, 2) + math.pow(obsY - y, 2)) <= 0

def show_text():
    score_font = pygame.font.Font('freesansbold.ttf',32)
    score_text = score_font.render('Score: {}'.format(score), True, (255,255,255))
    screen.blit(score_text, (0,0))

def remove_duplicates(listy):
    new_listy = []
    for item in listy:
        if item not in new_listy:
            new_listy.append(item)
    return new_listy

def move():
    global x,y
    if dirUp:
        y -= dy
    elif dirDown:
        y += dy
    elif dirRight:
        x += dx
    elif dirLeft:
        x -= dx

clock = pygame.time.Clock()

while running:
    clock.tick(10)
    screen.fill((0,128,0))

    body[0] = (x,y)

    snakeImg = [pygame.image.load('snakeblock.png') for i in range(len(body))]

    if x > 608 or x < 0:
        running = False
    elif y > 608 or y < 0:
        running = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                dirUp = True
                dirLeft = dirDown = dirRight = False
            if event.key == pygame.K_DOWN:
                dirDown = True
                dirUp = dirLeft = dirRight = False
            if event.key == pygame.K_RIGHT:
                dirRight = True
                dirUp = dirDown = dirLeft = False
            if event.key == pygame.K_LEFT:
                dirLeft = True
                dirUp = dirDown = dirRight = False

    for i in range(len(body)):
        if isCollision(foodx,foody,body[i][0],body[i][1]):
            foodx, foody = random.choice(squares), random.choice(squares)
            score += 1
            body.insert(0,pos[-2])

        move()

        pos.append((x,y))
        screen.blit(food, (foodx, foody))
        screen.blit(snakeImg[i], (body[i][0], body[i][1]))
    pos = remove_duplicates(pos)
    show_text()
    pygame.display.update()

【问题讨论】:

  • "我遇到了一个奇怪的错误,它使蛇的速度是以前的两倍"。 “之前”是什么意思?您更改了哪些代码使蛇的移动速度提高了一倍?
  • 首先,snake 每次迭代正常运行 32 次。当我吃一个苹果时,它会快两倍。
  • 在游戏循环内的 for 循环中,您在每个蛇体块的第一个蛇块上调用 move()。这意味着您将所有动作都放在第一个方块上。
  • 我知道。通常不是 x 和 y 将是 body[i] = (body[i][0], body[i][1])
  • 如果您移动每个块,您的代码仍然存在问题。但是,您的问题是“我遇到了一个奇怪的错误,它使蛇的速度是以前的两倍”。这是因为如果有 3 个块,您将移动块 3 次。这意味着蛇的速度是原来的 3 倍。

标签: python python-3.x list pygame tuples


【解决方案1】:

您的代码还会遇到其他问题,例如不测试边缘碰撞和蛇形块碰撞。但这是一个起点。

您的问题是,只要您有多个块,您就会在每个循环中多次移动起始块。

这是带有 cmets 的完整代码。

import pygame, math, random

pygame.init()

screen = pygame.display.set_mode((640,640))
pygame.display.set_caption('Snake')

score = 0

x, y = 320,320
dx,dy = 32,32
running = True
dirUp, dirDown = False, False
dirLeft, dirRight = False, True
body = [(x,y)]
pos = []


squares = []
for i in range(640):
    if i % 32 == 0:
        squares.append(i)
food = pygame.image.load('fruit.png')
food = pygame.transform.scale(food, (32,32))
foodx,foody = random.choice(squares), random.choice(squares)

def isCollision(obsX, obsY, x, y):
    return math.sqrt(math.pow(obsX - x, 2) + math.pow(obsY - y, 2)) <= 0

def show_text():
    score_font = pygame.font.Font('freesansbold.ttf',32)
    score_text = score_font.render('Score: {}'.format(score), True, (255,255,255))
    screen.blit(score_text, (0,0))

def move(x, y):
    # I changed this function to take arguments and return
    # values rather than set globals which is generally bad practice
    if dirUp:
        y -= dy
    elif dirDown:
        y += dy
    elif dirRight:
        x += dx
    elif dirLeft:
        x -= dx

    return x, y

clock = pygame.time.Clock()

while running:
    clock.tick(10)
    screen.fill((0,128,0))

    snakeImg = [pygame.transform.scale(pygame.image.load('snakeblock.png'), (32,32)) for i in range(len(body))]

    if x > 608 or x < 0:
        running = False
    elif y > 608 or y < 0:
        running = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                dirUp = True
                dirLeft = dirDown = dirRight = False
            if event.key == pygame.K_DOWN:
                dirDown = True
                dirUp = dirLeft = dirRight = False
            if event.key == pygame.K_RIGHT:
                dirRight = True
                dirUp = dirDown = dirLeft = False
            if event.key == pygame.K_LEFT:
                dirLeft = True
                dirUp = dirDown = dirRight = False

    # this for loop is reversed because you only need to move your first block
    # the rest of the blocks can just follow the pattern of the previously 
    # placed blocks
    for i in reversed(range(len(body))):
        if isCollision(foodx,foody,body[i][0],body[i][1]):
            foodx, foody = random.choice(squares), random.choice(squares)
            score += 1
            body.insert(0, move(body[i][0], body[i][1]))
        elif i == 0:
            # Here you only move your first block or element
            body[i] = move(body[i][0], body[i][1])
        else:
            # otherwise you can just place the current element
            # at the position of the previous element
            body[i] = body[i - 1]

        screen.blit(food, (foodx, foody))
        screen.blit(snakeImg[i], (body[i][0], body[i][1]))

    show_text()
    pygame.display.update()

【讨论】:

  • 谢谢!实际上,我已经在另一个版本的代码中计划了这些问题的解决方案。
【解决方案2】:

让别人知道如何让蛇撞墙和撞到自己:

if body[0][0] > 608 or body[0][0] < 0:
        running = False
    elif body[0][1] > 608 or body[0][1] < 0:
        running = False
[...]

for i in range(len(body)):
        if body[0] in body[1:]:
            running = False

【讨论】:

    猜你喜欢
    • 2012-03-03
    • 1970-01-01
    • 2011-12-24
    • 2019-09-17
    • 1970-01-01
    • 2019-11-20
    • 2016-06-07
    • 2021-10-17
    • 1970-01-01
    相关资源
    最近更新 更多