반응형
pygame을 통한 벽돌깨기 프로젝트를 만들어보았습니다.
해당 코드의 설명은 아래 코드에 작성해두었습니다.
** 피버 모드
게임 점수가 1000점이 되면 10초동안 공이 3개가 되어 빠른 속도로 진행이되고 10초후 다시 원상태로 돌아옵니다.
완벽한 코드는 아니어도 해당 코드를 통해 pygame 학습에 도움이 되었으면 좋겠습니다.
import sys
import math
import random
import pygame
from pygame.locals import QUIT, KEYDOWN, K_LEFT, K_RIGHT, Rect, KEYUP
import time
class Block:
""" 블록, 공, 패들 오브젝트 """
def __init__(self, col, rect, speed=0):
self.col = col
self.rect = rect
self.speed = speed
self.dir = random.randint(-45, 45) + 270
def move(self):
""" 공을 움직인다 """
self.rect.centerx += math.cos(math.radians(self.dir))\
* self.speed
self.rect.centery -= math.sin(math.radians(self.dir))\
* self.speed
def draw(self):
""" 블록, 공, 패들을 그린다 """
if self.speed == 0:
pygame.draw.rect(SURFACE, self.col, self.rect)
else:
pygame.draw.ellipse(SURFACE, self.col, self.rect)
# 피버 타임 이벤트
def feverTime():
global BALLS
# 공 두개를 추가해주고
for i in range(2):
BALLS.append(Block((200, 242, 0), Rect(300, 400, 20, 20), 10))
# 공의 속도를 15로 맞춘다.
for BALL in BALLS:
BALL.speed = 10
def tick():
""" 프레임별 처리 """
global BALLS, BLOCKS, score, isFeverTime, startTime, endTime
# 키 입력 처리
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key == K_LEFT:
PADDLE.rect.centerx -= 10
elif event.key == K_RIGHT:
PADDLE.rect.centerx += 10
for BALL in BALLS:
if BALL.rect.centery < 1000:
BALL.move()
# 블록과 충돌하면
prevlen = len(BLOCKS)
BLOCKS = [x for x in BLOCKS
if not x.rect.colliderect(BALL.rect)]
if len(BLOCKS) != prevlen:
BALL.dir *= -1
score += 100 # get score + 100
# 점수가 1000점이고, 피버타임이 아니면 피버타임으로 진입한다.
if score == 1000 and isFeverTime == False:
isFeverTime = True
feverTime()
# 10초를 카운트하고 10초 뒤에는 피버타임을 off한다.
elif isFeverTime == True:
if startTime == 0.0:
startTime = time.time()
elif startTime != 0.0:
endTime = time.time()
if endTime - startTime >= 10: # 10초
isFeverTime = False
# 패들과 충돌하면
if PADDLE.rect.colliderect(BALL.rect):
BALL.dir = 90 + (PADDLE.rect.centerx - BALL.rect.centerx) \
/ PADDLE.rect.width * 80
# 벽과 충돌하면
if BALL.rect.centerx < 0 or BALL.rect.centerx > 600:
BALL.dir = 180 - BALL.dir
if BALL.rect.centery < 0:
BALL.dir = -BALL.dir
BALL.speed = 15
pygame.init()
pygame.key.set_repeat(5, 5)
SURFACE = pygame.display.set_mode((600, 800))
FPSCLOCK = pygame.time.Clock()
BLOCKS = []
PADDLE = Block((242, 242, 0), Rect(300, 700, 100, 30))
BALLS = [Block((242, 242, 0), Rect(300, 400, 20, 20), 10)]
isNeedToRestart = False
isFeverTime = False
score = 0
startTime = 0.0
endTime = 0.0
# 초기화
def init():
global SURFACE, FPSCLOCK, BLOCKS, PADDLE, BALLS, isNeedToRestart, isFeverTime, score, startTime, endTime
pygame.init()
pygame.key.set_repeat(5, 5)
SURFACE = pygame.display.set_mode((600, 800))
FPSCLOCK = pygame.time.Clock()
BLOCKS = []
PADDLE = Block((242, 242, 0), Rect(300, 700, 100, 30))
BALLS = [Block((242, 242, 0), Rect(300, 400, 20, 20), 10)]
isNeedToRestart = False
isFeverTime = False
score = 0
startTime = 0.0
endTime = 0.0
def main():
global isNeedToRestart, score, isFeverTime, startTime, endTime
""" 메인 루틴 """
myfont = pygame.font.SysFont(None, 80)
smallfont = pygame.font.SysFont(None, 36)
scorefont = pygame.font.SysFont(None, 25)
mess_clear = myfont.render("Cleared!", True, (255, 255, 0))
mess_over = myfont.render("Game Over!", True, (255, 255, 0))
mess_replay = smallfont.render("replay (press r)", True, (255, 0, 0))
fps = 30
colors = [(255, 0, 0), (255, 165, 0), (242, 242, 0),
(0, 128, 0), (128, 0, 128), (0, 0, 250)]
# 블록을 추가해준다.
for ypos, color in enumerate(colors, start=0):
for xpos in range(0, 5):
BLOCKS.append(Block(color, Rect(xpos * 100 + 60, ypos * 50 + 40, 80, 30)))
while True:
tick()
# 공을 그린다
SURFACE.fill((0, 0, 0))
for BALL in BALLS:
BALL.draw()
PADDLE.draw()
# 블록을 그린다
for block in BLOCKS:
block.draw()
# 블록을 모두 제거하면 성공
if len(BLOCKS) == 0:
SURFACE.blit(mess_clear, (200, 400))
# 공이 패들 밑으로 내려가면 해당 공은 삭제
for BALL in BALLS:
if BALL.rect.centery > 800 and len(BLOCKS) > 0:
BALLS.remove(BALL)
# 피버타임이 끝난 경우
if isFeverTime == False and startTime != 0.0 and endTime != 0.0:
# 공 하나만 제외하고 모두 제거
for BALL in BALLS:
BALLS.remove(BALL)
if(len(BALLS) == 1):
break
startTime = 0.0
endTime = 0.0
# 속도 10으로 원복
for BALL in BALLS:
BALL.speed = 10
# 공이 하나도 없는 경우(끝난 경우)
if len(BALLS) <= 0:
SURFACE.blit(mess_over, (150, 400))
SURFACE.blit(mess_replay, (230, 460))
isNeedToRestart = True
# 스코어 보드
mess_score = scorefont.render("score : " + str(score), True, (255, 255, 255))
SURFACE.blit(mess_score, (10, 10))
pygame.display.update()
FPSCLOCK.tick(fps)
# r키를 누르면 재시작 가능하도록 설정
while isNeedToRestart:
for event in pygame.event.get():
if event.type == KEYDOWN and event.key == pygame.K_r:
isNeedToRestart = False
break
if event.type == QUIT:
pygame.quit()
sys.exit()
break
if isNeedToRestart == False:
init()
main()
break
if __name__ == '__main__':
main()
반응형
'Basic > Python' 카테고리의 다른 글
python priority queue 사용 방법 (heap queue) (0) | 2020.10.11 |
---|---|
Python 다익스트라, BFS, Greedy를 이용한 최단 경로 (4) | 2020.09.08 |
파이썬 파일 입출력을 통한 구구단 만들기 (0) | 2020.08.11 |
Python tuple 여러 사용 방법 (0) | 2020.07.07 |
Python Asyncio를 이용한 비동기 사용 (0) | 2020.07.01 |