2009-02-28 18 views
11

正如我所看到的,有兩種方法可以處理鼠標事件來繪製圖片。如何使用Python和pygame創建MS Paint克隆

第一個是檢測鼠標移動並畫出一條線到鼠標所在的位置,如here所示。但是,這樣做的問題在於,對於較大的筆刷大小,由於使用筆劃的筆觸大小來創建粗線,因此每個不是筆直的「線」之間會出現很多間隙。

另一種方式是在鼠標移動時畫圓圈,如圖所示here。問題在於,如果鼠標移動速度快於計算機檢測到鼠標輸入的速度,則每個圓圈之間會出現間隙。

下面是截圖與我的問題有兩個:

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

什麼是執行像MS油漆的刷子最好的辦法,用體面,大筆刷大小,沒有空白的行程每個圓圈之間是否有空隙?

+0

我不明白你的問題。你在談論沒有端蓋,或者......? – 2009-02-28 02:24:19

回答

13

爲什麼不這樣做呢?

在每個端點處繪製一個圓,並在兩者之間畫一條線。

編輯 rofl,只是無法阻止自己。

其實,你不想使用pygame.draw.line,因爲它作弊。它填充1像素寬的行或列(取決於攻角)像素。如果確實以大致垂直的角度(0度或90度)走,這不是問題,但是在45度處,您會注意到一種字符串bean的影響。

唯一的解決辦法是在每個像素的距離繪製一個圓。這裏...

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() 
1

對於第一個問題,你需要一個背景,即使它只是一種顏色。我與我製作的副本pong遊戲有同樣的問題。這裏是我做了一個副本畫圖程序的一個例子,左鍵單擊畫,點鼠標右鍵刪除,請單擊在彩色圖像上選擇一種顏色,按鈕來清除屏幕:

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) 
2

在每個不阻擊器循環步驟可以提高繪圖的速度(使用從前一個代碼改編的代碼可以消除我機器上的延遲問題)

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() 
相關問題