首页 > 解决方案 > 在网格中移动一个正方形

问题描述

在网格中进行方形移动

import pygame
from pygame.locals import *
pygame.init()
clock = pygame.time.Clock()
w = 1008
h = 640
left = 16
top = 16
width = 16
height = 16
YELLOW = (255, 255, 55)
BLUE = (0, 0, 255)
BLACK = (0, 0, 0)
bg = (255, 255, 255)
x = 0
y = 0
screen = pygame.display.set_mode((w, h))
gameExit = False
while not gameExit:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameExit = True
        if event.type == KEYDOWN:
            if event.key == K_DOWN:
                top += 16
            if event.key == K_UP:
                top -= 16
            if event.key == K_RIGHT:
                left += 16
            if event.key == K_LEFT:
                left -= 16
    x += 16
    y += 16
    screen.fill(BLACK)
    pygame.draw.rect(screen, [255, 255, 55], [left, top, width, height], 0)
    pygame.draw.line(screen, bg, (w - 16, y), (16, y), 1)
    pygame.draw.line(screen, bg, (x, h - 16), (y, 16), 1)
    pygame.display.flip()

pygame.quit()

目前,如果我 #out screen.fill() 网格出现在屏幕上并且 rect 在后面移动尾部,如果我从 screen.fill() 网格中移除 # 则会消失但 rect 正确移动而没有我想要的尾部两者都会发生。

标签: python-3.xpygame-surface

解决方案


您的代码的问题在于它没有达到您的预期。每次迭代 while 循环时,都会将 x 和 y 值增加 16 并绘制一条水平和垂直线。这似乎绘制了一个网格,因为在您的 while 循环迭代之间不会自动清除屏幕。但是,结果,一段时间后,您的 x 和 y 值增加到您开始绘制越来越多的网格线的点(如果您在循环中打印出这些线的起点和终点,这还不清楚)!

在开始绘制网格线之前添加screen.fill(BLACK)调用时,您基本上清除了整个屏幕。由于您不重新绘制旧网格线,因此只绘制下一对网格线,其余的将丢失。由于新的一对网格线最终会离开屏幕(如第一段所述),因此您的代码似乎不会绘制任何网格线。

当您screen.fill(BLACK)改为注释时,不会清除以前的图纸。所有的网格都是通过多次 while 循环迭代绘制的(除了浪费性地在屏幕外绘制新的网格线),就像之前绘制玩家的所有位置一样。

为了解决这个问题,你的游戏绘图循环应该是这样的结构:

  1. 清除屏幕。
  2. 绘制整个网格,而不是一次绘制两条线。在函数中执行此操作(例如draw_grid)。
  3. 在新玩家位置绘制矩形。也可以在函数中执行此操作(例如draw_player)。
  4. 冲洗并重复下一次迭代!

实现这些小的更改,您的代码可能如下所示:

import pygame
from pygame.locals import *

def draw_grid():
    screen.fill(BLACK)
    for y in range(height, h, height):#horizontal lines
        pygame.draw.line(screen, bg, (width, y), (w - width, y), 1)
    for x in range(width, w, width):#vertical lines
        pygame.draw.line(screen, bg, (x, height), (x, h - height), 1)

def draw_player():
    pygame.draw.rect(screen, [255, 255, 55], [left, top, width, height], 0)

pygame.init()
clock = pygame.time.Clock()
w = 1008
h = 640
left = 16
top = 16
width = 16
height = 16
YELLOW = (255, 255, 55)
BLUE = (0, 0, 255)
BLACK = (0, 0, 0)
bg = (255, 255, 255)
x = 0
y = 0
screen = pygame.display.set_mode((w, h))
gameExit = False

while not gameExit:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameExit = True
        if event.type == KEYDOWN:
            if event.key == K_DOWN:
                top += 16
            if event.key == K_UP:
                top -= 16
            if event.key == K_RIGHT:
                left += 16
            if event.key == K_LEFT:
                left -= 16

    draw_grid()
    draw_player()
    pygame.display.flip()

pygame.quit()

话虽如此,这段代码还有很大的改进空间,我将留给你。最大的问题是您使用了一堆全局变量。这些基本上是您的 while 循环之前列出的所有变量。当它们是可变的时,使用这样的全局变量是“邪恶的”。随着代码变得越来越大,推断哪些函数正在更改这些变量将变得更加困难,因为每个函数都可能访问这些变量。


推荐阅读