Python 3.x pygame中绘制像素艺术的有效方法
我正在pygame中制作一个非常简单的像素艺术软件。我的逻辑是创建一个网格类,它有一个2D列表,包含0。单击时,栅格近似于选定的行和列,并用与颜色对应的数字标记单元格。为了简单起见,让我们说“1” 代码工作正常,但速度很慢。如果行数和列数小于或等于10,则效果很好,但如果行数和列数大于10,则效果很差 我认为问题在于我每次都在更新整个屏幕,而且,由于程序必须检查每个单元格,它无法处理更大的列表Python 3.x pygame中绘制像素艺术的有效方法,python-3.x,performance,pygame,draw,pixel,Python 3.x,Performance,Pygame,Draw,Pixel,我正在pygame中制作一个非常简单的像素艺术软件。我的逻辑是创建一个网格类,它有一个2D列表,包含0。单击时,栅格近似于选定的行和列,并用与颜色对应的数字标记单元格。为了简单起见,让我们说“1” 代码工作正常,但速度很慢。如果行数和列数小于或等于10,则效果很好,但如果行数和列数大于10,则效果很差 我认为问题在于我每次都在更新整个屏幕,而且,由于程序必须检查每个单元格,它无法处理更大的列表 import pygame from grid import Grid from pincel imp
import pygame
from grid import Grid
from pincel import Pincel
from debugger import Debugger
from display import Display
from pygame.locals import *
pygame.init()
pygame.mixer_music.load("musica/musica1.wav")
pygame.mixer_music.play(-1)
width = 1300
height = 1300
screen = pygame.display.set_mode((1366, 768), pygame.RESIZABLE)
pygame.display.set_caption("SquareDraw")
#Grid Creator
numberOfRows = 25
numberOfColumns = 25
grid = Grid(numberOfRows, numberOfColumns)
# Medidas
basicX = width / numberOfColumns
basicY = height / numberOfRows
#Tool Creator
pincel = Pincel(2)
#variáveis de controle
running = 1
#Initial values
grid.equipTool(pincel)
#variáveis de controle de desenho
clicking = 0
def drawScreen(screen, grid, rows, columns, basicX, basicY):
for i in range(rows):
for j in range(columns):
if grid[i][j]:
print('yes')
print(i, j)
pygame.draw.rect(screen, (0, 0, 0), (j * basicX, i * basicY, basicX, basicY))
while running:
screen.fill((255, 255, 255))
Display.drawScreen(screen, grid.board, grid.getRows(), grid.getColumns(), basicX, basicY)
pygame.display.flip()
events = pygame.event.get()
for event in events:
if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
running = 0
if event.type == pygame.MOUSEBUTTONDOWN or clicking:
clicking = 1
x, y = pygame.mouse.get_pos()
Debugger.printArray2D(grid.board)
print('')
xInGrid = int(x / basicX)
yInGrid = int(y / basicY)
grid.ferramenta.draw(grid.board, xInGrid, yInGrid)
Debugger.printArray2D(grid.board)
print('')
if event.type == pygame.MOUSEBUTTONUP:
clicking = 0
if event.type == pygame.VIDEORESIZE:
width = event.w
height = event.h
basicX = width / numberOfColumns
basicY = height / numberOfRows
print(width, height)
pygame.quit()
类网格包含二维列表。类“Pincel”标记单元格,类“Debugger”仅用于打印列表或与调试相关的任何内容
是否有办法仅更新已更改的屏幕部分?如果是的话,我如何在我的逻辑中应用它
提前感谢:)几件事:
- 使用网格阵列存储屏幕的开/关块。它只有在屏幕调整大小并需要完全重画时才会被读取
- 打开新矩形后,直接在事件处理程序中绘制矩形并更新网格数组。这里不需要重新绘制整个屏幕
- 在调整大小事件中,将屏幕模式重置为新大小,然后使用网格阵列重新绘制整个屏幕。这是唯一一次你需要做一个完整的重画
import pygame
#from grid import Grid
#from pincel import Pincel
#from debugger import Debugger
#from display import Display
from pygame.locals import *
pygame.init()
#pygame.mixer_music.load("musica/musica1.wav")
#pygame.mixer_music.play(-1)
width = 1000
height = 1000
screen = pygame.display.set_mode((width, height), pygame.RESIZABLE)
pygame.display.set_caption("SquareDraw")
#Grid Creator
numberOfRows = 250
numberOfColumns = 250
#grid = Grid(numberOfRows, numberOfColumns)
grid = [[0 for x in range(numberOfRows)] for y in range(numberOfColumns)] # use array for grid: 0=white, 1=black
# Medidas
basicX = width / numberOfColumns
basicY = height / numberOfRows
#Tool Creator
#pincel = Pincel(2)
#xx
running = 1
#Initial values
#grid.equipTool(pincel)
#xx
clicking = 0
def drawScreen(screen, grid, basicX, basicY): # draw rectangles from grid array
for i in range(numberOfColumns):
for j in range(numberOfRows):
if grid[i][j]:
#print('yes')
#print(i, j)
pygame.draw.rect(screen, (0, 0, 0), (j * basicX, i * basicY, basicX, basicY))
screen.fill((255, 255, 255)) # start screen
while running:
events = pygame.event.get()
for event in events:
if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
running = 0
if event.type == pygame.MOUSEBUTTONDOWN or clicking: # mouse button down
clicking = 1
x, y = pygame.mouse.get_pos()
#Debugger.printArray2D(grid.board)
#print('')
xInGrid = int(x / basicX)
yInGrid = int(y / basicY)
grid[yInGrid][xInGrid] = 1 # save this point = 1, for screen redraw (if resize)
pygame.draw.rect(screen, (0, 0, 0), (xInGrid * basicX, yInGrid * basicY, basicX, basicY)) # draw rectangle
#grid.ferramenta.draw(grid.board, xInGrid, yInGrid)
#Debugger.printArray2D(grid.board)
#print('')
pygame.display.flip() # update screen
if event.type == pygame.MOUSEBUTTONUP:
clicking = 0
if event.type == pygame.VIDEORESIZE: # screen resized, must adjust grid height, width
width = event.w
height = event.h
basicX = width / numberOfColumns
basicY = height / numberOfRows
#print(width, height)
screen = pygame.display.set_mode((width, height), pygame.RESIZABLE) # reset screen with new height, width
screen.fill((255, 255, 255)) # clear screen
drawScreen(screen, grid, basicX, basicY) # redraw rectangles
pygame.display.flip() # update screen
pygame.quit()
太神了多谢各位。这正是我所需要的。在其他项目中,当我不必绘制整个屏幕时,我会记住这一点:)