有没有办法简化这个 pygame 代码?
Is there a way to simplify this pygame code?
我对pygame有点陌生,我不知道有没有办法简化这个,如果你能在绘图时改变颜色也很好。我已经尝试过实现它,但找不到让它工作的方法。它基本上是一个简单的像素艺术游戏:
import pygame
from sys import exit
def MousePos():
mouse_pos = pygame.mouse.get_pos()
return mouse_pos[0] // grid_size, mouse_pos[1] // grid_size
def DrawGrid():
for x in range(0, WIDTH, grid_size):
for y in range(0, HEIGHT, grid_size):
rect = pygame.Rect(x, y, grid_size, grid_size)
pygame.draw.rect(screen, "Black", rect, 1)
def DrawSquare():
mouse_buttons = pygame.mouse.get_pressed()
if mouse_buttons[0] and MousePos() not in pressed:
pressed.append(MousePos())
if mouse_buttons[1] and MousePos() not in pressed:
pressed.clear()
if mouse_buttons[2] and MousePos() in pressed:
pressed.remove(MousePos())
for coordinates in pressed:
rectangle = pygame.Rect(coordinates[0]*grid_size, coordinates[1]*grid_size, grid_size, grid_size)
pygame.draw.rect(screen, "Black", rectangle)
cursor = pygame.Rect(MousePos()[0]*grid_size, MousePos()[1]*grid_size, grid_size, grid_size)
pygame.draw.rect(screen, "Grey", cursor)
pygame.init()
clock = pygame.time.Clock()
WIDTH = 800
HEIGHT = 400
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("PixelArt!")
grid_size = 25
pressed = []
pygame.mouse.set_visible(False)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
screen.fill("White")
MousePos()
DrawGrid()
DrawSquare()
pygame.display.flip()
clock.tick(60)
编辑: 也许这个问题应该在类似的门户网站上继续 Code Review or Game Development
我一直在变量中绘制颜色并使用键来更改它。
1 = Red
、2 = Green
、3 = Blue
、0 = Black
但现在它需要用 pos
保留 color
- 我使用字典 pressed[pos] = color
但也许您应该为网格中的所有方块创建完整的二维列表,而不是 pressed
,并在开始时将 White
放在所有位置。如果您将颜色设置为元组,即 (255,0,0)
而不是字符串 Red
那么您可以将其保存在 numpy.array
中并简单地保存在文本文件中或将 numpy.array
转换为 Pillow.Image
和另存为 JPG/PNG/TIFF.
因为现在它可以绘制不同的颜色所以当我按下第一个按钮时我不检查是否 pos not in pressed
因为它不允许替换正方形的颜色。
没有那么多要简化的。
在 DrawSquare()
中你 运行 MousePos()
很多次但你可以 运行 它一次并分配给变量。
您可以使用 x, y = ...
代替 pos = ...
和 pos[0]
、pos[1]
。
或者您可以同时使用 x, y = pos = ...
.
您可以在开始时创建 cursor = Rect(...)
,然后使用 cursor.topleft = new_position
移动它。
也许在 draw.rect(...)
中你可以直接使用元组 (x, y, width, height)
而不是 Rect(x, y, width, height)
我使用了 PEP 8 -- Style Guide for Python Code
中的规则
lower_case_names
函数名称
verbs
用于函数名称 - convert
而不是 MousePos
(变量 nouns
和 类)
完整代码:
import pygame
from sys import exit
# --- constants --- # PEP8: `UPPER_CASE_NAMES`
WIDTH = 800
HEIGHT = 400
SQUARE_SIZE = 25
# --- classes --- # PEP8: `CamelCaseNames`
# empty
# --- functions --- # PEP8: `lower_case_names`
def convert_pos(pos):
x, y = pos
return (x // SQUARE_SIZE, y // SQUARE_SIZE)
def draw_grid():
for x in range(0, WIDTH, SQUARE_SIZE):
for y in range(0, HEIGHT, SQUARE_SIZE):
rect = pygame.Rect(x, y, SQUARE_SIZE, SQUARE_SIZE)
pygame.draw.rect(screen, "Black", rect, 1)
def draw_square():
mouse_buttons = pygame.mouse.get_pressed()
mouse_pos = pygame.mouse.get_pos()
grid_x, grid_y = grid_pos = convert_pos(mouse_pos)
cursor.topleft = (grid_x*SQUARE_SIZE, grid_y*SQUARE_SIZE)
if mouse_buttons[0]:
pressed[grid_pos] = draw_color
if mouse_buttons[1]: # and grid_pos not in pressed:
pressed.clear()
if mouse_buttons[2] and grid_pos in pressed:
#del pressed[grid_pos]
pressed.pop(grid_pos)
for (x, y), color in pressed.items():
rectangle = pygame.Rect(x*SQUARE_SIZE, y*SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)
pygame.draw.rect(screen, color, rectangle)
pygame.draw.rect(screen, "Grey", cursor)
# --- main ---
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("PixelArt!")
pygame.mouse.set_visible(False)
pressed = {} # dictionary for `pressed[position] = color
cursor = pygame.Rect(0, 0, SQUARE_SIZE, SQUARE_SIZE)
draw_color = 'Black'
# - mainloop -
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
draw_color = 'Red'
elif event.key == pygame.K_2:
draw_color = 'Green'
elif event.key == pygame.K_3:
draw_color = 'Blue'
elif event.key == pygame.K_0:
draw_color = 'Black'
# - draw -
screen.fill("White")
draw_grid()
draw_square()
pygame.display.flip()
clock.tick(60)
我对pygame有点陌生,我不知道有没有办法简化这个,如果你能在绘图时改变颜色也很好。我已经尝试过实现它,但找不到让它工作的方法。它基本上是一个简单的像素艺术游戏:
import pygame
from sys import exit
def MousePos():
mouse_pos = pygame.mouse.get_pos()
return mouse_pos[0] // grid_size, mouse_pos[1] // grid_size
def DrawGrid():
for x in range(0, WIDTH, grid_size):
for y in range(0, HEIGHT, grid_size):
rect = pygame.Rect(x, y, grid_size, grid_size)
pygame.draw.rect(screen, "Black", rect, 1)
def DrawSquare():
mouse_buttons = pygame.mouse.get_pressed()
if mouse_buttons[0] and MousePos() not in pressed:
pressed.append(MousePos())
if mouse_buttons[1] and MousePos() not in pressed:
pressed.clear()
if mouse_buttons[2] and MousePos() in pressed:
pressed.remove(MousePos())
for coordinates in pressed:
rectangle = pygame.Rect(coordinates[0]*grid_size, coordinates[1]*grid_size, grid_size, grid_size)
pygame.draw.rect(screen, "Black", rectangle)
cursor = pygame.Rect(MousePos()[0]*grid_size, MousePos()[1]*grid_size, grid_size, grid_size)
pygame.draw.rect(screen, "Grey", cursor)
pygame.init()
clock = pygame.time.Clock()
WIDTH = 800
HEIGHT = 400
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("PixelArt!")
grid_size = 25
pressed = []
pygame.mouse.set_visible(False)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
screen.fill("White")
MousePos()
DrawGrid()
DrawSquare()
pygame.display.flip()
clock.tick(60)
编辑: 也许这个问题应该在类似的门户网站上继续 Code Review or Game Development
我一直在变量中绘制颜色并使用键来更改它。
1 = Red
、2 = Green
、3 = Blue
、0 = Black
但现在它需要用 pos
保留 color
- 我使用字典 pressed[pos] = color
但也许您应该为网格中的所有方块创建完整的二维列表,而不是 pressed
,并在开始时将 White
放在所有位置。如果您将颜色设置为元组,即 (255,0,0)
而不是字符串 Red
那么您可以将其保存在 numpy.array
中并简单地保存在文本文件中或将 numpy.array
转换为 Pillow.Image
和另存为 JPG/PNG/TIFF.
因为现在它可以绘制不同的颜色所以当我按下第一个按钮时我不检查是否 pos not in pressed
因为它不允许替换正方形的颜色。
没有那么多要简化的。
在 DrawSquare()
中你 运行 MousePos()
很多次但你可以 运行 它一次并分配给变量。
您可以使用 x, y = ...
代替 pos = ...
和 pos[0]
、pos[1]
。
或者您可以同时使用 x, y = pos = ...
.
您可以在开始时创建 cursor = Rect(...)
,然后使用 cursor.topleft = new_position
移动它。
也许在 draw.rect(...)
中你可以直接使用元组 (x, y, width, height)
而不是 Rect(x, y, width, height)
我使用了 PEP 8 -- Style Guide for Python Code
中的规则lower_case_names
函数名称verbs
用于函数名称 -convert
而不是MousePos
(变量nouns
和 类)
完整代码:
import pygame
from sys import exit
# --- constants --- # PEP8: `UPPER_CASE_NAMES`
WIDTH = 800
HEIGHT = 400
SQUARE_SIZE = 25
# --- classes --- # PEP8: `CamelCaseNames`
# empty
# --- functions --- # PEP8: `lower_case_names`
def convert_pos(pos):
x, y = pos
return (x // SQUARE_SIZE, y // SQUARE_SIZE)
def draw_grid():
for x in range(0, WIDTH, SQUARE_SIZE):
for y in range(0, HEIGHT, SQUARE_SIZE):
rect = pygame.Rect(x, y, SQUARE_SIZE, SQUARE_SIZE)
pygame.draw.rect(screen, "Black", rect, 1)
def draw_square():
mouse_buttons = pygame.mouse.get_pressed()
mouse_pos = pygame.mouse.get_pos()
grid_x, grid_y = grid_pos = convert_pos(mouse_pos)
cursor.topleft = (grid_x*SQUARE_SIZE, grid_y*SQUARE_SIZE)
if mouse_buttons[0]:
pressed[grid_pos] = draw_color
if mouse_buttons[1]: # and grid_pos not in pressed:
pressed.clear()
if mouse_buttons[2] and grid_pos in pressed:
#del pressed[grid_pos]
pressed.pop(grid_pos)
for (x, y), color in pressed.items():
rectangle = pygame.Rect(x*SQUARE_SIZE, y*SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)
pygame.draw.rect(screen, color, rectangle)
pygame.draw.rect(screen, "Grey", cursor)
# --- main ---
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("PixelArt!")
pygame.mouse.set_visible(False)
pressed = {} # dictionary for `pressed[position] = color
cursor = pygame.Rect(0, 0, SQUARE_SIZE, SQUARE_SIZE)
draw_color = 'Black'
# - mainloop -
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
draw_color = 'Red'
elif event.key == pygame.K_2:
draw_color = 'Green'
elif event.key == pygame.K_3:
draw_color = 'Blue'
elif event.key == pygame.K_0:
draw_color = 'Black'
# - draw -
screen.fill("White")
draw_grid()
draw_square()
pygame.display.flip()
clock.tick(60)