본문 바로가기

[Pygame] ✈️ 전투기 슈팅 게임 만들기 7강 | 연사 제한(발사 쿨타임) 만들기

@도마22026. 1. 17. 19:00
728x90


1. 이번 강의 목표

이번 강의에서는 스페이스바를 누르고 있어도 총알이 무한으로 쏟아지지 않도록
발사에 쿨타임(연사 제한) 을 적용합니다.

구현할 내용은 다음과 같습니다.

  • 발사 간격(밀리초) 설정
  • 마지막 발사 시간 기록
  • 현재 시간과 비교하여 발사 가능 여부 판단

2. 왜 연사 제한이 필요한가요?

현재 코드는 스페이스바를 누르고 있으면 FPS(60) 기준으로 초당 60발이 나갑니다.
이러면

  • 게임 난이도가 무너지고
  • 총알이 너무 많아져서 성능도 떨어질 수 있습니다.

그래서 슈팅게임은 보통 발사 속도를 다음처럼 제한합니다.

  • 초당 5~10발 정도(상황에 따라 다름)

3. 시간은 pygame.time.get_ticks()로 관리합니다

Pygame은 게임이 시작된 후 경과 시간을 밀리초(ms)로 제공하는 함수가 있습니다.

pygame.time.get_ticks()

예를 들어 게임 시작 후 3초가 지나면 3000 같은 값이 됩니다.


4. 쿨타임 변수 만들기

다음 변수를 추가합니다.

fire_delay = 150
last_fire_time = 0

 

  • fire_delay: 발사 간격(ms) - 150ms면 초당 약 6~7발 정도입니다.
  • last_fire_time: 마지막으로 총알을 발사한 시간(ms)

5. 발사 로직 변경하기

기존에는 스페이스를 누르는 순간마다 발사했지만,
이제는 “발사 가능한 시간인지” 확인한 뒤 발사합니다.

now = pygame.time.get_ticks()

if keys[pygame.K_SPACE]:
    if now - last_fire_time >= fire_delay:
        last_fire_time = now

        bullet_rect = bullet_img.get_rect()
        bullet_rect.centerx = player_rect.centerx
        bullet_rect.bottom = player_rect.top
        bullets.append(bullet_rect)

 

이렇게 하면 스페이스를 계속 누르고 있어도
fire_delay 간격으로만 총알이 생성됩니다.


6. 실행 결과

이제 실행해보면

  • 스페이스를 눌렀을 때 총알이 “적당한 속도”로 나갑니다.
  • 총알이 과하게 쌓이지 않아 성능도 안정적입니다.
  • 슈팅게임 특유의 타격감이 살아납니다.

7. 마무리

이번 강의에서는 다음을 구현했습니다.

  • get_ticks()로 시간 측정
  • 발사 쿨타임(연사 제한) 적용
  • 스페이스를 누르고 있어도 일정 간격으로만 발사

이제 총알 발사가 정상적인 슈팅게임처럼 동작합니다.


전체 코드

더보기
import pygame
import sys
import random

pygame.init()

# 화면 설정
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 640
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Shooting Game")

# FPS 설정
clock = pygame.time.Clock()
FPS = 60

# ===== 스프라이트 로드 =====
player_img = pygame.image.load("images/player.png").convert_alpha()
enemy_img = pygame.image.load("images/enemy.png").convert_alpha()
bullet_img = pygame.image.load("images/bullet.png").convert_alpha()

# ===== 스프라이트 크기 조정 =====
PLAYER_SIZE = (40, 40)
ENEMY_SIZE = (40, 40)
BULLET_SIZE = (6, 16)

player_img = pygame.transform.scale(player_img, PLAYER_SIZE)
enemy_img = pygame.transform.scale(enemy_img, ENEMY_SIZE)
bullet_img = pygame.transform.scale(bullet_img, BULLET_SIZE)

# 플레이어 설정 (Rect로 위치/충돌 관리)
player_speed = 5
player_rect = player_img.get_rect()
player_rect.centerx = SCREEN_WIDTH // 2
player_rect.bottom = SCREEN_HEIGHT - 20

# 총알 설정
bullet_speed = 8
bullets = []

# ===== 연사 제한(쿨타임) 설정 =====
fire_delay = 150  # ms (값이 작을수록 연사 빠름)
last_fire_time = 0

# 적 설정
enemy_speed = 3
enemies = []

enemy_spawn_delay = 60
enemy_timer = 0

# 게임 루프
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    keys = pygame.key.get_pressed()

    # ===== 플레이어 이동 =====
    if keys[pygame.K_w]:
        player_rect.y -= player_speed
    if keys[pygame.K_s]:
        player_rect.y += player_speed
    if keys[pygame.K_a]:
        player_rect.x -= player_speed
    if keys[pygame.K_d]:
        player_rect.x += player_speed

    # 화면 밖 제한
    if player_rect.left < 0:
        player_rect.left = 0
    if player_rect.right > SCREEN_WIDTH:
        player_rect.right = SCREEN_WIDTH
    if player_rect.top < 0:
        player_rect.top = 0
    if player_rect.bottom > SCREEN_HEIGHT:
        player_rect.bottom = SCREEN_HEIGHT

    # ===== 총알 발사 (연사 제한 적용) =====
    now = pygame.time.get_ticks()
    if keys[pygame.K_SPACE]:
        if now - last_fire_time >= fire_delay:
            last_fire_time = now

            bullet_rect = bullet_img.get_rect()
            bullet_rect.centerx = player_rect.centerx
            bullet_rect.bottom = player_rect.top
            bullets.append(bullet_rect)

    # 총알 이동
    for b in bullets:
        b.y -= bullet_speed

    # 총알 제거
    for b in bullets[:]:
        if b.bottom < 0:
            bullets.remove(b)

    # ===== 적 생성 =====
    enemy_timer += 1
    if enemy_timer >= enemy_spawn_delay:
        enemy_timer = 0
        enemy_rect = enemy_img.get_rect()
        enemy_rect.x = random.randint(0, SCREEN_WIDTH - enemy_rect.width)
        enemy_rect.y = -enemy_rect.height
        enemies.append(enemy_rect)

    # 적 이동
    for e in enemies:
        e.y += enemy_speed

    # 적 제거
    for e in enemies[:]:
        if e.top > SCREEN_HEIGHT:
            enemies.remove(e)

    # ===== 충돌 처리 (총알 vs 적) =====
    for b in bullets[:]:
        for e in enemies[:]:
            if b.colliderect(e):
                if b in bullets:
                    bullets.remove(b)
                if e in enemies:
                    enemies.remove(e)
                break

    # ===== 화면 그리기 =====
    screen.fill((0, 0, 0))

    # 플레이어
    screen.blit(player_img, player_rect)

    # 총알
    for b in bullets:
        screen.blit(bullet_img, b)

    # 적
    for e in enemies:
        screen.blit(enemy_img, e)

    pygame.display.update()
    clock.tick(FPS)

pygame.quit()
sys.exit()

728x90
도마2
@도마2 :: 도마의 코드노트

초보자를 위한 코딩 강의를 정리합니다. 파이썬부터 C#, Unity 게임 제작까지 차근차근 기록합니다. — 도마

목차