pygame 미니게임
파이썬 라이브러리 pygame을 사용해 미니 게임 로직을 구현.
실제 작동까지 진행.
GAME: Annoying Ghost
Annoying Ghost 전체 코드
import pygame
from pygame.rect import *
import random
def restart():
global isGameOver, score
isGameOver = False
score = 0
for i in range(len(ghost)):
ghost_rect[i].y = -1
for i in range(len(missile)):
missile_rect[i].y = -1
def eventProcess():
global running
for event in pygame.event.get(): # 어떤 이벤트가 발생하였는가?
if event.type == pygame.QUIT: # 창이 닫히는 이벤트가 발생하였는가?
running = False # 게임이 진행중이 아님
if event.type == pygame.KEYDOWN: # 키가 눌러졌는지 확인
if event.key == pygame.K_LEFT: # 캐릭터를 왼쪽으로
move.x = -1
if event.key == pygame.K_RIGHT: # 캐릭터를 오른쪽으로
move.x = 1
if event.key == pygame.K_UP: # 캐릭터를 위로
move.y = -1
if event.key == pygame.K_DOWN: # 캐릭터를 아래로
move.y = 1
if event.key == pygame.K_r: # 리스타트
restart()
if event.key == pygame.K_SPACE:
makeMissile()
if event.type == pygame.KEYUP: # 방향키를 떼면 멈춤
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
move.x = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
move.y = 0
def movePlayer():
if not isGameOver:
player_rect.x += move.x
player_rect.y += move.y
if player_rect.x < 0:
player_rect.x = 0
if player_rect.x > screen_width - player_rect.width:
player_rect.x = screen_width - player_rect.width
if player_rect.y < 0:
player_rect.y = 0
if player_rect.y > screen_height - player_rect.height:
player_rect.y = screen_height - player_rect.height
screen.blit(player, player_rect)
def timeDelay500ms():
global time_delay_500ms
if time_delay_500ms > 5:
time_delay_500ms = 0
return True
time_delay_500ms += 1
return False
def makeGhost():
if isGameOver:
return
if timeDelay500ms():
idex = random.randint(0, len(ghost)-1)
if ghost_rect[idex].y == -1:
ghost_rect[idex].x = random.randint(0, screen_width)
ghost_rect[idex].y = 0
def moveGhost():
makeGhost()
for i in range(len(ghost)):
if ghost_rect[i].y == -1:
continue
if not isGameOver:
ghost_rect[i].y += 1
if ghost_rect[i].y > screen_height:
ghost_rect[i].y = 0
screen.blit(ghost[i], ghost_rect[i])
def CheckCollisionMissile():
global score, isGameOver
if isGameOver:
return
for rec in ghost_rect:
if rec.y == -1:
continue
for recM in missile_rect:
if rec.top < recM.bottom \
and recM.top < rec.bottom \
and rec.left < recM.right \
and recM.left < rec.right:
rec.y = -1
recM.y = -1
score += 10
break
def makeMissile():
if isGameOver:
return
for i in range(len(missile)):
if missile_rect[i].y == -1:
missile_rect[i].x = player_rect.x
missile_rect[i].y = player_rect.y
break
def moveMissile():
for i in range(len(missile)):
if missile_rect[i].y == -1:
continue
if not isGameOver:
missile_rect[i].y -= 1
if missile_rect[i].y < 0:
missile_rect[i].y = -1
screen.blit(missile[i], missile_rect[i])
def CheckCollision():
global score, isGameOver
if isGameOver:
return
for rec in ghost_rect:
if rec.y == -1:
continue
if rec.top < player_rect.bottom \
and player_rect.top < rec.bottom \
and rec.left < player_rect.right \
and player_rect.left < rec.right:
print('충돌')
isGameOver = True
break
# score += 1
def blinking():
global time_dealy_4sec, toggle
time_dealy_4sec += 1
if time_dealy_4sec > 40:
time_dealy_4sec = 0
toggle = ~toggle
return toggle
def setText():
mFont = pygame.font.SysFont("arial", 20, True, False)
screen.blit(mFont.render(
f'SCORE {score}', True, 'yellow'), (10, 10, 0, 0))
# print(pygame.font.get_fonts())
if isGameOver and blinking():
mFont = pygame.font.SysFont("arial", 100, True, False)
screen.blit(mFont.render(
'GAME', True, 'white'), (85, 200, 0, 0))
mFont = pygame.font.SysFont("arial", 100, True, False)
screen.blit(mFont.render(
'OVER', True, 'white'), (95, 300, 0, 0))
mFont = pygame.font.SysFont("arial", 20, True, False)
screen.blit(mFont.render(
'Press R Key Restart', True, 'white'), (145, 450, 0, 0))
# 변수 초기화
running = True # 게임이 진행중
screen_width = 480
screen_height = 640
move = Rect(0, 0, 0, 0) # x, y, 가로, 세로
time_delay_500ms = 0
time_dealy_4sec = 0
toggle = False
score = 0
isGameOver = False
# 초기화, 반드시 필요
pygame.init()
pygame.mixer.init()
# 배경음
pygame.mixer.music.load('sound.mp3')
pygame.mixer.music.play(-1)
# 화면 크기 설정
screen = pygame.display.set_mode((screen_width, screen_height))
background = pygame.image.load("background.png")
# 화면 타이틀
pygame.display.set_caption('Annoying Ghost')
# 플레이어
player = pygame.image.load("character.png")
player = pygame.transform.scale(player, (40, 40))
player_rect = player.get_rect()
player_size = player.get_rect().size # 이미지 크기를 구해옴
player_rect.centerx = (screen_width / 2) # 화면 가로의 절반 크기에 해당하는 곳에 위치
player_rect.centery = (screen_height / 2) # 화면 세로 크기 가장 아래에 해당하는 곳에 위치
# 고스트
ghost = [pygame.image.load("ghost.png") for i in range(20)]
ghost_rect = [None for i in range(len(ghost))]
for i in range(len(ghost)):
ghost[i] = pygame.transform.scale(ghost[i], (30, 30))
ghost_rect[i] = ghost[i].get_rect()
ghost_rect[i].y = -1
# 미사일
missile = [pygame.image.load("missile.png") for i in range(30)]
missile_rect = [None for i in range(len(missile))]
for i in range(len(missile)):
missile[i] = pygame.transform.scale(missile[i], (15, 15))
missile_rect[i] = missile[i].get_rect()
missile_rect[i].y = -1
# FPS
clock = pygame.time.Clock()
### 반복 이벤트 ###
while running:
# screen.fill((0, 0, 255)) # 배경 그리기, RGB
screen.blit(background, (0, 0)) # 배경 그리기, 이미지
eventProcess() # 이벤트 처리
movePlayer() # 플레이어 이동
moveGhost() # 적 생성 및 이동
moveMissile() # 미사일 생성 및 이동
CheckCollisionMissile()
CheckCollision() # 충돌 확인
setText() # 텍스트 업데이트
pygame.display.flip() # 화면 갱신 # 게임 화면을 다시 그리기
clock.tick(100) # ms 주기로 그리기
### 반복 이벤트###
이번 프로젝트로 얻게된 것:
아쉬운 점:
고생 많으셨습니다 :)
이제 진짜 개발을 시작하셨네요 ㅎㅎ
뭔가 색감이 귀엽습니다 ㅋㅋㅋ
우선 해당 게임의 기능을 다시 한번 정리 하시면서 한 번쯤 함수 혹은 클래스로 분류해보시는 것을 권장드립니다!
그리고 에러 코드는 완벽하게 잡을 수 없습니다. 그럼 이를 어떻게 막을 수 있을지 고민해보세요.
(예외처리 검색)
마지막으로 게임을 만들게 되면 조건문을 꽤 많이 정의하게 되며
자연스럽게 코드가 약간 지저분해집니다.
이럴때 파이썬에서는 어떻게 코드를 깔끔하게 정리할 수 있는지 검색해보세요 :)
(switch 문법)
이렇게 공부를 열심히 하신 만큼 다음 프로젝트도 잘 해내실 수 있을것 입니다.
더불이 이 기세를 몰아서 알고리즘도 한번..? ㅎㅎ