일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 쿠바전통음악
- 에르난 디아스
- 운석 피하기 게임
- 인생의 해상도
- pygame
- 고양이발 살인사건
- 나는 매트로폴리탄 미술관 경비원입니다.
- 매트로폴리탄
- Ai
- 운석피하기 게임
- 아무도 없는 숲속에서
- 단어가 품은 세계
- 타이핑좀비
- 시집
- Python
- 나는 스물일곱 2등 항해사입니다.
- comfyui
- gymnasium
- 타자연습게임
- 타이핑 몬스터
- Stable diffusion
- 숨결이 바람이 될 때
- Gym
- 게임개발
- openAI
- 황선엽
- frozen lake
- 부에노비스타 소셜클럽
- 트렌드코리아2025
- 어른의 행복은 조용하다
- Today
- Total
스푸79 기록 보관소
운석 피하기 게임 개발(3)- 움직임과 Frame (feat. ChatGPT) 본문
게임 플레이 하는 동안 화면에는 많은 이미지가 그려진다.
화면에 그려지는 이미지는 1초를 기준하는데
이를 프레임(frame)이라고 한다.
게임을 좋아하는 분이라면 어떤 게임에 대한 리뷰에서
'30프레임 보장한다. 60프레임을 보장한다.'
이런 얘기를 들어 본 적이 있으실 것이다.
60프레임이라는 말은 1초에 화면이 60번 그려진다는 것이다.
즉 이미지 한장이 그려지는 시간은 1/60 = 0.01666...초가 되는 것이다.
움직임을 처리하는데 이 프레임은 중요한 기준이 된다.
왜냐하면 내가 개발한 게임이 PC성능 따라서 프레임이 변경될 수 있기 때문이다.
프레임이 변경된다는 건
한장이 그려지는 시간이 바뀐다는 걸 의미하고
게임에 등장하는 캐릭터의 움직임이 PC사양에 따라서 빨라졌다 느려졌다 할 수 있다는 것이다.
이를 처리하는 방법은 두가지가 있다.
첫번째, 프레임이 변경되더라도 움직임에 대한 변화가 발생하지 않도록
프레임당 시간을 캐릭터 속도에 곱해주는 방법이다.
두번째, 게임의 최소 사양을 사용자에게 고정시키고 고정 프레임을 사용하는 방법이다.
이 포스트에서는 두번째 방법을 사용하기로 하겠다.
지난 포스트에 작성한 코드를 ChatGPT에 붙여넣고 60 Frame 고정 처리를 넣어달라고 부탁했다.
import pygame
import sys
import os
GAME_DIR = os.path.dirname(os.path.abspath(__file__))
class Main():
def __init__(self):
self.screen = pygame.display.set_mode((800, 800))
pygame.display.set_caption("Meteor Dodger")
icon = pygame.image.load(GAME_DIR + "/meteor_dodger.ico")
pygame.display.set_icon(icon)
# Clock 객체 생성
self.clock = pygame.time.Clock()
def play(self):
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
self.screen.fill((0, 0, 0))
pygame.display.flip()
# 60 FPS로 프레임 속도 고정
self.clock.tick(60)
if __name__ == "__main__":
gameMain = Main()
gameMain.play()
위의 self.clock 값을 print로 출력해 보면 0.016~0.017 사이의 값이 출력되는 걸 확인할 수 있다.
second_per_frame = self.clock.tick(60)
print("frame time : {0}".format(second_per_frame / 1000.0))
위의 코드 중 self.clock.tick(60)을 위의 코드로 변경 후 실행시켜보자.
출력 결과가 의미하는 것은 play함수 안에 while loop문이 한번 도는 시간은 0.016~0.017초가 걸린다는 뜻
즉, 초당 60프레임이 소요된다는 뜻이다.
움직임 처리하기에 앞서 이 부분을 설명한 이유가 있다.
우리가 왼쪽 방향키를 한번 누르는 시점에서
왼쪽으로 1 만큼 이동시킨다고 가정했을 때
0.016초만에 1pixel 이동하는 것이고 1초에는 총 60pixel이 이동하는 것이다.
우리가 이 강좌에서 사용한 메인 캐릭터 이미지는 아래와 같다.
폭 38px, 높이 41px의 이미지로
해당 이미지가 움직임 속도가
1frame에서 움직임은 최대 38px을 넘지 않도록 고려 해야한다.
그렇지 않으면 자연스럽게 이동하는 것이 아닌 순간 이동을 하듯이 보일 것이다.
이번에는 메인 캐릭터를 상하좌우로 움직이는 코드를 작성해보자.
ChatGPT에게 요청할때 sprites를 사용한 코드로 작성해 달라고 요청해보자.
# 플레이어 스프라이트 클래스 정의
class Player(pygame.sprite.Sprite):
def __init__(self, image_path, x, y):
super().__init__()
self.image = pygame.image.load(image_path) # 이미지 로드
self.rect = self.image.get_rect() # 이미지의 rect 얻기
self.rect.x = x
self.rect.y = y
self.speed = 3 # 이동 속도 설정
def update(self, keys):
# 키 입력에 따른 움직임 처리
if keys[pygame.K_LEFT]:
self.rect.x -= self.speed
if keys[pygame.K_RIGHT]:
self.rect.x += self.speed
if keys[pygame.K_UP]:
self.rect.y -= self.speed
if keys[pygame.K_DOWN]:
self.rect.y += self.speed
나의 경우는 기존 코드에 위의 코드를 붙인 예시를 보내주었다.
지난 포스트에서도 말했듯이 소스코드 파일 하나가 너무 커지는 건 좋지 않다.
player.py라는 별도의 파일을 새로 생성해서 그곳에 코드를 작성하자.
sprites를 사용하는 이유 중 하나가 위의 update 함수에 있다.
update를 확인해 보면 keys 라는 파라미터를 받는데
sprites를 사용하게 되면 같은 sprites그룹에 속한 경우 동일하게 처리가 된다.
속성이 유사한 개체에 대한 처리를 한꺼번에 처리할 수 있게된다.
적이 발사한 총알이나 이 게임에서 등장할 운석같은 경우
같은 속성을 가진 개체로 보고 하나의 코드를 작성해서 여러 개체를 선언함으로
코드가 간결해지고 나중에 수정도 쉬워진다.
player.py 로 파일이 2개로 분리되서 변경된 main.py 코드는 아래와 같다.
수정이 안된 부분은 생략하고
추가 또는 수정된 부분만 표시했다.
...(생략)...
from player import Player #player.py Player class를 import 하기 위해 처리
...(생략)...
class Main():
def __init__(self):
...(생략)...
self.player_sprites = pygame.sprite.Group() #스프라이트 처리를 위한 스프라이트그룹 생성
self.player = Player(400, 400) # Player 클래스 객체화
self.player_sprites.add(self.player)
def play(self):
while True:
...(생략)...
keys = pygame.key.get_pressed() # 현재 눌린 키 상태 확인
self.player_sprites.update(keys) # 스프라이트 업데이트
# 화면을 검정색으로 채우고 스프라이트를 그리기
self.screen.fill((0, 0, 0))
self.player_sprites.draw(self.screen)
방향키에 따라 위와 같이 움직이는 모습을 볼 수 있다.
전체 소스 코드 목록은 아래와 같다.
그런데 현재 소 스코드에 문제가 있다.
상하좌우로 아무곳이나 화면 끝까지 움직여보자.
메인 캐릭터가 화면 밖으로 사라지는 걸 볼 수가 있을 것이다.
다음 포스트에는 지금 말한 문제점을 수정하고 (혹시 본인이 직접 수정이 가능하다면 한번 직접 해 보길 바란다.)
코드 내에 임의의 숫자로 강제로 설정된 하드코딩 영역을 상수처리하도록 변경해 보겠다.
'게임공작소' 카테고리의 다른 글
운석 피하기 게임 개발(6)- 운석 처리(1) (1) | 2024.08.26 |
---|---|
운석 피하기 게임 개발(5)- 배경 넣기(feat. ChatGPT) (0) | 2024.08.25 |
운석 피하기 게임 개발(4)- 전역변수 설정 (0) | 2024.08.23 |
운석 피하기 게임 개발(2)- 기본화면 (feat. ChatGPT) (0) | 2024.08.19 |
운석 피하기 게임 개발(1)- 화면설계 (0) | 2024.08.18 |