×
Crocus
공부한 내용을 정리하는 블로그로 시작한
Crocus는 2014년 1월 14일 부터 시작하여
현재 월 6만명, 총 1,855,855명의 방문자 수를 기록하고 있습니다.
Donation
이제 많은 사용자들이 이용하는 만큼
더 다양한 서비스 개발/제공을 위해 후원금을 모금하고자 합니다.
후원을 해주시는 분들은 Donators 명단에 성명, 후원금을 기입해드리며
Crocus 블로그가 아닌 다른 곳에 정리해둔 저만의 내용을 공유해 드리고자 합니다.
Account
예금주 : 고관우
신한은행 : 110-334-866541
카카오뱅크 : 3333-01-7888060

👉 후원 페이지 바로가기 Donators
익명 : 5000원(Crocus응원합니다.)
busyhuman: 5000원(유용한 지식 감사합니다.)
익명 : 5000원(알고리즘 학습러)
728x90
반응형

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()

 

728x90
반응형