2016-07-01 84 views
1

我想在Python中使用Pygame編碼一個簡單的圓形定時器。 目前,它看起來像這樣: Timer防鋸齒電弧Pygame

正如你可以看到,藍線是非常波浪和它有白點。我正在通過使用pygame.draw.arc()函數實現這條藍線,但它不是反鋸齒,看起來很糟糕。我想它是反鋸齒的,但gfxdraw模塊應該讓我實現這一點,不支持弧寬選擇。這裏的代碼片段:

pygame.draw.arc(screen, blue, [center[0] - 120, center[1] - 120, 240, 240], pi/2, pi/2+pi*i*koef, 15) 
pygame.gfxdraw.aacircle(screen, center[0], center[1], 105, black) 
pygame.gfxdraw.aacircle(screen, center[0], center[1], 120, black) 

回答

0

我不知道這將解決這個問題的任何pygame的功能,這意味着你基本上要編寫自己的解決方案(或使用比pygame的其他東西),因爲draw壞了你」已經注意到並且gfxdraw不會給你厚度。

其中一個非常難看但簡單的解決方案是在弧段上多次繪製,總是稍微移動以「填充」缺失的空隙。這仍然會留下一些混淆在計時器弧的很靠前,但其餘的將被填滿。

import pygame 
from pygame.locals import * 
import pygame.gfxdraw 
import math 

# Screen size 
SCREEN_HEIGHT = 350 
SCREEN_WIDTH = 500 

# Colors 
BLACK = (0, 0, 0) 
WHITE = (255, 255, 255) 
GREY = (150, 150, 150) 
RED = (255,0,0) 


# initialisation 
pygame.init() 
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) 
done = False 
clock = pygame.time.Clock() 

# We need this if we want to be able to specify our 
# arc in degrees instead of radians 
def degreesToRadians(deg): 
    return deg/180.0 * math.pi 

# Draw an arc that is a portion of a circle. 
# We pass in screen and color, 
# followed by a tuple (x,y) that is the center of the circle, and the radius. 
# Next comes the start and ending angle on the "unit circle" (0 to 360) 
# of the circle we want to draw, and finally the thickness in pixels 
def drawCircleArc(screen,color,center,radius,startDeg,endDeg,thickness): 
    (x,y) = center 
    rect = (x-radius,y-radius,radius*2,radius*2) 
    startRad = degreesToRadians(startDeg) 
    endRad = degreesToRadians(endDeg) 

    pygame.draw.arc(screen,color,rect,startRad,endRad,thickness) 


# fill screen with background 
screen.fill(WHITE) 
center = [150, 200] 
pygame.gfxdraw.aacircle(screen, center[0], center[1], 105, BLACK) 
pygame.gfxdraw.aacircle(screen, center[0], center[1], 120, BLACK) 

pygame.display.update() 

step = 10 
maxdeg = 0 

while not done: 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      done = True 

    maxdeg = maxdeg + step 
    for i in range(min(0,maxdeg-30),maxdeg): 
     drawCircleArc(screen,RED,(150,200),119,i+90,max(i+10,maxdeg)+90,14) 
     #+90 will shift it from starting at the right to starting (roughly) at the top 
    pygame.display.flip() 

    clock.tick(2) # ensures a maximum of 60 frames per second 

pygame.quit() 

注意,我從https://www.cs.ucsb.edu/~pconrad/cs5nm/08F/ex/ex09/drawCircleArcExample.py

複製degreesToRadiansdrawCircleArc我一般不推薦這種解決方案,但它可能會在一個捏。

+0

看起來更好,但仍然不完美。我會嘗試谷歌或考慮其他可能的解決方案 –

+1

Easiert的方式,如果你需要使用pygame將只是在圖形程序中做,並從spritesheet blit計數器的步驟。如果你只需要在少數幾個地方,手寫黑客可能不值得。 – Isa

+1

爲什麼不繪製下一個段,然後應用洪水填充? –

0

小,我已經用Python寫的森林火災算法的ASCII藝術風格演示:

import sys 

class Canvas: 
    def __init__(self): 
     self.rows=10 
     self.columns=10 
     self.cells = {(r,c):None for r in range(1,self.rows+1) for c in range(1,self.columns+1)} 
     for i in range(3,6): 
      self.cells[(i,5)] = 1 
      self.cells[(i,8)] = 1 
     for i in range(5,8): 
      self.cells[(3,i)] = 1 
      self.cells[(6,i)] = 1 

    def display(self): 
     for i in range(1,self.rows): 
      for j in range(1,self.columns): 
       sys.stdout.write("*" if self.cells[(i,j)] else " ") 
      sys.stdout.write("\n") 


    def fill(self, x, y, t): 
     if not self.cells[(x,y)]: 
      to_fill = [(x,y)] 
      while to_fill: 
       # pick a point from the queue 
       x,y = to_fill.pop() 
       # change color if possible 
       self.cells[(x,y)] = t 

       # now the neighbours x,y +- 1 
       for delta_x in range(-1,2): 
        xdx = x+delta_x 
        if xdx > 0 and xdx < self.columns+1: 
         for delta_y in range(-1,2): 
          ydy = y+delta_y 
          # avoid diagonals 
          if (delta_x == 0)^(delta_y == 0): 
           if ydy > 0 and ydy < self.rows+1: 
            # valid x+delta_x,y+delta_y 
            # push in queue if no color 
            if not self.cells[(xdx,ydy)]: 
             to_fill.append((xdx,ydy)) 

c = Canvas() 
c.display() 
c.fill(4,6,2) 
c.display() 

所以基本上它創建了一個空白的畫布,畫在它是一種醜陋的空心矩形(第一圖) ,執行洪水填充和再次提請填充矩形:

**** 
    * * 
    * * 
    *** 





    **** 
    **** 
    **** 
    *** 

在開始時,你可以只畫2線劃定的區域,稱這種顏色填充方法通過X,在該區域一個點的y。

然後,對於下一次填充,只需繪製下一行,然後重複。