블로그 이미지
Leeway is... the freedom that someone has to take the action they want to or to change their plans.
maetel

Notice

Recent Post

Recent Comment

Recent Trackback

Archive

calendar

1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
  • total
  • today
  • yesterday

Category

2007. 7. 18. 12:41 Code/NodeBox
The mission I chose:
사용자 삽입 이미지

David Hirmes - blobs01

from Flash Math Creativity


우선, blob 하나의 움직임을 코딩해 보자.
#hirmes_blobs01_0.0

size(400, 200)
speed(100)

def setup():
    global x
    global v
    global a
   
    global check
    global c

    x = 0
    v = 10
    a = -0.1*v
   
    check = 0
    c = 0

def draw():
    global x
    global v
    global a
   
    global check
    global c
     
    v += a
    x += v
   
    if x > WIDTH:
        x = 0
    if x < 0:
        x = WIDTH
   
    check += c
       
    if v < 0:
        v = 0
        a = 0
        c = 1
    if check == 40:
        v = 15
        a = -1
        check = 0
          
    oval(x, 50, 50, 50)
전에 배운 pattern에서 실마리를 얻어 새로운 pattern을 만들어 보았다.
내가 생각해도 good idea! 쿄쿄.


이것을 아래의 move 메쏘드에 적용하면 된다.  
원하는 결과를 위해서는 다른 색의 방울 두 개에 동시에 동일한 움직임을 주어야 했는데, 이를 위해 Blob 클래스에서 움직임을 주는 메쏘드(move)와 색을 넣어 그리는 메쏘드(ball)를 분리하는 것을 하나의 해결책으로 제시해 보았다.
# hirmes_blobs01_0.1

class Blob:
    def __init__(self):
        self.f = 0
        
        self.x0 = 20
        self.y0 = 100
        self.x1 = 100
        self.y1 = 120
        
        self.v = 10
        self.a = -0.1*self.v
        self.check = 0
        self.c = 0
        
    def move(self):
        self.v += self.a

        self.x0 += self.v
        self.x1 += self.v * 0.8

        ###borders     
        if self.x0 > WIDTH:
            self.x0 = 0
        if self.x1 > WIDTH:
            self.x1 = 0
        if self.x0 < 0:
            self.x0 = WIDTH
        if self.x1 < 0:
            self.x1 = WIDTH  
       
       ###pauses
        self.check += self.c
        
        if self.v < 0:
            self.v = 0
            self.a = 0
            self.c = 1

        if self.check == 40:
            self.v = 15
            self.a = -1
            self.check = 0
        
    def ball(self, d, r, g, b):                    
        fill(r, g, b)
        ovalc(self.x0, self.y0, d, d)
        ovalc(self.x1, self.y1, d, d)
        
       
size(400, 300)
speed(30)


def setup():
    global bb
    
    bb = Blob()

    
def draw():
    global bb
    
    bb.move()
    bb.ball(80, 1, 0, 0)
    bb.ball(70, 1, 1, 1)

def ovalc(cx, cy, w, h):
    x = cx-w/2
    y = cy-h/2
    oval(x, y, w, h)  


이제 방울 수를 늘려 보자.
# hirmes_blobs01_1.0

class Blob:
    def __init__(self):
        ###initial position
        self.x0 = random(-WIDTH,WIDTH)
        self.x1 = random(-WIDTH,WIDTH)
        self.x2 = random(-WIDTH,WIDTH)
        self.x3 = random(-WIDTH,WIDTH)
        self.x4 = random(-WIDTH,WIDTH)
        self.x5 = random(-WIDTH,WIDTH)
        self.x6 = random(-WIDTH,WIDTH)
        self.x7 = random(-WIDTH,WIDTH)
        self.x8 = random(-WIDTH,WIDTH)
        self.x9 = random(-WIDTH,WIDTH)

        tb = 50
        self.y0 = random(tb,HEIGHT-tb)
        self.y1 = random(tb,HEIGHT-tb)
        self.y2 = random(tb,HEIGHT-tb)
        self.y3 = random(tb,HEIGHT-tb)
        self.y4 = random(tb,HEIGHT-tb)
        self.y5 = random(tb,HEIGHT-tb)
        self.y6 = random(tb,HEIGHT-tb)
        self.y7 = random(tb,HEIGHT-tb)
        self.y8 = random(tb,HEIGHT-tb)      
        self.y9 = random(tb,HEIGHT-tb)
              
        self.x = range(10)
        self.x[0] = self.x0
        self.x[1] = self.x1
        self.x[2] = self.x2
        self.x[3] = self.x3
        self.x[4] = self.x4
        self.x[5] = self.x5
        self.x[6] = self.x6
        self.x[7] = self.x7
        self.x[8] = self.x8
        self.x[9] = self.x9
              
        ###factors to make a move
        self.v = 15
        self.a = -0.1*self.v
      
        self.check = 0
        self.c = 0
 
    def move(self):
        self.v += self.a
        self.check += self.c
                 
        ###stop and then move again
        if self.v < 0:
            self.v = 0
            self.a = 0
            self.c = 1
       
        if self.check == 30:
            self.v = 15
            self.a = -0.1*self.v
            self.check = 0
      
       ###to move the centers of blobs
        for i in range(10):
            self.x[i] += self.v * 0.5 * (i+1)
          
            ###borders              
            if self.x[i] > WIDTH:
                self.x[i] = 0
            if self.x[i] > WIDTH:
                self.x[i] = 0
  
    def ball(self, d, r, g, b):                               
        y = range(10)
        y[0] = self.y0
        y[1] = self.y1
        y[2] = self.y2
        y[3] = self.y3
        y[4] = self.y4
        y[5] = self.y5
        y[6] = self.y6
        y[7] = self.y7
        y[8] = self.y8
        y[9] = self.y9
      
        fill(r, g, b)     
        for i in range(10):      
            ovalc(self.x[i], y[i], d, d)

 
size(400, 300)
speed(30)

def setup():
    global bb
  
    bb = Blob()

  
def draw():
    global bb
  
    bb.move()
    bb.ball(110, 1, 1, 1)
    bb.ball(100, 0.6, 0.6, 1)
    background(0, 0, 1)

def ovalc(cx, cy, w, h):
    x = cx-w/2
    y = cy-h/2
    oval(x, y, w, h)

각 방울들이 range 변수(클래스 멤버 self.x)로 조정되고 있는 데 반해, 휴지기를 설정해 주는  self.check 값이 정수로 고정되어 있어 모든 방울들이 일시에 멈추고 일시에 움직인다. self.check를 리스트 x에 관해 정의해야겠다는 결론이다. (이 결정은 총 10시간이 넘는 시도 끝에 포기되었고...)

(다음 날...)
애초에 방울들의 집합을 클래스 안에 넣었던 이유는, 그렇게 하지 않으면 draw()에서 개체별로 방울들을 그리게 되어 원치않은 윤곽선(큰 원)이 남는다고 생각했기 때문이었다. 하지만 아래와 같이 별개의 for 구문을 써서 그리게 되면(ball()) 이 문제가 해결된다. 그러므로 굳이 클래스 안에서 클래스 멤버를 리스트로 만들 이유가 없다. (사실, 아니라면 클래스를 이용해서 얻는 효용이 무엇이란 말인가... 어제의 조악한 코드를 보라. 하나의 판단 착오가 엄청난 삽질을 가져왔음을 알 수 있다.)
v0.0의 코드를 그대로 적용하되, 클래스 외부에서 클래스 멤버에 접근하는 (친숙한) 방식으로 코딩한 다음, 클래스를 보다 깔끔하게 만들기 위해 메쏘드들을 단지 재정리하기만 했다.
 

# hirmes_blobs01_2.1

class Blob:
    def __init__(self,x):      
        self.x = x
        tb = HEIGHT/10
        self.y = random(tb, HEIGHT-tb)
       
        self.v = 20
        self.a = -0.1*self.v
       
        self.check = 0
        self.c = 0
       
    def move(self, m):
        self.v += self.a
        self.x += self.v * m

        ###borders    
        if self.x > WIDTH:
            self.x = 0
        if self.x < 0:
            self.x = WIDTH 
   
    def pause(self, p):
        self.check += self.c
       
        if self.v <= 0:
            self.v = 0
            self.a = 0
            self.c = 1

        if self.check == 20 * p:
            self.v = 20
            self.a = -0.1*self.v
            self.check = 0
            self.c = 0
       
    def ball(self, d, r, g, b):                   
        fill(r, g, b)
        ovalc(self.x, self.y, d, d)
       
def ovalc(cx, cy, w, h):
    x = cx-w/2
    y = cy-h/2
    oval(x, y, w, h)  
       
      
size(600, 300)
speed(60)


def setup():
    global bb
   
    bb = range(10)
    b = range(10)
   
    for i in range(10):
        b[i] = random(WIDTH)   
        bb[i] = Blob(b[i])
   
def draw():
    global bb

    m = range(10)
    p = range(10)
   
    for i in range(10):
        m[i] = (i+1)*0.5       
        p[i] = i+1
       
   
    background(0, 0, 1)
   
    for i in range(10):       
        bb[i].move(m[i])
        bb[i].pause(p[i])
        bb[i].ball(120, 1, 1, 1)

    for i in range(10):
        bb[i].ball(110, 0.6, 0.6, 1)

m과 p에 의해 방울들이 움직이는 속력(거리)과 멈추는 시간(차례)에 변화를 줄 수 있다. 비로소 뭔가 내어 놓을 수 있는 코드가 된 것 같다.
다시 한 번 짚어 보면, 윤곽선을 남기지 않는 문제는 class 내에서 그리는 메쏘드를 별도로 정의해 주는 것만으로 완전히 해결되었던 것이다.

사용자 삽입 이미지

'Code > NodeBox' 카테고리의 다른 글

David Hirmes - lines14  (0) 2007.07.31
David Hirmes - lines02  (0) 2007.07.25
splash_class_multi  (0) 2007.07.13
splash_class  (0) 2007.07.13
progress_class  (0) 2007.07.12
posted by maetel