Project) 오락실 Pang 게임 만들기
[게임조건]
1. 캐릭터는 화면 아래에 위치, 좌우로만 이동 가능
2. 스페이스를 누르면 무기를 쏘아 올림
3. 큰 공 1개가 나타나서 바운스
4. 무기에 닿으면 공은 작은 크기 2개로 분할, 가장 작은 크기의 공은 사라짐
5. 모든 공을 없애면 게임 종료(성공)
6. 캐릭터는 공에 닿으면 게임 종료 (실패)
7. 시간 제한 99초 초과 시 게임 종료 (실패)
8. FPS 는 30으로 고정 (필요시 speed 값을 조정)
[게임 이미지]
1. 배경 : 640 * 480(가로 세로) - background.png
2. 무대 : 640 * 50 - stage.png
3. 캐릭터 : 33 * 60 - character.png
4. 무기 : 20 * 430 - weapon.png
5. 공 : 160 * 160, 80 * 80 , 40 * 40 , 20 * 20 - balloon1.png ~ balloon4.png
1. 기초 화면 구성
코드
import os
import pygame
pygame.init()
#화면 크기 설정
screen_width = 640
screen_height = 480
screen = pygame.display.set_mode((screen_width,screen_height))
#화면 타이틀 설정
pygame.display.set_caption("나도 팡")
#FPS
clock = pygame.time.Clock()
# 상대경로로 파일 가져오기
current_path = os.path.dirname(__file__)
image_path = os.path.join(current_path, "images")
# 배경 만들기
background = pygame.image.load(os.path.join(image_path, "background.png"))
# 스테이지 만들기
stage = pygame.image.load(os.path.join(image_path, "stage.png"))
stage_size = stage.get_rect().size
stage_height = stage_size[1]
# 캐릭터 만들기
character = pygame.image.load(os.path.join(image_path, "character.png"))
character_size = character.get_rect().size
character_width = character_size[0]
character_height = character_size[1]
character_x_pos = (screen_width / 2) - (character_width / 2)
character_y_pos = screen_height - character_height - stage_height
running = True
while running:
dt = clock.tick(30)
#이벤트 처리
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 3. 게임 캐린터 위치 정의
# 4. 충돌처리
# 5.화면에 그리기
screen.blit(background, (0,0))
screen.blit(stage, (0,screen_height - stage_height))
screen.blit(character, (character_x_pos , character_y_pos ))
pygame.display.update()
pygame.quit()
2. 무기 만들기
코드
import os
import pygame
pygame.init()
#화면 크기 설정
screen_width = 640
screen_height = 480
screen = pygame.display.set_mode((screen_width,screen_height))
#화면 타이틀 설정
pygame.display.set_caption("나도 팡")
#FPS
clock = pygame.time.Clock()
# 상대경로로 파일 가져오기
current_path = os.path.dirname(__file__)
image_path = os.path.join(current_path, "images")
# 배경 만들기
background = pygame.image.load(os.path.join(image_path, "background.png"))
# 스테이지 만들기
stage = pygame.image.load(os.path.join(image_path, "stage.png"))
stage_size = stage.get_rect().size
stage_height = stage_size[1]
# 캐릭터 만들기
character = pygame.image.load(os.path.join(image_path, "character.png"))
character_size = character.get_rect().size
character_width = character_size[0]
character_height = character_size[1]
character_x_pos = (screen_width / 2) - (character_width / 2)
character_y_pos = screen_height - character_height - stage_height
# 캐릭터 이동 방향
character_to_x = 0
# 캐릭터 이동 속도
character_speed = 5
# 무기 만들기
weapon = pygame.image.load(os.path.join(image_path, "weapon.png"))
weapon_size = weapon.get_rect().size
weapon_width = weapon_size[0]
# 무기는 한 번에 여러 발 발사 가능
weapons = []
# 무기 이동 속도
weapon_speed = 10
running = True
while running:
dt = clock.tick(30)
#이벤트 처리
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN: #키보드 눌러졌는지 확인
if event.key == pygame.K_LEFT : # 캐릭터를 왼쪽으로
character_to_x -= character_speed
elif event.key == pygame.K_RIGHT : # 캐릭터를 오른쪽으로
character_to_x += character_speed
elif event.key == pygame.K_SPACE: # 무기발사
weapon_x_pos = character_x_pos + (character_width / 2) - (weapon_width / 2)
weapon_y_pos = character_y_pos
weapons.append([weapon_x_pos, weapon_y_pos])
if event.type == pygame.KEYUP: #방향키를 떼면 멈춤. 키를 뗏다면 x,y 좌표값을 변화시키지 않는다.
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
character_to_x = 0
#캐릭터 좌표 바꾸기
character_x_pos += character_to_x
#화면 밖으로 벗어나지 않게 처리
#가로 경계 값
if character_x_pos < 0 :
character_x_pos = 0
elif character_x_pos > screen_width - character_width:
character_x_pos = screen_width - character_width
# 무기 위치 조정
# 100, 200 -> 180 ,160, 140....
# 500, 200 -> 180, 160, 140....
weapons = [[w[0], w[1] - weapon_speed] for w in weapons]
#천장에 닿지 않은 리스트만 다시 저장.--> 천장에 닿은 무기 없애기
weapons = [ [w[0], w[1]] for w in weapons if w[1] > 0]
# 4. 충돌처리
# 5.화면에 그리기 위에서 부터 아래 레이어
screen.blit(background, (0,0)) # 1 배경 그리고
# 2 . 무기 그리고
for weapon_x_pos , weapon_y_pos in weapons:
screen.blit(weapon, (weapon_x_pos , weapon_y_pos))
# 3 . 스테이지 그리고
screen.blit(stage, (0,screen_height - stage_height))
# 4. 캐릭터 그린다.
screen.blit(character, (character_x_pos , character_y_pos ))
pygame.display.update()
pygame.quit()
3. 공그리기
코드
import os
import pygame
pygame.init()
screen_width = 640
screen_height = 480
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption("나도 팡")
clock = pygame.time.Clock()
current_path = os.path.dirname(__file__)
image_path = os.path.join(current_path, "images")
background = pygame.image.load(os.path.join(image_path, "background.png"))
stage = pygame.image.load(os.path.join(image_path, "stage.png"))
stage_size = stage.get_rect().size
stage_height = stage_size[1]
character = pygame.image.load(os.path.join(image_path, "character.png"))
character_size = character.get_rect().size
character_width = character_size[0]
character_height = character_size[1]
character_x_pos = (screen_width / 2) - (character_width / 2)
character_y_pos = screen_height - character_height - stage_height
character_to_x = 0
character_speed = 5
weapon = pygame.image.load(os.path.join(image_path, "weapon.png"))
weapon_size = weapon.get_rect().size
weapon_width = weapon_size[0]
weapons = []
weapon_speed = 10
# 공 만들기 ( 4개 크기에 대해 따로 처리)
ball_images = [
pygame.image.load(os.path.join(image_path, "balloon1.png")),
pygame.image.load(os.path.join(image_path, "balloon2.png")),
pygame.image.load(os.path.join(image_path, "balloon3.png")),
pygame.image.load(os.path.join(image_path, "balloon4.png"))
]
# 공이 클수록 처음 스피드가 크게. 더 많이 튀어오름
# 공 크기에 따른 최초 스피드
ball_speed_y = [-18, -15, -12 ,-9] #index 0, 1, 2, 3 에 해당 하는 값
# 공들
balls = []
# 최초 발생 하는 큰 공 추가 사전으로 관리
balls.append({
"pos_x" : 50, # 공의 x 좌표
"pos_y" : 50, # 공의 y 좌표
"img_idx" : 0, #공의 이미지 인덱스
"to_x" : 3, # x축 이동 방향 -3 이면 왼쪽, 3이면 오른쪽으로
"to_y" : -6, #y축 이동방향,
"init_spd_y" : ball_speed_y[0]# y 최초 속도
})
running = True
while running:
dt = clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT :
character_to_x -= character_speed
elif event.key == pygame.K_RIGHT :
character_to_x += character_speed
elif event.key == pygame.K_SPACE:
weapon_x_pos = character_x_pos + (character_width / 2) - (weapon_width / 2)
weapon_y_pos = character_y_pos
weapons.append([weapon_x_pos, weapon_y_pos])
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
character_to_x = 0
character_x_pos += character_to_x
if character_x_pos < 0 :
character_x_pos = 0
elif character_x_pos > screen_width - character_width:
character_x_pos = screen_width - character_width
weapons = [[w[0], w[1] - weapon_speed] for w in weapons]
weapons = [ [w[0], w[1]] for w in weapons if w[1] > 0]
# 공 위치 정의
for ball_idx, ball_val in enumerate(balls):
ball_pos_x = ball_val["pos_x"]
ball_pos_y = ball_val["pos_y"]
ball_img_idx = ball_val["img_idx"]
ball_size = ball_images[ball_img_idx].get_rect().size
ball_width = ball_size[0]
ball_height = ball_size[1]
#공이 화면 밖으로 나가는것 처리
# 가로벽에 닿았을 때 공 이동 위치 변경 (튕겨 나오는 효과)
if ball_pos_x < 0 or ball_pos_x > screen_width - ball_width:
ball_val["to_x"] = ball_val["to_x"] * -1
#세로 위치
if ball_pos_y >= screen_height - stage_height - ball_height:
ball_val["to_y"] = ball_val["init_spd_y"]
else: # 그외의 모든 경우에는 속도를 증가
ball_val["to_y"] += 0.5
ball_val["pos_x"] += ball_val["to_x"]
ball_val["pos_y"] += ball_val["to_y"]
screen.blit(background, (0,0))
for weapon_x_pos , weapon_y_pos in weapons:
screen.blit(weapon, (weapon_x_pos , weapon_y_pos))
#공그리기
for idx, val in enumerate(balls) :
ball_pos_x = val["pos_x"]
ball_pos_y = val["pos_y"]
ball_img_idx = val["img_idx"]
screen.blit(ball_images[ball_img_idx], (ball_pos_x , ball_pos_y))
screen.blit(stage, (0,screen_height - stage_height))
screen.blit(character, (character_x_pos , character_y_pos ))
pygame.display.update()
pygame.quit()
4. 충돌처리 1단계
코드
import os
import pygame
pygame.init()
screen_width = 640
screen_height = 480
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption("나도 팡")
clock = pygame.time.Clock()
current_path = os.path.dirname(__file__)
image_path = os.path.join(current_path, "images")
background = pygame.image.load(os.path.join(image_path, "background.png"))
stage = pygame.image.load(os.path.join(image_path, "stage.png"))
stage_size = stage.get_rect().size
stage_height = stage_size[1]
character = pygame.image.load(os.path.join(image_path, "character.png"))
character_size = character.get_rect().size
character_width = character_size[0]
character_height = character_size[1]
character_x_pos = (screen_width / 2) - (character_width / 2)
character_y_pos = screen_height - character_height - stage_height
character_to_x = 0
character_speed = 5
weapon = pygame.image.load(os.path.join(image_path, "weapon.png"))
weapon_size = weapon.get_rect().size
weapon_width = weapon_size[0]
weapons = []
weapon_speed = 10
ball_images = [
pygame.image.load(os.path.join(image_path, "balloon1.png")),
pygame.image.load(os.path.join(image_path, "balloon2.png")),
pygame.image.load(os.path.join(image_path, "balloon3.png")),
pygame.image.load(os.path.join(image_path, "balloon4.png"))
]
ball_speed_y = [-18, -15, -12 ,-9]
balls = []
balls.append({
"pos_x" : 50,
"pos_y" : 50,
"img_idx" : 0,
"to_x" : 3,
"to_y" : -6,
"init_spd_y" : ball_speed_y[0]
})
# 사라질 무기, 공 정보 저장 변수
weapon_to_remove = -1
ball_to_remove = -1
running = True
while running:
dt = clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT :
character_to_x -= character_speed
elif event.key == pygame.K_RIGHT :
character_to_x += character_speed
elif event.key == pygame.K_SPACE:
weapon_x_pos = character_x_pos + (character_width / 2) - (weapon_width / 2)
weapon_y_pos = character_y_pos
weapons.append([weapon_x_pos, weapon_y_pos])
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
character_to_x = 0
character_x_pos += character_to_x
if character_x_pos < 0 :
character_x_pos = 0
elif character_x_pos > screen_width - character_width:
character_x_pos = screen_width - character_width
weapons = [[w[0], w[1] - weapon_speed] for w in weapons]
weapons = [ [w[0], w[1]] for w in weapons if w[1] > 0]
for ball_idx, ball_val in enumerate(balls):
ball_pos_x = ball_val["pos_x"]
ball_pos_y = ball_val["pos_y"]
ball_img_idx = ball_val["img_idx"]
ball_size = ball_images[ball_img_idx].get_rect().size
ball_width = ball_size[0]
ball_height = ball_size[1]
if ball_pos_x < 0 or ball_pos_x > screen_width - ball_width:
ball_val["to_x"] = ball_val["to_x"] * -1
if ball_pos_y >= screen_height - stage_height - ball_height:
ball_val["to_y"] = ball_val["init_spd_y"]
else:
ball_val["to_y"] += 0.5
ball_val["pos_x"] += ball_val["to_x"]
ball_val["pos_y"] += ball_val["to_y"]
#충돌 처리
# 캐릭터 rect 정보 업데이트
character_rect = character.get_rect()
character_rect.left = character_x_pos
character_rect.top = character_y_pos
#1단계 : 캐릭터와 공이 충동했다면 게임 종료
for ball_idx, ball_val in enumerate(balls):
ball_pos_x = ball_val["pos_x"]
ball_pos_y = ball_val["pos_y"]
ball_img_idx = ball_val["img_idx"]
#공 rect 정보 업데이트
ball_rect = ball_images[ball_img_idx].get_rect()
ball_rect.left = ball_pos_x
ball_rect.top = ball_pos_y
# 공과 캐릭터 충돌 처리
if character_rect.colliderect(ball_rect) :
running = False
break
#2단계 공과 무기들 충돌하면
# 공과 무기들 충돌 처리
for weapon_idx, weapon_val in enumerate(weapons):
weapon_pos_x = weapon_val[0]
weapon_pos_y = weapon_val[1]
# 무기 rect 정보 업데이트
weapon_rect = weapon.get_rect()
weapon_rect.left = weapon_pos_x
weapon_rect.top = weapon_pos_y
if weapon_rect.colliderect(ball_rect) :
#공도 없애고 무기도 사라짐
weapon_to_remove = weapon_idx #해당 무기 없애기 위한 값 설정
ball_to_remove = ball_idx # 해당 공 없애기 위한 값 설정
break
# 충돌된 공 or 무기 없애기
if ball_to_remove > -1:
del balls[ball_to_remove]
ball_to_remove = -1
if weapon_to_remove > -1:
del weapons[weapon_to_remove]
weapon_to_remove = -1
screen.blit(background, (0,0))
for weapon_x_pos , weapon_y_pos in weapons:
screen.blit(weapon, (weapon_x_pos , weapon_y_pos))
for idx, val in enumerate(balls) :
ball_pos_x = val["pos_x"]
ball_pos_y = val["pos_y"]
ball_img_idx = val["img_idx"]
screen.blit(ball_images[ball_img_idx], (ball_pos_x , ball_pos_y))
screen.blit(stage, (0,screen_height - stage_height))
screen.blit(character, (character_x_pos , character_y_pos ))
pygame.display.update()
pygame.quit()
5. 공 쪼개기
코드
import os
import pygame
pygame.init()
screen_width = 640
screen_height = 480
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption("나도 팡")
clock = pygame.time.Clock()
current_path = os.path.dirname(__file__)
image_path = os.path.join(current_path, "images")
background = pygame.image.load(os.path.join(image_path, "background.png"))
stage = pygame.image.load(os.path.join(image_path, "stage.png"))
stage_size = stage.get_rect().size
stage_height = stage_size[1]
character = pygame.image.load(os.path.join(image_path, "character.png"))
character_size = character.get_rect().size
character_width = character_size[0]
character_height = character_size[1]
character_x_pos = (screen_width / 2) - (character_width / 2)
character_y_pos = screen_height - character_height - stage_height
character_to_x = 0
character_speed = 5
weapon = pygame.image.load(os.path.join(image_path, "weapon.png"))
weapon_size = weapon.get_rect().size
weapon_width = weapon_size[0]
weapons = []
weapon_speed = 10
ball_images = [
pygame.image.load(os.path.join(image_path, "balloon1.png")),
pygame.image.load(os.path.join(image_path, "balloon2.png")),
pygame.image.load(os.path.join(image_path, "balloon3.png")),
pygame.image.load(os.path.join(image_path, "balloon4.png"))
]
ball_speed_y = [-18, -15, -12 ,-9]
balls = []
balls.append({
"pos_x" : 50,
"pos_y" : 50,
"img_idx" : 0,
"to_x" : 3,
"to_y" : -6,
"init_spd_y" : ball_speed_y[0]
})
# 사라질 무기, 공 정보 저장 변수
weapon_to_remove = -1
ball_to_remove = -1
running = True
while running:
dt = clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT :
character_to_x -= character_speed
elif event.key == pygame.K_RIGHT :
character_to_x += character_speed
elif event.key == pygame.K_SPACE:
weapon_x_pos = character_x_pos + (character_width / 2) - (weapon_width / 2)
weapon_y_pos = character_y_pos
weapons.append([weapon_x_pos, weapon_y_pos])
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
character_to_x = 0
character_x_pos += character_to_x
if character_x_pos < 0 :
character_x_pos = 0
elif character_x_pos > screen_width - character_width:
character_x_pos = screen_width - character_width
weapons = [[w[0], w[1] - weapon_speed] for w in weapons]
weapons = [ [w[0], w[1]] for w in weapons if w[1] > 0]
for ball_idx, ball_val in enumerate(balls):
ball_pos_x = ball_val["pos_x"]
ball_pos_y = ball_val["pos_y"]
ball_img_idx = ball_val["img_idx"]
ball_size = ball_images[ball_img_idx].get_rect().size
ball_width = ball_size[0]
ball_height = ball_size[1]
if ball_pos_x < 0 or ball_pos_x > screen_width - ball_width:
ball_val["to_x"] = ball_val["to_x"] * -1
if ball_pos_y >= screen_height - stage_height - ball_height:
ball_val["to_y"] = ball_val["init_spd_y"]
else:
ball_val["to_y"] += 0.5
ball_val["pos_x"] += ball_val["to_x"]
ball_val["pos_y"] += ball_val["to_y"]
#충돌 처리
# 캐릭터 rect 정보 업데이트
character_rect = character.get_rect()
character_rect.left = character_x_pos
character_rect.top = character_y_pos
#1단계 : 캐릭터와 공이 충동했다면 게임 종료
for ball_idx, ball_val in enumerate(balls):
ball_pos_x = ball_val["pos_x"]
ball_pos_y = ball_val["pos_y"]
ball_img_idx = ball_val["img_idx"]
#공 rect 정보 업데이트
ball_rect = ball_images[ball_img_idx].get_rect()
ball_rect.left = ball_pos_x
ball_rect.top = ball_pos_y
# 공과 캐릭터 충돌 처리
if character_rect.colliderect(ball_rect) :
running = False
break
#2단계 공과 무기들 충돌하면
# 공과 무기들 충돌 처리
for weapon_idx, weapon_val in enumerate(weapons):
weapon_pos_x = weapon_val[0]
weapon_pos_y = weapon_val[1]
# 무기 rect 정보 업데이트
weapon_rect = weapon.get_rect()
weapon_rect.left = weapon_pos_x
weapon_rect.top = weapon_pos_y
if weapon_rect.colliderect(ball_rect) :
#공도 없애고 무기도 사라짐
weapon_to_remove = weapon_idx
ball_to_remove = ball_idx
#일단 큰공은 없어지고 작은공 두개로 쪼개지면서 왼쪽으로, 오른쪽으로 튕겨져야 한다.
#위에 해당 공없애기 코드는 그대로 두고
#공쪼개기 시작
#가장 작은공이 아니라면 둘로 나누어진다.
if ball_img_idx < 3:
#현재 공 크기 정보를 가지고 옴
ball_width = ball_rect.size[0]
ball_height = ball_rect.size[1]
#나눠진 공 정보 #현재보다 더 작아진 공정보 idx 를 가지고 오기위해 +1
small_ball_rect = ball_images[ball_img_idx+1].get_rect()
small_ball_width = small_ball_rect.size[0]
small_ball_height = small_ball_rect.size[1]
#왼쪽으로 튕겨나가는 작은 공
balls.append({
"pos_x" : ball_pos_x + (ball_width / 2) - (small_ball_width / 2), # 공의 x 좌표
"pos_y" : ball_pos_y + (ball_height / 2) - (small_ball_height / 2), # 공의 y 좌표
"img_idx" : ball_img_idx + 1, # 공의 이미지 인덱스
"to_x" : -3, #x축 이동방향 - 3이면 왼쪽으로, 3이면 오른쪽 으로
"to_y" : -6, #y축 이동 방향
"init_spd_y" : ball_speed_y[ball_img_idx + 1] #y 최초 속도
})
#오른쪽으로 튕겨나가는 작은 공
balls.append({
"pos_x" : ball_pos_x + (ball_width / 2) - (small_ball_width / 2), # 공의 x 좌표
"pos_y" : ball_pos_y + (ball_height / 2) - (small_ball_height / 2), # 공의 y 좌표
"img_idx" : ball_img_idx + 1, # 공의 이미지 인덱스
"to_x" : 3, #x축 이동방향 - 3이면 왼쪽으로, 3이면 오른쪽 으로
"to_y" : -6, #y축 이동 방향
"init_spd_y" : ball_speed_y[ball_img_idx + 1] #y 최초 속도
})
break
# 충돌된 공 or 무기 없애기
if ball_to_remove > -1:
del balls[ball_to_remove]
ball_to_remove = -1
if weapon_to_remove > -1:
del weapons[weapon_to_remove]
weapon_to_remove = -1
screen.blit(background, (0,0))
for weapon_x_pos , weapon_y_pos in weapons:
screen.blit(weapon, (weapon_x_pos , weapon_y_pos))
for idx, val in enumerate(balls) :
ball_pos_x = val["pos_x"]
ball_pos_y = val["pos_y"]
ball_img_idx = val["img_idx"]
screen.blit(ball_images[ball_img_idx], (ball_pos_x , ball_pos_y))
screen.blit(stage, (0,screen_height - stage_height))
screen.blit(character, (character_x_pos , character_y_pos ))
pygame.display.update()
pygame.quit()
6. 게임 종료
코드
import os
import pygame
pygame.init()
screen_width = 640
screen_height = 480
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption("나도 팡")
clock = pygame.time.Clock()
current_path = os.path.dirname(__file__)
image_path = os.path.join(current_path, "images")
background = pygame.image.load(os.path.join(image_path, "background.png"))
stage = pygame.image.load(os.path.join(image_path, "stage.png"))
stage_size = stage.get_rect().size
stage_height = stage_size[1]
character = pygame.image.load(os.path.join(image_path, "character.png"))
character_size = character.get_rect().size
character_width = character_size[0]
character_height = character_size[1]
character_x_pos = (screen_width / 2) - (character_width / 2)
character_y_pos = screen_height - character_height - stage_height
character_to_x_LEFT = 0
character_to_x_RIGHT = 0
character_speed = 5
weapon = pygame.image.load(os.path.join(image_path, "weapon.png"))
weapon_size = weapon.get_rect().size
weapon_width = weapon_size[0]
weapons = []
weapon_speed = 10
ball_images = [
pygame.image.load(os.path.join(image_path, "balloon1.png")),
pygame.image.load(os.path.join(image_path, "balloon2.png")),
pygame.image.load(os.path.join(image_path, "balloon3.png")),
pygame.image.load(os.path.join(image_path, "balloon4.png"))
]
ball_speed_y = [-18, -15, -12 ,-9]
balls = []
balls.append({
"pos_x" : 50,
"pos_y" : 50,
"img_idx" : 0,
"to_x" : 3,
"to_y" : -6,
"init_spd_y" : ball_speed_y[0]
})
weapon_to_remove = -1
ball_to_remove = -1
#게임 종료
# 1. 모든 공을 없애면 게임 종료 (성공)
# 2. 캐릭터는 공에 닿으면 게임 종료 (실패)
# 3. 시간 제한 99초 초과 시 게임 종료 (실패)
# 종료 메시지
# TimeOver (시간 초과 실패)
# Mission Complete (성공)
# Game Over (캐릭터 공에 맞음 실패)
# 메세지 출력 위한 Font 정의
game_font = pygame.font.Font(None, 40)
total_time = 100
start_ticks = pygame.time.get_ticks() # 시작 시간 정의
game_result = "Game Over"
running = True
while running:
dt = clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT :
character_to_x_LEFT -= character_speed
elif event.key == pygame.K_RIGHT :
character_to_x_RIGHT += character_speed
elif event.key == pygame.K_SPACE:
weapon_x_pos = character_x_pos + (character_width / 2) - (weapon_width / 2)
weapon_y_pos = character_y_pos
weapons.append([weapon_x_pos, weapon_y_pos])
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
character_to_x_LEFT = 0
elif event.key == pygame.K_RIGHT:
character_to_x_RIGHT = 0
character_x_pos += character_to_x_LEFT + character_to_x_RIGHT
if character_x_pos < 0 :
character_x_pos = 0
elif character_x_pos > screen_width - character_width:
character_x_pos = screen_width - character_width
weapons = [[w[0], w[1] - weapon_speed] for w in weapons]
weapons = [ [w[0], w[1]] for w in weapons if w[1] > 0]
for ball_idx, ball_val in enumerate(balls):
ball_pos_x = ball_val["pos_x"]
ball_pos_y = ball_val["pos_y"]
ball_img_idx = ball_val["img_idx"]
ball_size = ball_images[ball_img_idx].get_rect().size
ball_width = ball_size[0]
ball_height = ball_size[1]
if ball_pos_x < 0 or ball_pos_x > screen_width - ball_width:
ball_val["to_x"] = ball_val["to_x"] * -1
if ball_pos_y >= screen_height - stage_height - ball_height:
ball_val["to_y"] = ball_val["init_spd_y"]
else:
ball_val["to_y"] += 0.5
ball_val["pos_x"] += ball_val["to_x"]
ball_val["pos_y"] += ball_val["to_y"]
character_rect = character.get_rect()
character_rect.left = character_x_pos
character_rect.top = character_y_pos
for ball_idx, ball_val in enumerate(balls):
ball_pos_x = ball_val["pos_x"]
ball_pos_y = ball_val["pos_y"]
ball_img_idx = ball_val["img_idx"]
ball_rect = ball_images[ball_img_idx].get_rect()
ball_rect.left = ball_pos_x
ball_rect.top = ball_pos_y
if character_rect.colliderect(ball_rect) :
running = False
break
# 공과 무기들 충돌 처리
for weapon_idx, weapon_val in enumerate(weapons):
weapon_pos_x = weapon_val[0]
weapon_pos_y = weapon_val[1]
weapon_rect = weapon.get_rect()
weapon_rect.left = weapon_pos_x
weapon_rect.top = weapon_pos_y
if weapon_rect.colliderect(ball_rect) :
weapon_to_remove = weapon_idx
ball_to_remove = ball_idx
if ball_img_idx < 3:
ball_width = ball_rect.size[0]
ball_height = ball_rect.size[1]
small_ball_rect = ball_images[ball_img_idx+1].get_rect()
small_ball_width = small_ball_rect.size[0]
small_ball_height = small_ball_rect.size[1]
balls.append({
"pos_x" : ball_pos_x + (ball_width / 2) - (small_ball_width / 2),
"pos_y" : ball_pos_y + (ball_height / 2) - (small_ball_height / 2),
"img_idx" : ball_img_idx + 1,
"to_x" : -3,
"to_y" : -6,
"init_spd_y" : ball_speed_y[ball_img_idx + 1]
})
balls.append({
"pos_x" : ball_pos_x + (ball_width / 2) - (small_ball_width / 2),
"pos_y" : ball_pos_y + (ball_height / 2) - (small_ball_height / 2),
"img_idx" : ball_img_idx + 1,
"to_x" : 3,
"to_y" : -6,
"init_spd_y" : ball_speed_y[ball_img_idx + 1]
})
break
else:
continue #안쪽 for 문 조건이 맞지 않으면 continue. 바깥 for 문 계속 수행
break # 안쪽 for 문에서 break 를 만나면 여기로 진입 가능. 2중 for 문을 한번에 탈출
if ball_to_remove > -1:
del balls[ball_to_remove]
ball_to_remove = -1
if weapon_to_remove > -1:
del weapons[weapon_to_remove]
weapon_to_remove = -1
# 모든 공을 없앤 경우 게임 종료 (성공)
if len(balls) == 0 :
game_result = "Mission Complete"
running = False
screen.blit(background, (0,0))
for weapon_x_pos , weapon_y_pos in weapons:
screen.blit(weapon, (weapon_x_pos , weapon_y_pos))
for idx, val in enumerate(balls) :
ball_pos_x = val["pos_x"]
ball_pos_y = val["pos_y"]
ball_img_idx = val["img_idx"]
screen.blit(ball_images[ball_img_idx], (ball_pos_x , ball_pos_y))
screen.blit(stage, (0,screen_height - stage_height))
screen.blit(character, (character_x_pos , character_y_pos ))
#경과 시간 계산
elapsed_time = (pygame.time.get_ticks()- start_ticks) / 1000 # ms -> s
timer = game_font.render("Time:{}".format(int(total_time-elapsed_time)),True,(255,255,255)) #실수를 정수로 바꾸기 위해 int 형변환
screen.blit(timer,(10,10))
#시간 초과했다면
if total_time - elapsed_time <= 0 :
game_result = "Time Over"
running = False
pygame.display.update()
# 게임 오버 메시지
msg = game_font.render(game_result, True,(255,255,0)) #노란색
msg_rect = msg.get_rect(center=(int(screen_width/2) , int(screen_height/2))) #실수를 정수로 바꾸기 위해 int 형변환
screen.blit(msg,msg_rect)
pygame.display.update()
pygame.time.delay(2000)
pygame.quit()
더보기
블로그에는 우클릭 방지가 걸려있어요. 코드복사는 카페에서 가능 합니다.
파이썬 기초는 나도코딩님이 인프런사이트에서 강의한 내용을 바탕으로 공부한 내용을 정리한 것 입니다.
추천 : ★★★★★
'코딩(개발) > 파이썬' 카테고리의 다른 글
파이썬 오토스크린 샷 (0) | 2020.12.30 |
---|---|
파이썬 GUI (0) | 2020.12.29 |
파이썬 똥 피하기 게임 (0) | 2020.12.25 |
파이썬 게임 만들기 (0) | 2020.12.24 |
파이썬 내장함수 / 외장함수 (0) | 2020.12.23 |
댓글