【问题标题】:Pygame: Draw single pixelPygame:绘制单个像素
【发布时间】:2022-03-23 23:39:29
【问题描述】:

我正在寻找允许我在显示屏上绘制单个像素的方法。例如,当我单击鼠标时,我希望单击像素的位置改变颜色。我知道如何读取鼠标位置,但我找不到简单的像素绘制(有 screen.fill 方法,但它没有按我的意愿工作)。

【问题讨论】:

  • surface.fill(COLOR, (pos, (1,1)) 还不够吗?

标签: python pygame


【解决方案1】:

您可以使用surface.set_at()

surface.set_at((x, y), color)

你也可以使用pygame.gfxdraw.pixel():

from pygame import gfxdraw
gfxdraw.pixel(surface, x, y, color)

但请注意警告:

EXPERIMENTAL!:意味着这个 api 可能会改变,或者在以后消失 pygame 发布。如果您使用它,您的代码将与下一个中断 pygame 发布。

您也可以使用surface.fill() 来完成这项工作:

def pixel(surface, color, pos):
    surface.fill(color, (pos, (1, 1)))

您也可以简单地画一条起点和终点相同的线:

def pixel(surface, color, pos):
    pygame.draw.line(surface, color, pos, pos)

【讨论】:

  • 我试过这个,但我认为有某种特定的方法可以做到这一点。现在我会坚持下去。
  • @user1165499 用另一种方法更新。
【解决方案2】:

Surface或显示器上绘制点的常用方法是使用[`pygame.Surface.set_at']:

window_surface.set_at((x, y), my_color)

但是,如果要绘制超过 1 个点,此功能非常慢,并且会导致性能严重不足。

单独设置每个像素的最小示例: repl.it/@Rabbid76/PyGame-DrawPixel-1

import pygame

pygame.init()
window = pygame.display.set_mode((300, 300))

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    window.fill(0)

    rect = pygame.Rect(window.get_rect().center, (0, 0)).inflate(*([min(window.get_size())//2]*2))
    
    for x in range(rect.width):
        u = x / (rect.width - 1)
        color = (round(u*255), 0, round((1-u)*255))
        for y in range(rect.height):
            window.set_at((rect.left + x, rect.top + y), color) 
    
    pygame.display.flip()

pygame.quit()
exit()

另一种选择是使用"pygame.PixelArray" 对象。此对象允许直接像素访问 Surface 对象。 PixelArray 像素项可以直接赋值。可以通过订阅访问像素。 PixelArray 锁定了Surface,当你改变像素时你必须close()它:

pixel_array = pygame.PixelArray(window_surface)

pixel_array[x, y] = my_color
pixel_array[start_x:end_x, start_y:end_y] = my_color

pixel_array.close()

一次设置一行像素的最小示例: repl.it/@Rabbid76/PyGame-DrawPixel-2

import pygame

pygame.init()
window = pygame.display.set_mode((300, 300))

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    window.fill(0)

    rect = pygame.Rect(window.get_rect().center, (0, 0)).inflate(*([min(window.get_size())//2]*2))

    pixel_array = pygame.PixelArray(window)
    
    for x in range(rect.width):
        u = x / (rect.width - 1)
        color = (round(u*255), 0, round((1-u)*255))
        pixel_array[rect.left + x, rect.top:rect.bottom] = color 
    
    pixel_array.close()
    
    pygame.display.flip()

pygame.quit()
exit()

【讨论】:

    【解决方案3】:

    对于那些对更现代的问题答案感兴趣的人,您可以使用pygame.draw.circle() 在给定位置(或中心)绘制单个像素。

    pygame.draw.circle(surface, color, center, 0)
    

    文档具体说:

    radius (int or float) -- 圆的半径,从center参数测量,半径为0只会绘制中心像素

    【讨论】:

    • pygame.draw.circle 最新版本的 pygame 2.0.0 状态:在 pygame 2.0.0 中更改:...半径为 0 时不绘制任何内容(使用中心坐标处的像素当半径等于 0 时绘制)...所以绘制一个半径为零的圆不再起作用。
    【解决方案4】:

    这样做的一种方法是画一条在同一点上盯着和结束的线。

    pygame.draw.line(surface, (255,255,255), (x,y), (x,y))
    

    【讨论】:

      【解决方案5】:

      绘制单个彩色像素

      def drawPoint(x,y,color):
      
          s = pygame.Surface((1,1))   # the object surface 1 x 1 pixel (a point!)
      
          s.fill(color)               # color as (r,g,b); e.g. (100,20,30)
      
      # now get an object 'rectangle' from the object surface and place it at position x,y
      
          r,r.x,r.y = s.get_rect(),x,y    
      
          screen.blit(s,r)            # link the object rectangle to the object surface
      

      当然你必须调用: pygame.display.update() 一旦你有 绘制您需要的所有点,不要在每个点都调用更新。

      【讨论】:

        【解决方案6】:
        # with this function, you can draw points and change the yer size
        def point(surface, color, x, y, size):
            '''the surface need the information of the pygame window'''
            for i in range(0, size):
                pygame.draw.line(surface, color, (x, y-1), (x, y+2), abs(size))
        

        【讨论】:

        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 1970-01-01
        • 2022-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-22
        • 1970-01-01
        • 1970-01-01
        • 2010-10-20
        相关资源
        最近更新 更多