🍳

005 게임 완성하기

1. 실행 코드

import pygame as pg import random def 스프라이트생성(이미지, 위치, 상태=None, 시간=None): 스프라이트 = pg.sprite.Sprite() 스프라이트.image = 이미지 스프라이트.rect = 스프라이트.image.get_rect() 스프라이트.rect.x, 스프라이트.rect.y = 위치[0], 위치[1] if 상태 != None: 스프라이트.상태 = 상태 if 시간 != None: 스프라이트.시간 = 시간 return 스프라이트 pg.init() 실행여부 = True 화면가로길이, 화면세로길이 = 874, 987 화면 = pg.display.set_mode([화면가로길이, 화면세로길이]) pg.display.set_caption('부족들의 마음을 요리로 사로잡아라!') #색 지정 흰색 = (255, 255, 255) 검은색 = (0, 0, 0) #글꼴 설정 글꼴 = pg.font.SysFont('malgungothic', 25) #게임 요소 초기화 경과시간 = 0 점수 = 0 시계 = pg.time.Clock() 현재챕터 = 1 최종챕터 = 10 자바독상태 = "기본자세" 자바독인덱스 = 0 자바독움직임흐름 = 1 자바독요리가능여부 = True 현재요리 = "사료" 현재요리상태 = "전" 요리움직임여부 = False 이미지마우스위치 = [0, 0] 요리초기위치 = [424, 248] 요리위치 = [요리초기위치[0] - 53, 요리초기위치[1] - 30] 손님가로숫자, 손님세로숫자 = 4, 2 손님생각최대시간 = 5 손님대기최대시간 = 10 요리상태리스트 = ['전', '후'] 요리리스트 = ['사료', '뼈다귀', '물'] 배경이미지 = pg.image.load('img/배경.png') 배경이미지 = pg.transform.scale(배경이미지, (화면가로길이, 화면세로길이)) 챕터바이미지크기 = (358, 61) 챕터바이미지 = pg.image.load('img/챕터바.png') 챕터바이미지 = pg.transform.scale(챕터바이미지, 챕터바이미지크기) 자바독이미지크기 = (238, 238) 자바독이미지딕셔너리 = {} 자바독이미지딕셔너리['기본자세'] = pg.image.load('img/자바독_기본자세.png') 자바독이미지딕셔너리['기본자세'] = pg.transform.scale(자바독이미지딕셔너리['기본자세'], 자바독이미지크기) for 요리 in 요리리스트: 자바독이미지딕셔너리[요리] = [] for 인덱스 in range(3): 자바독요리중이미지 = pg.image.load(f'img/자바독_{요리}_요리중_{인덱스+1}.png') 자바독요리중이미지 = pg.transform.scale(자바독요리중이미지, 자바독이미지크기) 자바독이미지딕셔너리[요리].append(자바독요리중이미지) 주방테이블이미지크기 = (668, 173) 주방테이블이미지 = pg.image.load('img/주방-테이블.png') 주방테이블이미지 = pg.transform.scale(주방테이블이미지, 주방테이블이미지크기) 요리이미지크기딕셔너리 = {'사료':(106, 61), '뼈다귀':(106, 61), '물':(106, 61)} 요리이미지딕셔너리 = {} for 요리상태 in 요리상태리스트: 요리이미지딕셔너리[요리상태] = {} for 요리 in 요리리스트: 요리이미지딕셔너리[요리상태][요리] = pg.image.load(f'img/{요리}_요리{요리상태}.png') 요리이미지딕셔너리[요리상태][요리] = pg.transform.scale(요리이미지딕셔너리[요리상태][요리], 요리이미지크기딕셔너리[요리]) 요리스프라이트 = 스프라이트생성(요리이미지딕셔너리['전'][현재요리], 요리위치) 동족이미지크기 = (196, 314) 동족음식생각중이미지 = pg.image.load('img/동족_음식-생각-중.png') 동족음식생각중이미지 = pg.transform.scale(동족음식생각중이미지, 동족이미지크기) 동족원하는음식을받음이미지 = pg.image.load('img/동족_원하는-음식을-받음.png') 동족원하는음식을받음이미지 = pg.transform.scale(동족원하는음식을받음이미지, 동족이미지크기) 동족원하지않는음식을받음이미지 = pg.image.load('img/동족_원하지-않는-음식을-받음(화남).png') 동족원하지않는음식을받음이미지 = pg.transform.scale(동족원하지않는음식을받음이미지, 동족이미지크기) 동족이미지리스트 = [동족음식생각중이미지, 동족원하는음식을받음이미지, 동족원하지않는음식을받음이미지] 동족스프라이트리스트 = [스프라이트생성(동족이미지리스트[0], (50+동족이미지크기[0]*j, 350+동족이미지크기[1]*i), 0, random.random()*(손님생각최대시간-1)) for i in range(손님세로숫자) for j in range(손님가로숫자)] 이미지움직임최대시간 = 0.2 이미지움직임시간 = 0 움직임최대횟수 = 3 움직임횟수 = 0 while 실행여부: if 현재챕터 <= 최종챕터: 화면.blit(배경이미지, (0, 0)) 흐른시간 = 시계.tick(60) / 1000 경과시간 += 흐른시간 시간문자열 = '%02d:%02d'%(경과시간/60, 경과시간%60) 경과시간글자 = 글꼴.render(시간문자열, True, 검은색) 화면.blit(챕터바이미지, ((화면가로길이 - 챕터바이미지크기[0]) // 2, 7)) 화면.blit(경과시간글자, (20, 20)) 챕터문자열 = f'{현재챕터}챕터' 챕터글자 = 글꼴.render(챕터문자열, True, 흰색) 화면.blit(챕터글자, ((화면가로길이 - 14 * len(챕터문자열)) // 2 - 10, 20)) 점수문자열 = f'{점수}점' 점수글자 = 글꼴.render(점수문자열, True, 검은색) 화면.blit(점수글자, ((화면가로길이 - 14 * len(점수문자열)) - 30, 20)) if 자바독상태 == '기본자세': 화면.blit(자바독이미지딕셔너리[자바독상태], (321, 85)) else: 화면.blit(자바독이미지딕셔너리[자바독상태][자바독인덱스], (321, 85)) 화면.blit(주방테이블이미지, (100, 192)) for 동족스프라이트 in 동족스프라이트리스트: 화면.blit(동족스프라이트.image, 동족스프라이트.rect) 요청요리리스트 = {} for 인덱스, 요리 in enumerate(요리리스트): 요청요리리스트[요리] = 화면.blit(요리이미지딕셔너리['후'][요리], (460 + 90 * 인덱스, 280 - 요리이미지딕셔너리["후"][요리].get_height())) for 동족스프라이트 in 동족스프라이트리스트: 동족스프라이트.시간 -= 흐른시간 if 동족스프라이트.시간 <= 0: if 동족스프라이트.상태 == 0: #생각하는 중 동족스프라이트.상태 = 1 동족스프라이트.시간 = 손님대기최대시간 동족스프라이트.생각음식 = random.choice(요리리스트) elif 동족스프라이트.상태 == 1: #음식을 주문하고 대기하는 중 동족스프라이트.image = 동족이미지리스트[2] 동족스프라이트.상태 = 2 동족스프라이트.시간 = 2 elif 동족스프라이트.상태 == 2: #주문한 음식 동족스프라이트.상태 = 0 동족스프라이트.시간 = 1 + random.random() * (손님생각최대시간-1) 동족스프라이트.image = 동족이미지리스트[0] 화면.blit(동족스프라이트.image, 동족스프라이트.rect) if 동족스프라이트.상태 == 1: 음식크기 = 요리이미지크기딕셔너리[동족스프라이트.생각음식] 음식위치 = [동족스프라이트.rect.x + 100 - (음식크기[0] // 2), 동족스프라이트.rect.y + 60 - (음식크기[1] // 2)] 화면.blit(요리이미지딕셔너리["후"][동족스프라이트.생각음식], 음식위치) 요리스프라이트.image = 요리이미지딕셔너리[현재요리상태][현재요리] if 자바독요리가능여부: 요리위치 = [요리초기위치[0] - 요리스프라이트.image.get_width() // 2, 요리초기위치[1] - 요리스프라이트.image.get_height() // 2 ] 요리스프라이트.rect.x, 요리스프라이트.rect.y = 요리위치[0], 요리위치[1] 진행중인요리 = 화면.blit(요리스프라이트.image, 요리스프라이트.rect) if 요리움직임여부: 마우스위치 = pg.mouse.get_pos() 요리위치 = [마우스위치[0] + 이미지마우스위치[0], 마우스위치[1] + 이미지마우스위치[1]] else: 손님리스트 = [] for 인덱스 in range(len(동족스프라이트리스트)): 동족스프라이트 = 동족스프라이트리스트[인덱스] if pg.sprite.collide_mask(동족스프라이트, 요리스프라이트): 손님리스트.append(동족스프라이트) if len(손님리스트) == 1 and 손님리스트[0].상태 == 1: if 현재요리 == 손님리스트[0].생각음식 and 현재요리상태 == '후': 손님리스트[0].image = 동족이미지리스트[1] 점수 += 1 현재챕터 = 점수 // 2 + 1 else: 손님리스트[0].image = 동족이미지리스트[2] 현재요리상태 = '전' 손님리스트[0].상태 = 2 손님리스트[0].시간 = 2 자바독요리가능여부 = True else: 화면.fill(흰색) 시간 = 글꼴.render(f'경과시간은 {경과시간//60}분 {경과시간%60}초 입니다', True, (0, 0, 0)) 화면.blit(시간, (화면가로길이 / 2 - 230, 화면세로길이 / 2 - 80)) pg.display.update() for 이벤트 in pg.event.get(): if 이벤트.type == pg.QUIT: 실행여부 = False elif 이벤트.type == pg.MOUSEBUTTONDOWN: 클릭위치 = pg.mouse.get_pos() if 진행중인요리.collidepoint(클릭위치): 요리움직임여부 = True 자바독요리가능여부 = False 이미지마우스위치 = [요리위치[0] - 클릭위치[0], 요리위치[1] - 클릭위치[1]] for 요리 in 요리리스트: if 요청요리리스트[요리].collidepoint(클릭위치): 현재요리 = 요리 현재요리상태 = '전' 자바독요리가능여부 = True elif 이벤트.type == pg.MOUSEBUTTONUP: 요리움직임여부 = False keys = pg.key.get_pressed() # print(keys) if keys[pg.K_SPACE] and 자바독요리가능여부: if 자바독상태 == "기본자세": 자바독상태 = 현재요리 else: 이미지움직임시간 += 흐른시간 if 이미지움직임시간 >= 이미지움직임최대시간: 이미지움직임시간 = 0 자바독인덱스 += 자바독움직임흐름 if 자바독인덱스 == 0 or 자바독인덱스 == len(자바독이미지딕셔너리[자바독상태]) - 1: 자바독움직임흐름 *= -1 움직임횟수 += 1 if 움직임횟수 >= 움직임최대횟수: 현재요리상태 = '후' else: 이미지움직임시간 = 0 자바독상태 = "기본자세" 자바독인덱스 = 0 자바독움직임흐름 = 1 움직임횟수 = 0 pg.display.quit()
 

2. 상세 내용

if 요리움직임여부: 마우스위치 = pg.mouse.get_pos() 요리위치 = [마우스위치[0] + 이미지마우스위치[0], 마우스위치[1] + 이미지마우스위치[1]] else: 손님리스트 = [] for 인덱스 in range(len(동족스프라이트리스트)): 동족스프라이트 = 동족스프라이트리스트[인덱스] if pg.sprite.collide_mask(동족스프라이트, 요리스프라이트): 손님리스트.append(동족스프라이트) if len(손님리스트) == 1 and 손님리스트[0].상태 == 1: if 현재요리 == 손님리스트[0].생각음식 and 현재요리상태 == '후': 손님리스트[0].image = 동족이미지리스트[1] 점수 += 1 현재챕터 = 점수 // 2 + 1 else: 손님리스트[0].image = 동족이미지리스트[2] 현재요리상태 = '전' 손님리스트[0].상태 = 2 손님리스트[0].시간 = 2 자바독요리가능여부 = True
  • 위에 부분은 003 강의의 드래그앤드롭을 참고해주세요
  • 요리가 움직이지 않으면 요리가 손님에게 제공되는지 확인합니다.
    • collide_mask를 이용해 닿은 손님들을 검사합니다.
    • 책상의 거리가 좁기 때문에 2명도 닿을 수 있습니다.
    • 따라서 닿은 사람이 1명이 넘으면 누구한테 줄 지 모르므로 생략합니다.
    • 닿은 사람이 한명이면 그 사람의 상태를 검사하고 요리와 요리상태에 따라 손님의 상태를 표시합니다.
    • 손님에게 요리 전달이 완료되면 손님에 상태를 초기화하고 요리 위치도 초기화합니다. 이때 요리를 다시할 수 있도록 요리가능여부도 초기화합니다.
 
화면.fill(흰색) 시간 = 글꼴.render(f'경과시간은 {경과시간//60}분 {경과시간%60}초 입니다', True, (0, 0, 0)) 화면.blit(시간, (화면가로길이 / 2 - 230, 화면세로길이 / 2 - 80))
  • 챕터가 전부 진행되어 게임이 끝난 후 화면입니다.
  • 강의에서는 흰 화면에 걸린 시간을 표시하는 방법으로 간단하게 하였지만 원하는 방식으로 출력하시면 됩니다.
 

3. 실행 결과

notion imagenotion image