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. 7. 15. 22:10

보스전은 그동안 여러 종류의 총알을 구현하면서 사용한 코드를 그대로 재활용해서 구현해 보았다.

보스의 본체 위에 터렛을 올리고 보스와 터렛이 함께 움직이도록 처리했다.

그리고 총알 발사하는 로직은 기존에 개발한 조준탄, n-way탄, 원형 회전탄을 거의 그대로 사용했다. 

수정한 부분은 거의 발사 간격 정도이다.

 

보스의 움직임은 처음에는 좌우로 한번 움직이고

그리고 가운데로 이동 한 뒤에 아래로 이동했다가 다시 제자리로 돌아오도록 처리했다.

움직임을 처리하는 데이터는 배열 형태로 만들었다.

보스의 움직임 배열의 기본 구조는 아래와 같다.

0 start_x (시작 위치 -1인 경우 현재 위치)
1 start_y (시작 위치 -1인 경우 현재 위치)
2 dx (x의 좌표 이동값)
3 dy (y의 좌표 이동값)
4 speed (속도)
5 theta (방향, -1인 경우 현재 방향 유지)
6 duration (지속시간)

방향 부분은 여기서는 구현을 하지 않았는데 나중에 적기의 편대 비행을 구현할 때 구현해 볼 생각이다.

 

아래는 위의 움직임 배열과 터렛을 설정하는 보스클래스는 초기화 부분 소스코드이다.

class EnemyBoss(pygame.sprite.Sprite):
    def __init__(self, x, y, GameMain):
        pygame.sprite.Sprite.__init__(self)
        self.images = \
            [pygame.image.load(img_dir + "/img/boss_template.png")]
        self.image = self.images[0]
        self.rect = self.image.get_rect()
        self.rect.center = [x, y]
        self.speed = 4        
        self.x = x
        self.y = y
        self.current_frame = 0
        self.movement_idx = 0
        self.movement_data = [[-1, -1, 1, 0, 1, -1, 180]
                             ,[-1, -1, -1, 0, 1, -1, 180]
                             ,[-1, -1, -1, 0, 1, -1, 180]
                             ,[-1, -1, 1, 0, 1, -1, 180]
                             ,[-1, -1, 0, 1, 3, -1, 150]
                             ,[-1, -1, 0, -1, 3, -1, 150]]        
        self.turret01 = EnemyTurret03(250, 112)
        self.turret02 = EnemyTurret01(289, 95)
        self.turret03 = EnemyTurret01(412, 95)
        self.turret04 = EnemyTurret03(450, 112)
        self.turret05 = EnemyTurret02(350, 65)
        self.turret06 = EnemyTurret02(350, 105)
        self.id = None

 

보스의 본체 이미지는 보면 검은색 동그라미 부분이 보인다.

이 검은색 동그라미 부분에 터렛이 위치할 것이다.

turret01~06에는 다른 예제를 만들면서 개발한 enemy class를 그대로 선언해서 넣었다.

 

아래는 보스 클래스의 update 영역의 소스코드이다. 

매 프레임마다 현재 프레임을 체크하면서 움직임 데이터에 설정된 값에 따라 움직이도록 처리했다.

지속시간(duration)이 현재 프레임 값보다 커지면

프레임값을 초기화 시키고 다음 움직임 배열을 불러오도록 처리했다.

그리고 배열에 선언된 모든 움직임을 마치면 바로 처음부터 다시 반복하도록 했다.

    def update(self, GameMain):
        self.current_frame += 1
        self.move()

    def move(self):
        if self.movement_idx >= len(self.movement_data):
            self.movement_idx = 0

        dx = self.movement_data[self.movement_idx][2] 
        dy = self.movement_data[self.movement_idx][3]
        speed = self.movement_data[self.movement_idx][4]
        duration = self.movement_data[self.movement_idx][6]

        sync_dx = dx * speed
        sync_dy = dy * speed

        self.x += sync_dx
        self.y += sync_dy
        self.left_turret01.move(sync_dx, sync_dy)
        self.left_turret02.move(sync_dx, sync_dy)
        self.left_turret03.move(sync_dx, sync_dy)
        self.left_turret04.move(sync_dx, sync_dy)
        self.left_turret05.move(sync_dx, sync_dy)
        self.left_turret06.move(sync_dx, sync_dy)

        self.rect.centerx = int(self.x)
        self.rect.centery = int(self.y)

        if self.current_frame >= duration:
            self.movement_idx += 1
            self.current_frame = 0

보스 클래스를 선언한 후 sprite_group에 추가할 때 유의할 점이 있다.

바로 터렛이 boss sprite group에 본체보다 나중에 추가되어야 한다는 것이다.

왜냐하면 pygame에서는 별도의 layer처리가 없기 때문에 등록된 순서대로 처리가 된다.

쉽게 말해 나중에 그려진게 먼저 그려진 그림을 엎어버리는 것이다.

터렛이 본체보다 먼저 add가 되면 화면에 보이지 않게 된다.

따라서 아래 코드와 같이 순서를 생각해서 sprite group에 add 시켜야한다.

        boss = EnemyBoss(350, 100, GameMain)
        self.boss_group.add(boss)
        self.boss_group.add(boss.turret01)
        self.boss_group.add(boss.turret02)
        self.boss_group.add(boss.turret03)
        self.boss_group.add(boss.turret04)
        self.boss_group.add(boss.turret05)
        self.boss_group.add(boss.turret06)

보스 움직이는 부분을 제외하고는 사실 기존의 코드를 거의 그대로 활용했기 때문에 크게 설명할 부분은 없다.

 

기존에 개발한 원형탄이나 nway탄이 보스의 위,아래 움직임에 따라 다양한 궤적을 보여주는데

움직임 데이터를 조금 더 상세하게 직접 변경해 보기 바란다.

예제에서 사용된 소스 코드를 첨부한다.

07_boss.zip
0.05MB

다음 번에는 적기의 편대 비행을 구현해 올려 보도록 하겠다.