문제

내가 보았 듯이, 마우스 이벤트를 처리하여 그림을 그리는 두 가지 방법이 있습니다.

첫 번째는 마우스가 움직일 때를 감지하고 마우스가있는 위치에 선을 그리는 것입니다. 여기. 그러나이 문제는 브러시 크기가 크면 라인의 스트로크 크기를 사용하여 두꺼운 선을 생성하기 때문에 똑바로 아닌 각 "선"사이에 많은 간격이 나타납니다.

다른 방법은 표시된대로 마우스가 움직일 때 원을 그리는 것입니다. 여기. 이 문제는 컴퓨터가 마우스 입력을 감지하는 것보다 마우스가 더 빨리 움직이면 각 원 사이에 간격이 나타납니다.

다음은 다음과 같은 문제에 대한 스크린 샷입니다.

http://imgur.com/32DXN.jpg

MS Paint 's와 같은 브러시를 구현하는 가장 좋은 방법은 무엇입니까? 선의 스트로크에 틈이 없거나 각 원 사이의 간격이없는 괜찮은 빅 브러시 크기가있는 가장 좋은 방법은 무엇입니까?

도움이 되었습니까?

해결책

왜 둘 다하지 않습니까?

각 엔드 포인트에서 원과 둘 사이의 선을 그립니다.

편집하다 Rofl, 그냥 내 자신을 막을 수 없었습니다.

사실, 당신은 사용하고 싶지 않습니다 pygame.draw.line 속임수 때문입니다. 픽셀의 1 픽셀 와이드 행 또는 열 (공격 각도에 따라)을 채 웁니다. 대략 수직 각도, 0 Deg 또는 90 도로 가면 문제가되지 않지만 45 대에 일종의 끈 콩 효과.

유일한 해결책은 모든 픽셀의 거리에서 원을 그리는 것입니다. 여기...

import pygame, random

screen = pygame.display.set_mode((800,600))

draw_on = False
last_pos = (0, 0)
color = (255, 128, 0)
radius = 10

def roundline(srf, color, start, end, radius=1):
    dx = end[0]-start[0]
    dy = end[1]-start[1]
    distance = max(abs(dx), abs(dy))
    for i in range(distance):
        x = int( start[0]+float(i)/distance*dx)
        y = int( start[1]+float(i)/distance*dy)
        pygame.draw.circle(srf, color, (x, y), radius)

try:
    while True:
        e = pygame.event.wait()
        if e.type == pygame.QUIT:
            raise StopIteration
        if e.type == pygame.MOUSEBUTTONDOWN:
            color = (random.randrange(256), random.randrange(256), random.randrange(256))
            pygame.draw.circle(screen, color, e.pos, radius)
            draw_on = True
        if e.type == pygame.MOUSEBUTTONUP:
            draw_on = False
        if e.type == pygame.MOUSEMOTION:
            if draw_on:
                pygame.draw.circle(screen, color, e.pos, radius)
                roundline(screen, color, e.pos, last_pos,  radius)
            last_pos = e.pos
        pygame.display.flip()

except StopIteration:
    pass

pygame.quit()

다른 팁

각 루프 단계에서 블리팅되지 않으면 도면의 속도가 향상 될 수 있습니다 (이전 코드를 사용하여 이전 코드를 사용하면 내 컴퓨터에서 지연 문제를 제거 할 수 있습니다)

import pygame, random

screen = pygame.display.set_mode((800,600))

draw_on = False
last_pos = (0, 0)
color = (255, 128, 0)
radius = 10

def roundline(srf, color, start, end, radius=1):
    dx = end[0]-start[0]
    dy = end[1]-start[1]
    distance = max(abs(dx), abs(dy))
    for i in range(distance):
        x = int( start[0]+float(i)/distance*dx)
        y = int( start[1]+float(i)/distance*dy)
        pygame.display.update(pygame.draw.circle(srf, color, (x, y), radius))

try:
    while True:
        e = pygame.event.wait()
        if e.type == pygame.QUIT:
            raise StopIteration
        if e.type == pygame.MOUSEBUTTONDOWN:
            color = (random.randrange(256), random.randrange(256), random.randrange(256))
            pygame.draw.circle(screen, color, e.pos, radius)
            draw_on = True
        if e.type == pygame.MOUSEBUTTONUP:
            draw_on = False
        if e.type == pygame.MOUSEMOTION:
            if draw_on:
                pygame.display.update(pygame.draw.circle(screen, color, e.pos, radius))
                roundline(screen, color, e.pos, last_pos,  radius)
            last_pos = e.pos
        #pygame.display.flip()

except StopIteration:
    pass

pygame.quit()

첫 번째 문제의 경우 색상 일지라도 배경이 필요합니다. 나는 내가 만든 복제판 게임에서도 같은 문제가 있었다. 다음은 내가 만든 복제 페인트 프로그램의 예입니다. 왼쪽 클릭하고 오른쪽 클릭하고 마우스 오른쪽 버튼을 클릭하고 색상 이미지를 클릭하여 색상을 선택하고 화면을 지우려면 버튼을 확인하십시오.

import os
os.environ['SDL_VIDEO_CENTERED'] = '1'
from pygamehelper import *
from pygame import *
from pygame.locals import *
from vec2d import *
from math import e, pi, cos, sin, sqrt
from random import uniform

class Starter(PygameHelper):
    def __init__(self):
        self.w, self.h = 800, 600
        PygameHelper.__init__(self, size=(self.w, self.h), fill=((255,255,255)))

        self.img= pygame.image.load("colors.png")
        self.screen.blit(self.img, (0,0))

        self.drawcolor= (0,0,0)
        self.x= 0

    def update(self):
        pass

    def keyUp(self, key):
        if key==K_UP:
            self.screen.fill((255,255,255))
            self.screen.blit(self.img, (0,0))




    def mouseUp(self, button, pos):
        pass

    def mouseMotion(self, buttons, pos, rel):
        if pos[1]>=172: 
            if buttons[0]==1:
                #pygame.draw.circle(self.screen, (0,0,0), pos, 5)
                pygame.draw.line(self.screen, self.drawcolor, pos, (pos[0]-rel[0], pos[1]-rel[1]),5)                
            if buttons[2]==1:
                pygame.draw.circle(self.screen, (255,255,255), pos, 30)
            if buttons[1]==1:
                #RAINBOW MODE
                color= self.screen.get_at((self.x, 0))
                pygame.draw.line(self.screen, color, pos, (pos[0]-rel[0], pos[1]-rel[1]), 5)

                self.x+= 1
                if self.x>172: self.x=0

        else:
            if pos[0]<172:
                if buttons[0]==1:
                    self.drawcolor= self.screen.get_at(pos)
                    pygame.draw.circle(self.screen, self.drawcolor, (250, 100), 30)

    def draw(self):
        pass
        #self.screen.fill((255,255,255))
        #pygame.draw.circle(self.screen, (0,0,0), (50,100), 20)

s = Starter()
s.mainLoop(40)

다음은 Matthew 's의 단순화 된 버전입니다 예시 불행히도 실행할 수 없습니다.

마우스가 움직일 때 pygame.MOUSEMOTION 이벤트는 위치와 상대적인 움직임을 포함하는 이벤트 큐에 추가됩니다. 이것들을 사용하여 이전 위치를 계산 한 다음 두 지점을 전달할 수 있습니다. pygame.draw.line.

pygame.MOUSEMOTION 이벤트에는 또한 이벤트에도 있습니다 buttons 현재 다운 된 마우스 버튼을 확인하는 데 사용할 수있는 속성.

import os
import random

import pygame as pg


class App:

    def __init__(self):
        os.environ['SDL_VIDEO_CENTERED'] = '1'
        pg.init()
        self.w, self.h = 800, 600
        self.screen = pg.display.set_mode((self.w, self.h))
        self.screen.fill(pg.Color('white'))
        self.clock = pg.time.Clock()
        self.drawcolor = (0, 0, 0)

    def mainloop(self):
        while True:
            for event in pg.event.get():
                if event.type == pg.QUIT:
                    return
                elif event.type == pg.MOUSEBUTTONDOWN:
                    if event.button == 2:  # Color picker (middle mouse button).
                        self.drawcolor = self.screen.get_at(pos)
                        # Pick a random color.
                        # self.drawcolor = [random.randrange(256) for _ in range(3)]
                elif event.type == pg.MOUSEMOTION:
                    pos, rel = event.pos, event.rel
                    if event.buttons[0]:  # If the left mouse button is down.
                        # Draw a line from the pos to the previous pos.
                        pg.draw.line(self.screen, self.drawcolor, pos, (pos[0]-rel[0], pos[1]-rel[1]), 5)
                    elif event.buttons[2]:  # If the right mouse button is down.
                        # Erase by drawing a circle.
                        pg.draw.circle(self.screen, (255, 255, 255), pos, 30)

            pg.display.flip()
            self.clock.tick(30)


if __name__ == '__main__':
    app = App()
    app.mainloop()
    pg.quit()
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top