총알 쏘기, 적과 충돌 처리
저번 1편에 이어서 chatGPT를 활용한 게임 만들기를 진행 보기로 하겠습니다. 1편에서는 단순한 이동만 가능했지만 2편에서는 총알을 쏘고 플레이어가 적과 충돌을 처리하는 부분을 추가해서 구현해 보도록 하겠습니다.
1편 참고 https://deer.cafe24.com/chatgpt-갤러그-게임-만들기
나: 갤러그 게임에 총 쏘는 기능을 추가해줘
이번에도 chatGPT에게 질문을 해보도록 하겠습니다.
chatGPT: 갤러그 게임에 총을 쏘는 기능을 추가하려면, 총알 이미지를 준비하고, 총알의 속도, 크기, 총알 발사 위치 등을 설정해야 합니다. 아래는 간단한 총알을 발사하는 코드 예시입니다:
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import pygame import random # 게임 초기화 pygame.init() # 게임 화면 설정 screen_width = 480 screen_height = 640 screen = pygame.display.set_mode((screen_width, screen_height)) # 총알 이미지 로드 bullet_img = pygame.image.load("bullet.png") # 총알 클래스 class Bullet: def __init__(self, x, y, speed): self.image = bullet_img self.rect = self.image.get_rect() self.rect.center = (x, y) self.speed = speed def update(self): self.rect.y -= self.speed # 게임 루프 while True: # 이벤트 처리 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: # 총알 발사 bullet = Bullet(player.rect.centerx, player.rect.top, 10) bullet_list.add(bullet) # 총알 업데이트 for bullet in bullet_list: bullet.update() # 화면 업데이트 screen.fill((0, 0, 0)) bullet_list.draw(screen) pygame.display.flip() |
위 코드에서는 Bullet
클래스를 정의하여 총알을 만들고, bullet_list
에 추가하여 화면에 그립니다. 총알의 속도는 10으로 설정하였고, 스페이스바를 누르면 Bullet
클래스의 인스턴스를 만들어 bullet_list
에 추가합니다. 추가된 총알들은 update()
메소드를 이용하여 화면에 그려지게 됩니다.
이 코드는 기본적인 총알 발사 기능만을 구현하였으며, 게임 전반적인 내용을 고려하여 추가적인 코드를 작성해야 합니다.
알려준 코드는 총알 쏘는 코드만 들어가 있고 전체적으로 수정이 필요해 보입니다. 질문을 바꿔서 다시 해보았습니다.
나:실행가능하도록 코드를 전부 알려줘
chatGPT: 네, 아래는 갤러그 게임 코드 전체입니다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
import pygame import random pygame.init() # 게임 화면 설정 screen_width = 600 screen_height = 800 screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("Galaga") # 게임 변수 초기화 player_img = pygame.image.load("player.png").convert_alpha() player = pygame.sprite.Sprite() player.img = player_img player.rect = player_img.get_rect() player.rect.centerx = screen_width // 2 player.rect.bottom = screen_height bullet_list = pygame.sprite.Group() # 총알 그룹 enemy_list = pygame.sprite.Group() # 적 그룹 enemy_count = 0 # 적 생성 카운트 explosion_sound = pygame.mixer.Sound("explosion.wav") # 폭발 효과음 score = 0 # 게임 점수 clock = pygame.time.Clock() # 시계 객체 # 적 클래스 class Enemy(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.img = pygame.image.load("enemy.png").convert_alpha() self.rect = self.img.get_rect() self.rect.centerx = x self.rect.centery = y self.speed = 3 def update(self): self.rect.y += self.speed if self.rect.top > screen_height: self.kill() # 총알 클래스 class Bullet(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.img = pygame.image.load("bullet.png").convert_alpha() self.rect = self.img.get_rect() self.rect.centerx = x self.rect.centery = y self.speed = -10 def update(self): self.rect.y += self.speed if self.rect.bottom < 0: self.kill() # 게임 루프 running = True while running: # 이벤트 처리 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: bullet = Bullet(player.rect.centerx, player.rect.top) bullet_list.add(bullet) # 키 입력 처리 keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: player.rect.x -= 5 if player.rect.left < 0: player.rect.left = 0 elif keys[pygame.K_RIGHT]: player.rect.x += 5 if player.rect.right > screen_width: player.rect.right = screen_width # 게임 로직 enemy_count += 1 if enemy_count == 50: enemy = Enemy(random.randint(0, screen_width), 0) enemy_list.add(enemy) enemy_count = 0 # 충돌 처리 for bullet in bullet_list: enemies = pygame.sprite.spritecollide(bullet, enemy_list, True) for enemy in enemies: explosion_sound.play() score += 100 bullet.kill() enemies = pygame.sprite.spritecollide(player, enemy_list, True) if len(enemies) > 0: explosion_sound.play() running = False # 그리기 screen.fill((0, 0, 0)) screen.blit(player_img, player.rect) bullet_list.draw(screen) enemy |
코드가 출력되는 도중에 멈췄습니다. 이럴경우 다시 알려달라고 하면 이어서 출력해줍니다.
나: 코드가 중간에 짤렸는데 이어서 작성해줘
chatGPT:죄송합니다. 중간에 코드가 누락된 것 같습니다. 전체 코드를 다시 첨부해드리겠습니다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
import pygame import random pygame.init() # 게임 화면 크기 설정 screen_width = 480 screen_height = 640 screen = pygame.display.set_mode((screen_width, screen_height)) # 게임 타이틀 설정 pygame.display.set_caption("Galaga") # 배경 이미지 불러오기 background = pygame.image.load("background.png") # 적 이미지 불러오기 enemy_images = [ pygame.image.load("enemy1.png"), pygame.image.load("enemy2.png"), pygame.image.load("enemy3.png"), pygame.image.load("enemy4.png") ] # 적 클래스 class Enemy: def __init__(self): self.image = random.choice(enemy_images) self.rect = self.image.get_rect() self.rect.x = random.randrange(0, screen_width - self.rect.width) self.rect.y = random.randrange(-150, -100) self.speed = random.randrange(1, 5) def update(self): self.rect.y += self.speed if self.rect.y > screen_height: self.rect.x = random.randrange(0, screen_width - self.rect.width) self.rect.y = random.randrange(-150, -100) self.speed = random.randrange(1, 5) # 플레이어 이미지 불러오기 player_img = pygame.image.load("player.png") player_size = player_img.get_rect().size player_width = player_size[0] player_height = player_size[1] player_x_pos = (screen_width / 2) - (player_width / 2) player_y_pos = screen_height - player_height # 플레이어 클래스 class Player: def __init__(self): self.image = player_img self.rect = self.image.get_rect() self.rect.x = player_x_pos self.rect.y = player_y_pos self.speed = 0 def update(self): self.rect.x += self.speed if self.rect.x < 0: self.rect.x = 0 elif self.rect.x > screen_width - self.rect.width: self.rect.x = screen_width - self.rect.width # 총알 이미지 불러오기 bullet_img = pygame.image.load("bullet.png") bullet_width = bullet_img.get_rect().width bullet_height = bullet_img.get_rect().height # 총알 클래스 class Bullet: def __init__(self, x, y): self.image = bullet_img self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.speed = -10 def update(self): self.rect.y += self.speed if self.rect.y < -bullet_height: self.kill() # pygame 초기화 pygame.init() # FPS clock = pygame.time.Clock() # 플레이어 생성 player = Player() # 적 생성 enemy_list = pygame.sprite.Group() for i in range(10): enemy = Enemy() enemy_list.add(enemy) # 총알 생성 bullet_list = pygame.sprite.Group() # 게임 루프 running = True score = 0 while running: # FPS 설정 clock.tick(60) # 이벤트 처리 for event in pygame.event.get |
또 짤렸습니다. 다시 요청해 보겠습니다.
나: # 이벤트 처리 for event in pygame.event.get 이 부분 부터 다시 알려줘
chatGPT
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# 게임 루프 running = True score = 0 while running: # FPS 설정 clock.tick(60) # 이벤트 처리 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: player.move_left() elif event.key == pygame.K_RIGHT: player.move_right() elif event.key == pygame.K_SPACE: player.shoot(bullet_list) # 게임 로직 처리 for bullet in bullet_list: bullet.move() if bullet.rect.bottom < 0: bullet_list.remove(bullet) # 총알과 적군 충돌 검사 if pygame.sprite.spritecollide(bullet, enemy_list, True): score += 10 # 적군이 화면 아래로 벗어나면 제거 for enemy in enemy_list: if enemy.rect.top > HEIGHT: enemy_list.remove(enemy) # 적군 생성 if len(enemy_list) < 10: enemy = Enemy(enemy_img) enemy_list.add(enemy) # 게임 객체 그리기 screen.fill((0, 0, 0)) screen.blit(background_img, (0, 0)) screen.blit(player_img, player.rect) bullet_list.draw(screen) enemy_list.draw(screen) # 화면에 점수 출력 font = pygame.font.Font(None, 30) score_text = font.render("Score: {}".format(score), True, (255, 255, 255)) screen.blit(score_text, (10, 10)) # 화면 업데이트 pygame.display.flip() # 게임 종료 pygame.quit() |
전체적인 코드가 나온 듯합니다. 비주얼 스튜디오를 실행하여 코드를 조합해보도록 하겠습니다.
(중간에 여러번 질문을 더 하면서 여러 코드를 추가했고 게임오버 시에 재시작을 선택하는 기능도 추가하였습니다.)
전체 코드를 올려보겠습니다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
import pygame import random import sys pygame.init() # 게임 화면 크기 설정 screen_width = 480 screen_height = 640 screen = pygame.display.set_mode((screen_width, screen_height)) # 게임 타이틀 설정 pygame.display.set_caption("Galaga") # 배경 이미지 불러오기 background_img = pygame.image.load("background.png") # 적 이미지 불러오기 enemy_images = [ pygame.image.load("enemy1.png"), pygame.image.load("enemy2.png") ] # 적 클래스 class Enemy(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = random.choice(enemy_images) self.rect = self.image.get_rect() self.rect.x = random.randrange(0, screen_width - self.rect.width) self.rect.y = random.randrange(-150, -100) self.speed = random.randrange(1, 5) def update(self): self.rect.y += self.speed if self.rect.y > screen_height: self.rect.x = random.randrange(0, screen_width - self.rect.width) self.rect.y = random.randrange(-150, -100) self.speed = random.randrange(1, 5) # 플레이어 이미지 불러오기 player_img = pygame.image.load("player.png") player_size = player_img.get_rect().size player_width = player_size[0] player_height = player_size[1] player_x_pos = (screen_width / 2) - (player_width / 2) player_y_pos = screen_height - player_height player_speed = 1 # 플레이어 클래스 class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = player_img self.rect = self.image.get_rect() self.rect.x = player_x_pos self.rect.y = player_y_pos self.speed_x = player_speed def update(self): self.rect.x += self.speed_x if self.rect.x < 0: self.rect.x = 0 elif self.rect.x > screen_width - self.rect.width: self.rect.x = screen_width - self.rect.width # 이동 함수 def move_player(self, x, y): self.rect.x += x self.rect.y += y if self.rect.x < 0: self.rect.x = 0 elif self.rect.x > screen_width: self.rect.x = screen_width if self.rect.y < 0: self.rect.y = 0 elif self.rect.y > screen_height: self.rect.y = screen_height # 총알 이미지 불러오기 bullet_img = pygame.image.load("bullet.png") bullet_width = bullet_img.get_rect().width bullet_height = bullet_img.get_rect().height # 총알 클래스 class Bullet(pygame.sprite.Sprite): def __init__(self, x, y, speed): super().__init__() self.image = bullet_img self.rect = self.image.get_rect() self.rect.center = (x, y) self.speed = speed def update(self): self.rect.y -= self.speed # pygame 초기화 pygame.init() # FPS clock = pygame.time.Clock() def main(): # 플레이어 생성 player = Player() # 적 생성 enemy_list = pygame.sprite.Group() for i in range(10): enemy = Enemy() enemy_list.add(enemy) # 총알 생성 bullet_list = pygame.sprite.Group() # 게임 루프 running = True score = 0 while running: # FPS 설정 clock.tick(60) # 이벤트 처리 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 키 입력 처리 keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: player.move_player(-player_speed, 0) elif keys[pygame.K_RIGHT]: player.move_player(player_speed, 0) elif keys[pygame.K_UP]: player.move_player(0, -player_speed) elif keys[pygame.K_DOWN]: player.move_player(0, player_speed) elif keys[pygame.K_SPACE]: bullet = Bullet(player.rect.centerx, player.rect.top, 10) bullet_list.add(bullet) # 게임 로직 처리 for bullet in bullet_list: bullet.update() bullet_list.draw(screen) if bullet.rect.bottom < 0: bullet_list.remove(bullet) # 총알과 적군 충돌 검사 if pygame.sprite.spritecollide(bullet, enemy_list, True): score += 10 # 적군이 화면 아래로 벗어나면 제거 for enemy in enemy_list: if enemy.rect.top > screen_height: enemy_list.remove(enemy) # 적군 생성 if len(enemy_list) < 10: enemy = Enemy(enemy_images) enemy_list.add(enemy) # 충돌 검사 player_hit_list = pygame.sprite.spritecollide(player, enemy_list, True) if player_hit_list: running = False # 게임 객체 그리기 screen.fill((0, 0, 0)) screen.blit(background_img, (0, 0)) screen.blit(player_img, player.rect) enemy_list.update() enemy_list.draw(screen) # 화면에 점수 출력 font = pygame.font.Font(None, 30) score_text = font.render("Score: {}".format(score), True, (255, 255, 255)) screen.blit(score_text, (10, 10)) # 화면 업데이트 pygame.display.flip() # 게임 오버 메시지 출력 if not running: game_over_font = pygame.font.Font(None, 50) game_over_text = game_over_font.render("GAME OVER", True, (255, 0, 0)) screen.blit(game_over_text, (screen_width/2 - game_over_text.get_width() / 2, screen_height/2 - game_over_text.get_height()/2)) # 다시하기/종료 선택 메시지 출력 font = pygame.font.Font(None, 30) restart_text = font.render( "Press R to restart or Q to quit", True, (255, 255, 255)) screen.blit(restart_text, (screen_width/2 - restart_text.get_width() / 2, screen_height/2 + game_over_text.get_height()/2 + 10)) # 키 입력 대기 while True: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_r: # 다시 시작 main() elif event.key == pygame.K_q: # 종료 pygame.quit() sys.exit() pygame.display.update() main() |
이 코드를 실행하게 되면 enemy와 player가 충돌하는 경우 게임이 종료되고 게임오버를 화면에 출력하고 재도전 여부를 묻는 화면이 나타나게 됩니다.
총알과 적의 충돌부분은 3편에 이어서 작성하겠습니다….(코드는 구현이 되었는데 약간의 오류가 있네요,, 오류를 잡고 글을 이어나가도록 하곗습니다.)
![]() | ![]() |
게임오버시 재시작 여부를 추가하였습니다