🐸

006 동족 구출하기 및 점수 구현

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. 구현 방식(정리)

  1. 개리동족이미지(구출 전과 구출 후)와 포탈이미지를 로드하고 그에 따른 스프라이트를 만듭니다.
  1. 동료와 포탈이 번가라가며 움직이도록 만듭니다.
  1. 처음에 동료를 만나면 개리 뒤에 이동하도록 하고 포탈이 움직일 수 있도록 합니다.
  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. 실행 화면

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