반응형

지금까지 진행된 프로젝트를 실행했을 경우 공이 이리저리 잘 튕기고 막대로 공을 튕겨내는 것도 가능하긴 하지만 공이 움직이는 각도는 바뀌지 않습니다.
이럴 경우 공의 움직임은 너무 단조롭게 됩니다. 따라서 실제 벽돌깨기 게임을 보면 공을 튕겨내는 막대의 어느 위치에 공이 맞느냐에 따라 공이 움직이는 각도가 달라지게 됩니다.

공이 맞는 위치에 따라 공의 이동 방향이 달라집니다

위 그림에서 보듯 공이 어디에 부딪치느냐에 따라 공의 방향을 바꿔 줄것 입니다.

    #barx : 막대의 x 좌표
    def collideBar(self,barx):
        self.diry *=-1
        
        #공의 x 좌표가 바의 x 좌표보다 작은건 바의 왼쪽부분에 부딪쳤다는것입다
        #이때 공은 왼쪽방향으로 반사됩니다.
        #반대의 경우엔 바의 오른쪽에 부딪쳤다는 것으로 공은 오른쪽방향으로 반사됩니다
        bx = barx - self.rect.center[0]
        if self.rect.center[0] < barx:
            self.moveLeft(bx)
        elif barx < self.rect.center[0]: 
            self.moveRight(bx)

막대와 공의 충돌시에 호출되는 함수에 막대의 x 좌표를 인자로 넘겨 줍니다.

barx 좌표는 공을 튕겨내는 막대 중심의 X 좌표 입니다. 공의 x 좌표는 rect.center[0] 로 얻을 수 있기 때문에 이 두 변수를 비교해서 공이 막대의 왼쪽에 맞았는지 오른쪽에 맞았는지를 판단 할 수 있게 됩니다.

또한 위의 두 값을 빼기를 해보면(barx -self.rect.center[0]) 막대의 어느 위치에 충돌했는지도 알 수 있습니다. 따라서 이 충돌 위치에 따라 공의 새로운 이동각도를 구할 수 있습니다.

 

    def moveLeft(self,bx):
        self.angle = 191 + bx
        self.dirx=1
        
    def moveRight(self,bx):
        self.angle = 169 + bx
        self.dirx=1

위의 moveLeft 와 moveRight 함수는 각각 공을 왼쪽으로 보낼것인지 오른쪽으로 보낼것인지에 따라 호출 됩니다.

공을 왼쪽으로 보내기 위해서는 180 ~ 270 도 사이의 각도로 설정을 해야 합니다. 다만 180 과 270도는 수직, 수평으로 공이 이동되기 때문에 실제로는 190~260도 사이로 값을 변경하게 됩니다.
따라서 각도는 191에 "barx -self.rect.center[0]" 값을 더해서 공의 새로운 이동 각도를 구하게 됩니다.

공을 오른쪽으로 보내는 것도 마찬가지 입니다.
공을 오른쪽으로 보내기 위해서는 90~180 도 사이의 각도로 설정해야 합니다. 다만 위와 같은 이유로 실제 각도는 100~170 도 사이에서 결정되게 됩니다.

사실 이 경우는 막대의 크기가 144로 반으로 나눌경우 72 이기 때문에 좀 쉽게 한 편입니다. 위에서 설명했듯이 각도의 범위가 100~170 도로 막대의 길이와 비슷했기에 단순히 더하고 빼는 것 만으로 새로운 각도를 쉽게 구할 수 있었습니다. 만일 막대의 크기가 크거나 작아서 새로운 공의 이동각도를 단순히 더하기 빼기로 구하기 어려울 경우엔 막대의 길이와 각도와의 비율을 이용해서 새로운 공의 이동 각도를 구해야 할 것입니다.


마지막으로 소스에서 "self.dirx=1" 란 문장이 있는데 이는 각도에 맞게 공을 이동 시키기 위한 것입니다. 공이 왼쪽이나 오른쪽벽에 부딪히면 dirx에 -1 을 곱해 부호를 바꿔주어 공이 벽에서 반사되어 움직이게 됩니다. 그런데 우리가 원하는 대로, 예를 들어 100~170도 사이로 공을 보내려고 할때는 dirx가 마이너스 값이면 공은 반대로 190~260도 방향으로 날아가게 됩니다. 그렇기 때문에 우리가 원하는 각도를 입력해서 공의 방향을 정해줄 때는 dirx는 언제나 플러스 값으로 바꿔주어야 합니다. 

지금 생각엔 아예 처음부터 각도와 부호를 이용해서 이동방향을 정해주는게 더 간단했을지도 모르겠다는 생각도 들기는 합니다만......여러분이 직접 바꿔 보는것도 좋겠지요. ^^;

 

+ Recent posts