공(고양이)가 안없어집니다.. 이미지를 바꾸면서 ball을 cat으로, to_remove를 _rm으로 바꾼 것 양해부탁드립니다.
# 2. 강아지가 고양이에 닿으면 게임 종료, 실패
# 3. 시간 제한 99초 초과 시 게임 종료, 실패
import pygame, os
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()
# 1. 사용자 게임 초기화
# 이미지 불러오기
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, "puppy.png")) # 70*70 캐릭터 불러오기
character_size = character.get_rect().size # 캐릭터 이미지의 가로 세로 크기를 가져옴
character_width = character_size[0] # 캐릭터의 가로 크기
character_height = character_size[1] # 캐릭터의 세로 크기
character_pos_x = (screen_width - character_width) / 2 # x position = 화면 가로의 절반에 위치 하도록 (캐릭터의 x 좌표)
character_pos_y = screen_height - stage_height - character_height + 10
# 이동할 좌표
chracter_to_x = 0
# 이동 속도
character_speed = 0.4
# 무기 만들기
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
# target
cat_images = [
pygame.image.load(os.path.join(image_path, "cat0.png")),
pygame.image.load(os.path.join(image_path, "cat1.png")),
pygame.image.load(os.path.join(image_path, "cat2.png")),
pygame.image.load(os.path.join(image_path, "cat3.png"))
]
# 타겟 크기에 따른 최초 스피드
cat_speed_y = [-18, -15, -12, -9] # index 0 1 2 3 - cat 1 2 3 4
# 타겟들
cats = []
# 최초 발생하는 큰 고양이 추가
cats.append({
"pos_x" : 50, # 고양이의 x 좌표
"pos_y" : 50, # 고양이의 y 좌표
"img_idx" : 0, # 고양이의 이미지 인덱스
"to_x" : 3, # 고양이의 x축 이동 방향, -3이면 왼쪽으로 3이면 오른쪽ㅇfh
"to_y" : -6, # y축 이동 방향
"init_spd_y" : cat_speed_y[0] # y축 최초 속도
})
# 사라질 츄르, 고양이 정보 저장 변수
weapon_rm = -1
cat_rm = -1
# 폰트 정의
game_font = pygame.font.Font(None, 40) # 폰트 객체 생성 (폰트, 크기)
# 게임 총 시간
total_time= 100
# 시작 시간 계산
start_ticks = pygame.time.get_ticks() # 현재 tick 정보를 받아옴
# Game Over, TIME OVER, Mission Complete
game_result = "GAME OVER"
# event loop
running = True # 게임이 진행 중인가?
while running:
dt = clock.tick(30) # delta = clock. FPS 설정
for event in pygame.event.get(): # 키보드에 맞는 이벤트 실행되면
if event.type == pygame.QUIT: # 창 끄기 이벤트 발생 시
running = False
if event.type == pygame.KEYDOWN: # 키가 눌러졌는데 확인
if event.key == pygame.K_RIGHT:
chracter_to_x += character_speed
elif event.key == pygame.K_LEFT:
chracter_to_x -= character_speed
elif event.key == pygame.K_SPACE: # 스페이스바 누르면 무기 발사
weapon_pos_x = character_pos_x + (character_width / 2) - (weapon_width / 2)
weapon_pos_y = character_pos_y
weapons.append([weapon_pos_x, weapon_pos_y])
elif event.key == pygame.K_UP:
pass
elif event.key == pygame.K_DOWN:
pass
if event.type == pygame.KEYUP: # 방향키를 뗐을 때
if event.key == pygame.K_RIGHT or event.key == pygame.K_LEFT:
chracter_to_x = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
pass
# 캐릭터 움직이기
character_pos_x += chracter_to_x * dt # FPS에 따라 속도가 변하지 않게 delta 값을 곱해주어 고정해줌
# 캐릭터 가로 경계값 처리
if character_pos_x < 0:
character_pos_x = 0
elif character_pos_x > screen_width - character_width:
character_pos_x = screen_width - character_width
# 무기 위치 조정
weapons = [[w[0], w[1] - weapon_speed] for w in weapons]
# 무기가 천장에 닿으면 없애기
# weapons = [[w[0], w[1]] for w in wea pons if w[1] > 0]
# 타겟 위치 정의
for cat_idx, cat_val in enumerate(cats):
cat_pos_x = cat_val["pos_x"]
cat_pos_y = cat_val["pos_y"]
cat_img_idx = cat_val["img_idx"]
cat_size = cat_images[cat_img_idx].get_rect().size
cat_width = cat_size[0]
cat_height = cat_size[1]
# 가로 경계값: 타겟의 경계값 처리 -> 경계값이 닿으면 반대 쪽으로 튕김
if cat_pos_x < 0 or cat_pos_x > (screen_width - cat_width):
cat_val["to_x"] *= -1
# 세로 경계값: 스테이지에 튕겨서 올라감
if cat_pos_y >= (screen_height - stage_height - cat_height):
cat_val["to_y"] = cat_val["init_spd_y"]
else: # 그 외 모든 경우에는 to_y를 증가
cat_val["to_y"] += 0.5
cat_val["pos_x"] += cat_val["to_x"]
cat_val["pos_y"] += cat_val["to_y"]
# 충돌 처리를 위한 rect 정보 update
character_rect = character.get_rect()
character_rect.left = character_pos_x
character_rect.top = character_pos_y
for cat_idx, cat_val in enumerate(cats):
cat_pos_x = cat_val["pos_x"]
cat_pos_y = cat_val["pos_y"]
cat_img_idx = cat_val["img_idx"]
# cat rect 정보 업뎃
cat_rect = cat_images[cat_img_idx].get_rect()
cat_rect.left = cat_pos_x
cat_rect.top = cat_pos_y
# cat과 puppy 충돌 처리
if character_rect.colliderect(cat_rect):
running = False
break
# cat과 츄르 충돌 처리
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(cat_rect):
weapon_rm = weapon_idx # 해당 츄르 없애기 위한 값 설정
cat_rm = cat_idx # 해당 고양이 없애기 위한 값 설정
if cat_img_idx < 3: # 0 1 2 -> 가장 작은 공이 아니라면
# 현재 고양이 크기 정보
cat_width = cat_rect.size[0]
cat_height = cat_rect.size[1]
#나눠질 고양이 정보
small_cat_rect = cat_images[cat_img_idx + 1].get_rect()
small_cat_width = small_cat_rect.size[0]
small_cat_heigth = small_cat_rect.size[1]
# 왼쪽으로 튕겨나가는 작은 고양이
cats.append({
"pos_x" : cat_pos_x + (cat_width / 2) - (small_cat_width / 2),
"pos_y" : cat_pos_y + (cat_height / 2) - (small_cat_heigth / 2), # 고양이의 y 좌표
"img_idx" : cat_img_idx + 1,
"to_x" : -3, # 고양이의 x축 이동 방향, -3이면 왼쪽으로 3이면 오른쪽ㅇfh
"to_y" : -6, # y축 이동 방향
"init_spd_y" : cat_speed_y[cat_img_idx + 1] # y축 최초 속도
})
# 오른쪽으로 튕겨나가는 작은 고양이
cats.append({
"pos_x" : cat_pos_x + (cat_width / 2) - (small_cat_width / 2),
"pos_y" : cat_pos_y + (cat_height / 2) - (small_cat_heigth / 2), # 고양이의 y 좌표
"img_idx" : cat_img_idx + 1,
"to_x" : +3, # 고양이의 x축 이동 방향, -3이면 왼쪽으로 3이면 오른쪽ㅇfh
"to_y" : -6, # y축 이동 방향
"init_spd_y" : cat_speed_y[cat_img_idx + 1] # y축 최초 속도
})
break
else:
continue
# 충돌된 cat or 무기 없애기
if cat_rm > -1:
del cats[cat_rm]
cat_rm = -1
if weapon_rm > -1:
del weapons[weapon_rm]
weapon_rm = -1
# 모든 cat이 없어졌을 때
if(len(cats)==0):
game_result = "MISSION COMPLETE"
running = False
# screen.fill((r, g, b)) # rgb 값으로 배경색 채울 수도 있음
screen.blit(background, (0, 0)) # 배경 이미지를 어디서부터 나타내줄건지. 0, 0 -> 왼쪽 맨 위부터
for weapon_pos_x, weapon_pos_y in weapons:
screen.blit(weapon, (weapon_pos_x, weapon_pos_y))
for idx, val in enumerate(cats):
cat_pos_x = val["pos_x"]
cat_pos_y = val["pos_y"]
cat_img_idx = val["img_idx"]
screen.blit(cat_images[cat_img_idx], (cat_pos_x, cat_pos_y))
screen.blit(stage, (0, screen_height - stage_height))
screen.blit(character, (character_pos_x, character_pos_y)) # 캐릭터 그리기
# 타이머, 경과 시간 계산
elapsed_time = (pygame.time.get_ticks() - start_ticks) / 1000 # 초단위로 표시
timer = game_font.render("Time: {}".format(int(total_time - elapsed_time)), True, (255, 0, 0))
screen.blit(timer, (10, 10))
# 시간이 0 이하면 game over
if(total_time - elapsed_time <= 0):
game_result = "TIME OVER"
running = False
pygame.display.update() # 게임 화면 다시 그리기
# 잠시 대기
pygame.time.delay(1000) # 2초 대기
# 게임 오버 메세지
msg = game_font.render(game_result, True, (255,0,0))
msg_rect = msg.get_rect(center=(int(screen_width / 2), int(screen_height / 2)))
screen.blit(msg, msg_rect)
pygame.display.update()
pygame.time.delay(2000)
# pygame 종료
pygame.quit()