인프런 커뮤니티 질문&답변

강정윤님의 프로필 이미지
강정윤

작성한 질문수

파이썬 무료 강의 (활용편1) - 추억의 오락실 게임 만들기 (3시간)

공 튕기기

TypeError: invalid destination position for blit

작성

·

598

0

위와 같은 에러가 납니다.. ball을 cat으로 쓴 점 감안해주시면 감사하겠습니다.

error:

File "c:\Users\user\Desktop\pygame_basic\1_create_frame.py", line 159, in <module>

    screen.blit(cat_images[cat_img_idx], (cat_pos_x, cat_pos_y))

TypeError: invalid destination position for blit

--source

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_x_pos = (screen_width - character_width) / 2  # x position = 화면 가로의 절반에 위치 하도록 (캐릭터의 x 좌표)
character_y_pos = 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축 최초 속도
})

# 폰트 정의
game_font = pygame.font.Font(None, 40) # 폰트 객체 생성 (폰트, 크기)

# 게임 총 시간
total_time= 10

# 시작 시간 계산
start_ticks = pygame.time.get_ticks() # 현재 tick 정보를 받아옴

# 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_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])
            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_x_pos += chracter_to_x * dt # FPS에 따라 속도가 변하지 않게 delta 값을 곱해주어 고정해줌

    # 캐릭터 가로 경계값 처리
    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 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["pos_x"]
        cat_val["pos_y"] += cat_val["pos_y"]


    # 충돌 처리를 위한 rect 정보 update
    character_rect = character.get_rect()
    character_rect.left = character_x_pos 
    character_rect.top = character_y_pos

    # screen.fill((r, g, b)) # rgb 값으로 배경색 채울 수도 있음
    screen.blit(background, (0, 0)) # 배경 이미지를 어디서부터 나타내줄건지. 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(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_x_pos, character_y_pos)) # 캐릭터 그리기
    
    # 타이머, 경과 시간 계산
    elapsed_time = (pygame.time.get_ticks() - start_ticks) / 1000 # 초단위로 표시
    timer = game_font.render(str(int(total_time - elapsed_time)), True, (255, 0, 0))
    screen.blit(timer, (10, 10))
    # 시간이 0 이하면 game over
    if(total_time - elapsed_time <= 0):
        print("Game Over")
        running = False

    pygame.display.update() # 게임 화면 다시 그리기

# 잠시 대기
pygame.time.delay(2000) # 2초 대기

# pygame 종료
pygame.quit()

답변 1

0

cat_val["pos_x"] += cat_val["pos_x"]
cat_val["pos_y"] += cat_val["pos_y"]

이부분

cat_val["pos_x"] += cat_val["to_x"]
cat_val["pos_y"] += cat_val["to_y"]

강정윤님의 프로필 이미지
강정윤

작성한 질문수

질문하기