1. 실행 코드
import pygame as pg import random # 이미지 초기화 def 스프라이트_생성(이미지): 스프라이트 = pg.sprite.Sprite() 스프라이트.image = 이미지 스프라이트.rect = 스프라이트.image.get_rect() return 스프라이트 pg.init() # 게임 기본 설정 실행여부 = True 화면가로길이, 화면세로길이 = 800, 450 화면 = pg.display.set_mode([화면가로길이, 화면세로길이]) pg.display.set_caption('동족을 노역장에서 구출하라!') 배경이미지 = pg.image.load('img/배경.png') 배경이미지 = pg.transform.scale(배경이미지, (화면가로길이, 화면세로길이)) 개리점프이미지 = pg.image.load('img/개리-뛰는-모습5(점프).png') 개리점프이미지 = pg.transform.scale(개리점프이미지, (100, 100)) 개리착지이미지 = pg.image.load('img/개리-뛰는-모습6(착지).png') 개리착지이미지 = pg.transform.scale(개리착지이미지, (100, 100)) 개리뛰기이미지리스트 = [pg.image.load(f'img/개리-뛰는-모습{인덱스}.png') for 인덱스 in range(1, 5)] for 인덱스 in range(len(개리뛰기이미지리스트)): 개리뛰기이미지리스트[인덱스] = pg.transform.scale(개리뛰기이미지리스트[인덱스], (100, 100)) 개리스프라이트 = 스프라이트_생성(개리뛰기이미지리스트[0]) 돌이미지 = pg.image.load('img/돌.png') 돌이미지 = pg.transform.scale(돌이미지, (100, 100)) 개리동료이미지 = pg.image.load('img/동료_구출-전.png') 개리동료이미지 = pg.transform.scale(개리동료이미지, (100, 100)) 개리동료구출이미지 = pg.image.load('img/동료_구출-후.png') 개리동료구출이미지 = pg.transform.scale(개리동료구출이미지, (100, 100)) 개리동료스프라이트 = 스프라이트_생성(개리동료이미지) 포탈이미지 = pg.image.load('img/포탈.png') 포탈이미지 = pg.transform.scale(포탈이미지, (100, 100)) 포탈스프라이트 = 스프라이트_생성(포탈이미지) # 게임 요소 초기화 게임여부 = True 개리시작높이 = 255 점수 = 0 개리뛰기상태 = 0 개리뛰는흐름 = 1 개리동작업데이트시간 = 0 점프기본속도 = 0.1 점프속도 = 점프기본속도 점프상태 = False 개리위치 = [70, 개리시작높이] 요소들속도 = 300 돌멩이생성시간 = 1 돌멩이시작높이 = 280 돌멩이위치리스트 = [[500, 돌멩이시작높이]] 돌멩이스프라이트리스트 = [스프라이트_생성(돌이미지) for _ in 돌멩이위치리스트] 개리동료구출상태 = False 개리동료최초위치 = 900 개리동료위치 = [개리동료최초위치, 개리시작높이] 포탈최초위치 = 900 포탈위치 = [포탈최초위치, 개리시작높이] 시계 = pg.time.Clock() while 실행여부: if 게임여부: 화면.blit(배경이미지, (0, 0)) # 게임 시간 계산 경과시간 = 시계.tick(60) / 1000 개리스프라이트.rect.x, 개리스프라이트.rect.y = 개리위치[0], 개리위치[1] 화면.blit(개리스프라이트.image, 개리스프라이트.rect) # 개리 동족 및 포탈 그리기, 개리 동족 구출하기 개리동료스프라이트.rect.x, 개리동료스프라이트.rect.y = 개리동료위치[0], 개리동료위치[1] 화면.blit(개리동료스프라이트.image, 개리동료스프라이트.rect) 포탈스프라이트.rect.x, 포탈스프라이트.rect.y = 포탈위치[0], 포탈위치[1] 화면.blit(포탈스프라이트.image, 포탈스프라이트.rect) if not 개리동료구출상태: 개리동료스프라이트.image = 개리동료이미지 if pg.sprite.collide_mask(개리스프라이트, 개리동료스프라이트): 개리동료구출상태 = True 개리동료위치[0] = 15 개리동료위치[1] = 개리위치[1] 개리동료위치[0] -= 요소들속도 * 경과시간 if 개리동료위치[0] < -50: 개리동료위치[0] = 개리동료최초위치 else: 개리동료스프라이트.image = 개리동료구출이미지 if pg.sprite.collide_mask(개리동료스프라이트, 포탈스프라이트): 개리동료위치[0] = 개리동료최초위치 개리동료위치[1] = 개리시작높이 점수 += 1 포탈위치[0] = 포탈최초위치 개리동료구출상태 = False print(f"점수 = {점수}") # 점수 확인용 포탈위치[0] -= 요소들속도 * 경과시간 if 포탈위치[0] < -50: 포탈위치[0] = 포탈최초위치 for 돌멩이위치, 돌멩이스프라이트 in zip(돌멩이위치리스트, 돌멩이스프라이트리스트): 돌멩이스프라이트.rect.x, 돌멩이스프라이트.rect.y = 돌멩이위치[0], 돌멩이위치[1] 화면.blit(돌멩이스프라이트.image, 돌멩이스프라이트.rect) if pg.sprite.collide_mask(개리스프라이트, 돌멩이스프라이트) != None: 게임여부 = False 돌멩이위치[0] -= 요소들속도 * 경과시간 if 돌멩이위치[0] < -100: 돌멩이스프라이트리스트.remove(돌멩이스프라이트) 돌멩이위치리스트.remove(돌멩이위치) # 개리 점프 if 점프상태: 개리스프라이트.image = 점프속도 > 0 and 개리점프이미지 or 개리착지이미지 개리위치[1] -= 점프속도 * 경과시간 * 1000 점프속도 -= 점프기본속도 * 경과시간 * 2 if 개리동료구출상태: 개리동료위치[1] = 개리위치[1] if 개리위치[1] >= 개리시작높이: 개리위치[1] = 개리시작높이 점프상태 = False 점프속도 = 점프기본속도 else: 개리동작업데이트시간 += 경과시간 if 개리동작업데이트시간 > 0.2: 개리동작업데이트시간 = 0 개리스프라이트.image = 개리뛰기이미지리스트[개리뛰기상태] 개리뛰기상태 += 개리뛰는흐름 if 개리뛰기상태 == len(개리뛰기이미지리스트) - 1 or 개리뛰기상태 == 0: 개리뛰는흐름 *= -1 돌멩이생성시간 -= 경과시간 if 돌멩이생성시간 <= 0: 돌멩이스프라이트리스트.append(스프라이트_생성(돌이미지)) 돌멩이위치리스트.append([900, 돌멩이시작높이]) 돌멩이생성시간 = random.random() * 2 + 1 for 이벤트 in pg.event.get(): if 이벤트.type == pg.QUIT: 실행여부 = False elif 이벤트.type == pg.KEYDOWN: if 게임여부 and 이벤트.key == pg.K_SPACE and not 점프상태: 점프상태 = True pg.display.update() pg.display.quit()
2. 상세 설명
2-1. 구현 방식(정리)
- 개리동족이미지(구출 전과 구출 후)와 포탈이미지를 로드하고 그에 따른 스프라이트를 만듭니다.
- 동료와 포탈이 번가라가며 움직이도록 만듭니다.
- 처음에 동료를 만나면 개리 뒤에 이동하도록 하고 포탈이 움직일 수 있도록 합니다.
- 포탈과 만나면 개리동료를 원래 위치로 보내고 점수를 증가시킵니다.(print로 체크.)
2-2. 구현
개리동료이미지 = pg.image.load('img/동료_구출-전.png') 개리동료이미지 = pg.transform.scale(개리동료이미지, (100, 100)) 개리동료구출이미지 = pg.image.load('img/동료_구출-후.png') 개리동료구출이미지 = pg.transform.scale(개리동료구출이미지, (100, 100)) 개리동료스프라이트 = 스프라이트_생성(개리동료이미지) 포탈이미지 = pg.image.load('img/포탈.png') 포탈이미지 = pg.transform.scale(포탈이미지, (100, 100)) 포탈스프라이트 = 스프라이트_생성(포탈이미지) # ... 중략 .... 점수 = 0
- 개리동료(구출 전과 구출 후) 및 포탈이미지를 로드하고 스프라이트도 함께 만듭니다.
- 점수 : 개리동료가 구출되고 포탈에 들어가 탈출했을 때 점수를 올릴 수 있도록 만듭니다.
개리동료구출상태 = False 개리동료최초위치 = 900 개리동료위치 = [개리동료최초위치, 개리시작높이] 포탈최초위치 = 900 포탈위치 = [포탈최초위치, 개리시작높이]
- 개리동료구출상태 : 개리동료의 이미지를 상태를 변경하기 위한 변수입니다.
- 개리동료최초위치 : 구출된 후 다음 동료가 오는 것처럼 보이기 위해 다시 원래대로 되돌릴 x좌표입니다.
- 개리동료위치 : 개리위치나 돌멩이위치와 같이 개리동료위치도 소수 연산을 위하여 따로 만듭니다.
- 포탈최초위치 : 개리동료가 탈출하고 원래 위치로 되돌리기 위한 x좌표입니다.
- 포탈위치 : 개리동료위치와 같이 위치의 소수 연산을 위하여 따로 만듭니다.
개리동료스프라이트.rect.x, 개리동료스프라이트.rect.y = 개리동료위치[0], 개리동료위치[1] 화면.blit(개리동료스프라이트.image, 개리동료스프라이트.rect) 포탈스프라이트.rect.x, 포탈스프라이트.rect.y = 포탈위치[0], 포탈위치[1] 화면.blit(포탈스프라이트.image, 포탈스프라이트.rect) if not 개리동료구출상태: 개리동료스프라이트.image = 개리동료이미지 if pg.sprite.collide_mask(개리스프라이트, 개리동료스프라이트): 개리동료구출상태 = True 개리동료위치[0] = 15 개리동료위치[1] = 개리위치[1] 개리동료위치[0] -= 요소들속도 * 경과시간 if 개리동료위치[0] < -50: 개리동료위치[0] = 개리동료최초위치 else: 개리동료스프라이트.image = 개리동료구출이미지 if pg.sprite.collide_mask(개리동료스프라이트, 포탈스프라이트): 개리동료위치[0] = 개리동료최초위치 개리동료위치[1] = 개리시작높이 점수 += 1 포탈위치[0] = 포탈최초위치 개리동료구출상태 = False print(f"점수 = {점수}") # 점수 확인용 포탈위치[0] -= 요소들속도 * 경과시간 if 포탈위치[0] < -50: 포탈위치[0] = 포탈최초위치
- 개리동료와 포탈을 각 위치변수에 따라 업데이트합니다.
- 개리동료구출상태
- 구출 전
- 구출 전 이미지로 바꿔줍니다.
- 개리동료와 개리가 만나야 하므로 개리동료와 충돌체크합니다.
- 구출한 뒤에는 개리동료를 개리뒤에 위치시키고 y좌표를 통일합니다.
- 개리동료가 혹시나 구출되지 못하고 화면 밖으로 나가면 원래위치로 되돌립니다.(점프 높이 상 실제 실행될 일은 없으나 점프 시간과 높이를 조정함에 따라 달라질 수 있어 제거하지 않았습니다.)
- 구출 후
- 구출 후 이미지로 바꿔줍니다.
- 개리동료가 포탈과 만나야 탈출할 수 있으므로 포탈과 충돌체크합니다.
- 포탈과 만나면 개리동료와 포탈를 원래 위치로 되돌리고 점수를 올립니다.
- 개리동료가 혹시나 포탈에 들어가지 못하고 화면 밖으로 나가면 원래위치로 되돌립니다.(구출 전 코드의 개리동료 코드와 마찬가지로 이 부분은 현재는 실행되지 않습니다. 그러나 포탈 높이를 조정하는 등의 수정을 하면 필요하므로 제거하지 않았습니다.)
if 개리동료구출상태: 개리동료위치[1] = 개리위치[1]
- 개리동료가 구출되서 포탈이 들어가기 전까지는 개리와 높이를 똑같이 맞춰줍니다.
3. 실행 화면



마지막 장면에서 포탈과 돌멩이가 같이 붙어있어 오류가 발생합니다. 다음 챕터에서 이를 해결하기 위한 코드를 작성해보겠습니다.