Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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 31
Archives
Today
Total
관리 메뉴

개발이 취미인 개발자

슈팅게임 알고리즘-조준탄 구현하기 본문

슈팅게임 알고리즘(pygame)

슈팅게임 알고리즘-조준탄 구현하기

도그풋79 2022. 4. 4. 16:13

플레이어 위치를 향해 발사되는 총알(조준탄)을 구현해보자.

총알이 발사되는 위치 좌표를 sx, sy 라고 하고

플레이어의 위치를 tx, ty 라고 할 때

발사되는 위치와 플레이어의 위치는 아래와 같은 그림으로 나타낼 수 있다.

조준탄이 발사되면 위 그림의 삼각형의 빗변을 따라 위치가 이동하게 된다.

atan2 함수를 이용하면 총알이 발사되는 각도를 구할 수가 있다.

math.atan2를 통해 구해지는 값은 라디언 값으로 cos, sin 함수를 이용하면

위의 삼각형 빗변을 따라 이동하는 좌표 x, y를 구할 수가 있다.

        self.angle = math.atan2(ty - sy, tx - sx)
        self.theta = math.degrees(self.angle) * -1

총알이 발사되기 전 포탑이 플레이어 위치를 계속 조준하게 만들려면 조준하고 있는 방향을 바꿔줘야 한다.

이때 atan2를 통해 구한 값을 math.degree 함수를 이용하면 각도로 변경할 수 있다. 이 각도값을 활용하면

transform.rotate 함수를 통해 포탑의 이미지를 회전시킬 수가 있다.

def __init__(self, x, y, angle, theta, speed):
        pygame.sprite.Sprite.__init__(self) 
        self.image = pygame.transform.rotate(\
            pygame.image.load(img_dir + "/img/enemy_bullet_01.png"), theta)
		self.rect = self.image.get_rect()
        self.rect.center = [x, y]
        self.angle = angle
        self.speed = speed
        self.max_speed = 10.0        
        self.x = x
        self.y = y

 

    def update(self, GameMain):
        self.dx = math.cos(self.angle) * self.speed
        self.dy = math.sin(self.angle) * self.speed
        if self.max_speed > self.speed:
            self.speed += 0.2

        self.x += self.dx
        self.y += self.dy
        self.rect.centerx = int(self.x)
        self.rect.centery = int(self.y)

조준탄이 움직이는 위치는 cos, sin함수를 통해 구할 수가 있다.

총알의 속도를 매 프레임마다 0.2 정도 증가시켜 주는데 그렇지 않으면 조준탄의 속도가 일정하기 때문에 플레이어가 총알을 피하기가 쉬어진다. 속도감을 주기 위해서는 위의 코드처럼 최고 속도에 도달 할때까지 속도를 올려주는 것이 좋다.

 

또 위의 코드를 보면 int로 형변환을 하는데 그 이유는 pygame은 소숫점 좌표를 정할 수가 없기 때문이다.

하지만 정확한 위치까지 총알이 도달하려면 소숫점을 포함한 계산이 필요하다.

x, y의 좌표값을 계속 누적시키면서 소숫점 값을 유지하고

마지막 총알이 그려질 때의 좌표만 int형으로 변환해야 원래 목표했던 위치에 도달하게 된다.

 

전체 소스코드를 압축해서 올려본다. 압축을 풀고 game_main.py를 실행하면 된다.

01_aiming_bullet.zip
0.01MB