스푸79 기록 보관소

운석 피하기 게임 개발(6)- 운석 처리(1) 본문

게임개발

운석 피하기 게임 개발(6)- 운석 처리(1)

스푸79 2024. 8. 26. 08:00

운석 피하기 게임이니깐 운석이 메인 캐릭터를 향해 날라오게 처리해 보도록 하겠다.

ChatGPT님께 그동안 신세를 좀 졌으니

오늘은 혼자 코딩을 해보겠다.ㅎ

 

우선 아래와 같은 총 8개의 운석 asset을 준비했다.

 

meteor.py 파일을 새로 만들어서 Meteor class를 하나 새로 만들었다.

총 4개의 운석 번호 01, 02, 03, 04 중에서 임의로 한개를 뽑고, 2개 형태의 운석 모양 중에 한개를 뽑도록 했다.

import pygame
import random
from enviroment import Enviroment as env

class Meteor(pygame.sprite.Sprite):
    def __init__(self, s_pos, d_pos):
        super().__init__()
        meteor_color = random.choice(['01', '02', '03', '04']) 
        meteor_type = random.choice(['A', 'B'])
        image_info = env.GAME_IMG_DIR + "meteor_" + meteor_color + "_" + meteor_type + ".png"
        self.image = pygame.image.load(image_info)
        self.rect = self.image.get_rect()
        self.rect.center = (s_pos)
        self.pos = s_pos
        self.speed = random.randint(1, 5)
        self.velocity = self.speed
        self.target = (pygame.Vector2(d_pos) - pygame.Vector2(s_pos))
        self.target.normalize_ip()

    def update(self):
        self.move()        
        
    def move(self):
        self.velocity = self.target * self.speed
        self.pos += self.velocity
        self.rect = self.image.get_rect()
        self.rect.center = (self.pos)

 

위의 코드 중 s_pod, d_pos 이 두 파라미터는 중요한 역할을 한다.

d_pos는 destination_pos로 메인 캐릭터의 현재 위치

s_pos는 source_pos로 현재 생성된 운석의 위치가 된다.

self.target = pygame.Vector2(d_pos) - pygame.Vector2(s_pos) 의 값은 vector값으로

메인 캐릭터를 향해 나아가는 vector값으로 변환이 된다.

(즉, 현재 운석은 메인 캐릭터를 향해 나아가는 것이다. 운석을 조준해서 쏘는 것과 동일하다.)

self.target.normalize_ip() 처리를 해주면 해당 vector값은 속도가 1로 처리가 된다.

 

main.py에서 운석을 소환하는 method를 만들 생각이다.

self.meteor_spawn_delay_time = 500 으로 설정해서 0.5 초 간격으로 생성하도록 처리했다.

if pygame.time.get_ticks() - self.meteor_spawn_time > self.meteor_spawn_delay_time:

 

위의 코드는 현재 시간에서 마지막 운석이 소환된 시간을 빼서 0.5보다 큰 경우에 동작하도록 처리하는 로직이다.

 

environment 에 각 생성 위치 TOP 1, RIGHT 2, BOTTOM 3, LEFT 4로 설정해 준 후 random하고 위치를 잡도록 했다.

그리고 25퍼센트의 확률로 운석이 반대편으로 직선으로 나아가도록 처리했다.

모든 운석이 메인 캐릭터를 향하는 건 너무 인위적인 느낌이 나기 때문이다.

... 생략 ...
from meteor import Meteor # 운석클래스 import 


class Main():
    def __init__(self):        
        ... 생략 ...
        self.meteor_sprites = pygame.sprite.Group() # 운석 sprites group 생성
        self.meteor_spawn_delay_time = 500 # 운석 delay time 0.5초 (1000 = 1초)
        self.meteor_spawn_time = pygame.time.get_ticks()

    def play(self):
        while self.running:
            ... 생략 ...
            self.meteor_sprites.update() # meteor sprites 움직임 업데이트
            self.spawnMeteor() # meteor 생성 처리
            
            ...생략...

            self.meteor_sprites.draw(self.screen) # meteor sprites 화면 그리기

            pygame.display.flip()
            self.clock.tick(env.FPS)

    
    def spawnMeteor(self):
        #0.5초마다 한개씩 생성
        if pygame.time.get_ticks() - self.meteor_spawn_time > self.meteor_spawn_delay_time:
            dir = random.randint(1, 4)
            if dir == env.TOP:
                pos = (random.randint(0, env.WIDTH), 0)
            elif dir == env.RIGHT:
                pos = (env.WIDTH, random.randint(0, env.HEIGHT))
            elif dir == env.BOTTOM:
                pos = (random.randint(0, env.WIDTH), env.HEIGHT)
            elif dir == env.LEFT:
                pos = (0, random.randint(0, env.HEIGHT))

            if random.randint(1, env.METEOR_DIR_CHANE) == 1: #25% 확률 일직선 처리
                if dir == env.TOP:
                    d_pos = (pos[0], env.HEIGHT)
                elif dir == env.RIGHT:
                    d_pos = (0, pos[1])
                elif dir == env.BOTTOM:
                    d_pos = (pos[0], 0)
                elif dir == env.LEFT:
                    d_pos = (env.WIDTH, pos[1])                
            else:
                d_pos = (self.player.rect.centerx, self.player.rect.centery)

            meteor = Meteor(pos, d_pos)
            self.meteor_sprites.add(meteor)
            self.meteor_spawn_time = pygame.time.get_ticks() #spawn 시간 현재시간으로 초기화

if __name__ == "__main__":    
    gameMain = Main()
    gameMain.play()
    pygame.quit()

 

최종 결과 화면은 아래와 같다.

 

 

결과물을 보고 나서 뭔가 심심하다는 느낌이 들지 않는가?

이유는 운석이 살아있다는 느낌을 주지 않기 때문이다.

우주 공간을 날아다는 운석이 저렇게 회전도 없이 밋밋하게 돌아다니는 건 말이 되지 않기 때문이다.

또 크기가 너무 일정하다.

다음 포스트는 이 문제를 해결할 계획이다.

 

또 오늘 작성한 코드에는 심각한 문제가 있다. 이건 여러분이 직접 찾아서 수정해 보길 바란다.

힌트를 아래에 캡쳐해 보겠다.

 

 

05. meteor.zip
0.02MB