강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của kooroo761432
kooroo761432

câu hỏi đã được viết

Bài giảng Python miễn phí (Cách sử dụng Phần 1) - Tạo game arcade hoài cổ (3 giờ)

Chia bóng

공에 무기가 닿았을 때 공이 안 사라져요

Viết

·

519

0

import pygameos

from pygame.constants import K_LEFTK_RIGHT

pygame.init() # 초기화 (항상 적어야 하는것)
pygame.mixer.init()

# 화면 크기
screen_width = 640 # 가로
screen_height = 480 # 세로
screen = pygame.display.set_mode((screen_widthscreen_height)) # 화면 설정

# 화면 타이틀
pygame.display.set_caption("dudcks pang"# 게임 이름

current_path = os.path.dirname(__file__) # 현재 파일의 위치 반환
image_path = os.path.join(current_path"images")
music_path = os.path.join(current_path"music")

# 배경 만들기
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 = (screen_width / 2) - (character_width / 2 )
character_y = 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축 이동방향
    "to_y" : -6# y축 이동방향
    "init_spd_y" : ball_speed_y[0] }) # y 최초 속도

# 사라질 무기, 공 정보 저장 변수
weapon_to_remove = -1
ball_to_remove = -1

# 음악
music = pygame.mixer.music.load(os.path.join(music_path"music.mp3"))
pygame.mixer.music.set_volume(0.2)
pygame.mixer.music.play()
MUSIC_END_EVENT = pygame.USEREVENT + 1
pygame.mixer.music.set_endevent(MUSIC_END_EVENT)

# FPS
clock = pygame.time.Clock()

# 이벤트 루트
running = True
while running:
    dt = clock.tick(30# 초당 프레임 수
    for event in pygame.event.get(): # 들어오는 이벤트를 받아옴
        if event.type == pygame.QUIT# X버튼을 눌렀을때
            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 = character_x + (character_width / 2) - (weapon_width / 2)        
                weapon_y = character_y
                weapons.append([weapon_xweapon_y])

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                character_to_x = 0

        if event.type == MUSIC_END_EVENT:
            pygame.mixer.music.play()

    # 캐릭터 위치 정의
    character_x += character_to_x

    if character_x < 0:
        character_x = 0
    elif character_x > screen_width - character_width:
        character_x = screen_width - character_width

    # 무기 위치 조정
    # 100, 200 -> 180, 160, 140, ...
    # 500, 200 -> 180, 160, 140, ...
    weapons = [ [w[0], w[1] - weapon_speedfor w in weapons]

    # 천장에 닿은 무기 없애기
    weapons = [ [w[0], w[1] - weapon_speedfor w in weapons if w[1] > 0]

    # 공 위치 정의
    for ball_idxball_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
    character_rect.top = character_y

    for ball_idxball_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

        # 공과 무기들 충돌 처리
        for weapon_idxweapon_val in enumerate(weapons):
            weapon_x = weapon_val[0]
            weapon_y = weapon_val[1]

            # 무기 rect 정보 업데이트
            weapon_rect = weapon.get_rect()
            weapon_rect.left = weapon_x
            weapon_rect.top = weapon_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), # 공의 x좌표 
                        "pos_y" : ball_pos_y + (ball_height / 2) - (small_ball_height / 2), # 공의 y좌표
                        "img_idx" : ball_img_idx + 1# 공의 이미지 인덱스
                        "to_x" : -3# x축 이동방향
                        "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축 이동방향
                        "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, (00))
    
    for weapon_xweapon_y in weapons:
        screen.blit(weapon, (weapon_xweapon_y))

    for idxval 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_xball_pos_y))

    screen.blit(stage, (0screen_height - stage_height))
    screen.blit(character, (character_xcharacter_y))

    

    pygame.display.update() # 게임 화면 다시 그리기 (항상 적어야 하는것)

# pygame 종료
pygame.quit

이렇게 해봤는데 어떨때는 잘 되고 어떨때는 작은 공들이 우수수 나와요

GUIpygamepython

Câu trả lời 2

1

                        "init_spd_y" : ball_speed_y[ball_img_idx + 1] }) # y 최초 속도

                

                break

해당부분 바꿔봐요. 다음과 같이

                        "init_spd_y" : ball_speed_y[ball_img_idx + 1]
                       }) # y 최초 속도
                break
        else# 계임 계속
            continue # 안쪽 for 문 조건이 맞지 않으면 continue. 바깥 for
        break  

0

kooroo761432님의 프로필 이미지
kooroo761432
Người đặt câu hỏi

이렇게 바꿔도 될때도 있고 안될때도 있네요... 계속 해보니...

Hình ảnh hồ sơ của kooroo761432
kooroo761432

câu hỏi đã được viết

Đặt câu hỏi