티스토리 뷰
추가 기능 구현

프롬프트 (step05.py에 이어서 작성)
40개의 벽돌 중 랜덤하게 4개의 벽돌을 보너스 벽돌로 지정하여라.
보너스 벽돌은 일반 벽돌과 다른 색으로 표시하여라.
일반 벽돌은 10점, 보너스 벽돌은 20점을 주도록 수정하여라.
단계별 핵심 설명
1. 전역변수
이번 실습에서는 보너스 벽돌을 만들기 위하여 random 라이브러리를 추가하였다.
import random
그리고 보너스 벽돌과 점수 정보를 전역변수로 추가하였다.
BONUS_BRICK_COUNT = 4
NORMAL_SCORE = 10
BONUS_SCORE = 20
bonus_bricks = []
- BONUS_BRICK_COUNT는 보너스 벽돌의 개수이다.
- NORMAL_SCORE는 일반 벽돌 점수이다
- BONUS_SCORE는 보너스 벽돌 점수이다.
- bonus_bricks는 랜덤하게 선택된 보너스 벽돌을 저장하는 리스트이다.
보너스 벽돌을 다른 색으로 표시하기 위하여 RED 색상도 추가하였다.
RED = (255, 0, 0)
2. 초기화
벽돌 40개를 모두 만든 뒤, 그중에서 랜덤하게 4개를 선택한다.
bonus_bricks = random.sample(bricks, BONUS_BRICK_COUNT)
- random.sample()은 리스트 안에서 중복 없이 원하는 개수만큼 뽑을 때 사용한다.
- 여기서는 bricks 리스트 안에 들어 있는 40개의 벽돌 중에서 4개를 랜덤하게 선택하여 bonus_bricks에 저장한다.
- 즉, 실행할 때마다 보너스 벽돌의 위치가 달라진다.
3. 입력
입력 단계는 기존 STEP05와 거의 같다. 이번 실습에서는 보너스 벽돌을 만드는 것이 목적이므로 입력 처리에는 큰 변화가 없다.
기존처럼 "ready" 상태에서 Space Bar를 누르면 게임이 시작된다.
if game_state == "ready":
if event.key == pygame.K_SPACE:
game_state = "play"
패들 이동도 기존처럼 "play" 상태에서만 가능하다.
4. 업데이트
업데이트 단계에서 가장 중요한 변화는 벽돌과 충돌했을 때의 점수 처리이다. 먼저 공이 충돌한 벽돌이 보너스 벽돌인지 확인한다.
is_bonus = brick in bonus_bricks
- 충돌한 벽돌이 bonus_bricks 안에 있으면 보너스 벽돌이다.
- 보너스 벽돌이면 20점을 더한다.
if is_bonus:
bonus_bricks.remove(brick)
score += BONUS_SCORE
- 일반 벽돌이면 10점을 더한다.
else:
score += NORMAL_SCORE
- 따라서 점수 규칙은 다음과 같다.
일반 벽돌 → 10점
보너스 벽돌 → 20점
5. 출력
출력 단계에서는 벽돌을 그릴 때 보너스 벽돌인지 확인한다.
for brick in bricks:
if brick in bonus_bricks:
pygame.draw.rect(screen, RED, brick)
else:
pygame.draw.rect(screen, WHITE, brick)
- 보너스 벽돌이면 빨간색으로 출력한다.
pygame.draw.rect(screen, RED, brick)
- 일반 벽돌이면 기존처럼 흰색으로 출력한다.
pygame.draw.rect(screen, WHITE, brick)
- 따라서 화면에는 흰색 벽돌 36개와 빨간색 보너스 벽돌 4개가 표시된다.
6. 실행
실행 단계는 기존 STEP05와 같다.
다만 게임을 실행할 때마다 init() 함수 안에서 보너스 벽돌을 새로 랜덤 선택하므로, 매번 다른 위치의 벽돌 4개가 보너스 벽돌이 된다.
전체코드 (step06.py)
import pygame
import sys
import random # ADDED 랜덤 보너스 벽돌 선택을 위해 추가
# 전역 변수
WIDTH, HEIGHT = 600, 800
screen = None
clock = None
running = True
# 게임 상태
game_state = "ready" # ready, play, game_over, clear
# 종료 메시지
end_message = ""
# 색상
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0) # ADDED 보너스 벽돌 색상
# 글꼴 정보
font = None
# 공 정보
BALL_RADIUS = 10
BALL_SPEED_X = 4
BALL_SPEED_Y = -4
ball_pos = None
ball_vel = None
# 패들 정보
PADDLE_WIDTH = 100
PADDLE_HEIGHT = 15
PADDLE_SPEED = 7
paddle_rect = None
paddle_dx = 0
# 벽돌 정보
BRICK_ROWS = 5
BRICK_COLS = 8
BRICK_WIDTH = 60
BRICK_HEIGHT = 20
BRICK_GAP = 10
bricks = []
# ADDED 보너스 벽돌 정보
BONUS_BRICK_COUNT = 4
NORMAL_SCORE = 10
BONUS_SCORE = 20
bonus_bricks = []
# 게임 정보
score = 0
life = 3
block_count = 0
# 1. 게임 초기화
def init():
global screen, clock
global font
global ball_pos, ball_vel, paddle_rect, bricks
global score, life, block_count
global game_state, end_message
global bonus_bricks # ADDED
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("벽돌깨기 5단계 - 보너스 벽돌")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 30)
# 게임 상태 초기화
game_state = "ready"
end_message = ""
# 게임 정보 초기화
score = 0
life = 3
block_count = BRICK_ROWS * BRICK_COLS
# 공 초기 위치와 속도
ball_pos = [WIDTH // 2, HEIGHT // 2]
ball_vel = [BALL_SPEED_X, BALL_SPEED_Y]
# 패들 초기 위치
paddle_x = WIDTH // 2 - PADDLE_WIDTH // 2
paddle_y = HEIGHT - 50
paddle_rect = pygame.Rect(
paddle_x,
paddle_y,
PADDLE_WIDTH,
PADDLE_HEIGHT
)
# 벽돌 생성
bricks = []
total_brick_width = BRICK_COLS * BRICK_WIDTH + (BRICK_COLS - 1) * BRICK_GAP
start_x = WIDTH // 2 - total_brick_width // 2
start_y = 80
for row in range(BRICK_ROWS):
for col in range(BRICK_COLS):
brick_x = start_x + col * (BRICK_WIDTH + BRICK_GAP)
brick_y = start_y + row * (BRICK_HEIGHT + BRICK_GAP)
brick = pygame.Rect(
brick_x,
brick_y,
BRICK_WIDTH,
BRICK_HEIGHT
)
bricks.append(brick)
# ADDED 전체 벽돌 중 랜덤하게 4개를 보너스 벽돌로 선택
bonus_bricks = random.sample(bricks, BONUS_BRICK_COUNT)
# 2. 입력 처리
def handle_input():
global running
global paddle_dx
global game_state
paddle_dx = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# ready 상태에서 SPACE BAR를 누르면 게임 시작
if event.type == pygame.KEYDOWN:
if game_state == "ready":
if event.key == pygame.K_SPACE:
game_state = "play"
# 게임 종료 상태에서 아무 키나 누르면 종료
elif game_state == "game_over" or game_state == "clear":
running = False
# play 상태에서만 패들 이동
if game_state == "play":
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
paddle_dx = -PADDLE_SPEED
if keys[pygame.K_RIGHT]:
paddle_dx = PADDLE_SPEED
# 3. 게임 업데이트
def update_game():
global ball_pos, ball_vel, bricks
global score, life, block_count
global game_state, end_message
global bonus_bricks # ADDED
# play 상태가 아니면 게임을 업데이트하지 않음
if game_state != "play":
return
# 패들 위치 업데이트
paddle_rect.x += paddle_dx
# 패들이 화면 밖으로 나가지 않도록 제한
if paddle_rect.left < 0:
paddle_rect.left = 0
if paddle_rect.right > WIDTH:
paddle_rect.right = WIDTH
# 공 위치 업데이트
ball_pos[0] += ball_vel[0]
ball_pos[1] += ball_vel[1]
# 공을 충돌 검사용 사각형으로 변환
ball_rect = pygame.Rect(
ball_pos[0] - BALL_RADIUS,
ball_pos[1] - BALL_RADIUS,
BALL_RADIUS * 2,
BALL_RADIUS * 2
)
# 왼쪽 벽 충돌
if ball_pos[0] - BALL_RADIUS <= 0:
ball_vel[0] = abs(ball_vel[0])
# 오른쪽 벽 충돌
if ball_pos[0] + BALL_RADIUS >= WIDTH:
ball_vel[0] = -abs(ball_vel[0])
# 위쪽 벽 충돌
if ball_pos[1] - BALL_RADIUS <= 0:
ball_vel[1] = abs(ball_vel[1])
# 패들과 충돌
if ball_rect.colliderect(paddle_rect):
if ball_vel[1] > 0:
ball_vel[1] = -abs(ball_vel[1])
ball_pos[1] = paddle_rect.top - BALL_RADIUS
# 벽돌과 충돌
for brick in bricks[:]:
if ball_rect.colliderect(brick):
# ADDED 충돌한 벽돌이 보너스 벽돌인지 먼저 확인
is_bonus = brick in bonus_bricks
bricks.remove(brick)
# ADDED 보너스 벽돌이면 보너스 목록에서도 제거
if is_bonus:
bonus_bricks.remove(brick)
score += BONUS_SCORE
else:
score += NORMAL_SCORE
ball_vel[1] *= -1
block_count -= 1
# 남은 벽돌 수가 0이면 게임 클리어
if block_count <= 0:
game_state = "clear"
end_message = "You Win"
return
break
# 공이 화면 아래로 떨어졌을 때
if ball_pos[1] - BALL_RADIUS > HEIGHT:
life -= 1
# 생명이 0이면 게임 오버
if life <= 0:
game_state = "game_over"
end_message = "Game Over"
return
# 생명이 남아 있으면 공을 중앙으로 되돌리고 ready 상태로 변경
ball_pos = [WIDTH // 2, HEIGHT // 2]
ball_vel = [BALL_SPEED_X, BALL_SPEED_Y]
game_state = "ready"
# 종료 화면 출력
def render_end_screen():
screen.fill(BLACK)
message_text = font.render(end_message, True, WHITE)
message_rect = message_text.get_rect(
center=(WIDTH // 2, HEIGHT // 2 - 30)
)
screen.blit(message_text, message_rect)
guide_text = font.render("Press any key to exit", True, WHITE)
guide_rect = guide_text.get_rect(
center=(WIDTH // 2, HEIGHT // 2 + 20)
)
screen.blit(guide_text, guide_rect)
# 4. 출력 처리
def render():
# 게임 종료 상태이면 종료 화면 출력
if game_state == "game_over" or game_state == "clear":
render_end_screen()
pygame.display.flip()
return
screen.fill(BLACK)
# 게임 정보 출력
text_score = font.render(f"Score: {score}", True, WHITE)
text_life = font.render(f"Life: {life}", True, WHITE)
text_blocks = font.render(f"Blocks: {block_count}", True, WHITE)
score_rect = text_score.get_rect(topleft=(10, 10))
life_rect = text_life.get_rect(midtop=(WIDTH // 2, 10))
blocks_rect = text_blocks.get_rect(topright=(WIDTH - 10, 10))
screen.blit(text_score, score_rect)
screen.blit(text_life, life_rect)
screen.blit(text_blocks, blocks_rect)
# CHANGED 벽돌 그리기
for brick in bricks:
if brick in bonus_bricks:
pygame.draw.rect(screen, RED, brick)
else:
pygame.draw.rect(screen, WHITE, brick)
# 공 그리기
pygame.draw.circle(
screen,
WHITE,
(int(ball_pos[0]), int(ball_pos[1])),
BALL_RADIUS
)
# 패들 그리기
pygame.draw.rect(screen, WHITE, paddle_rect)
# ready 상태에서 시작 안내 문구 출력
if game_state == "ready":
start_text = font.render("Press SPACE to Start", True, WHITE)
start_rect = start_text.get_rect(
center=(WIDTH // 2, HEIGHT // 2 + 60)
)
screen.blit(start_text, start_rect)
pygame.display.flip()
# 5. 게임 실행
def run_game():
init()
while running:
handle_input()
update_game()
render()
clock.tick(60)
pygame.quit()
sys.exit()
run_game()
반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- figma
- Text Mining
- pygame
- 라이브러리
- 챗봇
- python
- 파이썬
- HIG
- UX
- 텍스트마이닝
- matplotlib
- 텍스트 마이닝
- 스마트기술
- 초보자를 위한 텍스트마이닝
- 사물인터넷
- 데이터R지
- 챗GPT
- 데이타R지
- 관계자분석
- 파이썬기초
- 프로토타입
- 4차산업혁명
- 휴리스틱평가
- HCI
- UI
- 컴퓨팅사고력
- 파이썬 기초
- Idle
- 피그마
- 안드로이드
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
글 보관함
