상세 컨텐츠

본문 제목

[Python 파이썬 독학 활용1편 1-2일차]

파이썬 스터디/파이썬-Python 활용편1

by 후즈테크 2020. 10. 21. 22:25

본문

반응형

 

[5] frame_per_second.py  

: 움직이는 속도 및 화면 전환(FPS)에 대한 정의

import pygame


pygame.init() # 초기화 작업(반드시 필요)

# 화면 크기 설정
screen_width = 480 # 가로 크기 픽셀단위
screen_height = 640 # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("Nado Game") #게임 이름

# FPS
clock = pygame.time.Clock()



# 배경 이미지 불러오기
background = pygame.image.load("D:/python/workspace/pygame_basic/background.png") # 이미지 불러오기, 경로 설정시 '\\' 또는 '/' 폴더 위치 표현 가능


# 캐릭터(스프라이트) 불러오기
character = pygame.image.load("D:/python/workspace/pygame_basic/character.png") # 이미지 불러오기, 경로 설정시 '\\' 또는 '/' 폴더 위치 표현 가능
character_size = character.get_rect().size # 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 # 캐릭터의 세로 위치, 화면 크기의 가장 아래

# 이동할 좌표
to_x = 0
to_y = 0

# 이동 속도

character_speed = 0.6

# 이벤트  루프
running = True # 게임이 진행중인가?
while running:
    dt = clock.tick(60) # 게임화면의 초당 프레임 수 설정

    # 캐릭터 가 100만큼 이동을 해야함
    # 10 fps : 1초 동안에 10번 동작 -> 1번에 10만큼 이동, 10 * 10 = 100
    # 20 fps : 1초 동안에 20번 동작 -> 1번에 5만큼 이동, 20 * 5 = 100

    #print("fps : " + str(clock.get_fps())) # 프레임 값 출력

    for event in pygame.event.get():
        if event.type == pygame.QUIT: # 오른쪽 상단 X 버튼, 창이 닫히는 이벤트가(종료) 가 발생하였는가?
            running = False # 게임이 진행중이 아님

        if event.type == pygame.KEYDOWN: #(KEYDOWN 대문자) , 키가 눌러졌는지 확인
            if event.key == pygame.K_LEFT: # 캐릭터를 왼쪽으로
                to_x -= character_speed # (to_x 값을  5감소 )
            elif event.key == pygame.K_RIGHT: # 캐릭터를  오른쪽으로
                to_x += character_speed # (to_x 값을  5증가 )
            elif event.key == pygame.K_UP: # 캐릭터를  위쪽으로
                to_y -= character_speed # (to_y 값을  5감소 )
            elif event.key == pygame.K_DOWN: # 캐릭터를  아래쪽으로
                to_y += character_speed # (to_y 값을  5증가 )

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                to_x = 0
            elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                to_y = 0


    character_x_pos += to_x * dt
    character_y_pos += to_y * dt

    # 가로 경계값 처리
    if character_x_pos <= 0:
        character_x_pos = 0
    elif character_x_pos > screen_width - character_width:
        character_x_pos = screen_width - character_width
    
    # 세로 경계값 처리
    if character_y_pos <=0:
        character_y_pos = 0
    elif character_y_pos > screen_height - character_height:
        character_y_pos = screen_height - character_height


    screen.blit(background, (0, 0))  # 배경 그리기 blit 으로 이미지 표시, 튜플 형식으로 표시 위치 설정

    screen.blit(character, (character_x_pos, character_y_pos))
    pygame.display.update() # 게임 화면을 다시 그리기!! (반드시 필요)

# pygame 종료
pygame.quit()

 - 화면 내 캐릭터가 움직이는 속도에 대한 정의가 필요.

 - FPS(Frame Per Second) 로 1초당 몇 Frame 으로 화면을 구성할 것인지에 대한 정의를 할 수 있다.

     : FPS가 높을수록 화면이 자연스럽게 움직이며, 낮으면 버벅거리는 것 처럼 보이게 된다.

       (일반적으로 24 또는 30 FPS 이상일 경우, 어색함을 느끼지 않으며 게임등과 같은 고성능의 기능을 할 경우에는 60 FPS 정도가 적정 값으로 사용할 수 있다.)

 - FPS에 대한 정의를 clock 객체로 선언하며, pygame.time.Clock() 함수를 통해 받을 수 있다.

 - while 구문 안에 dt = clock.tick(60) 으로 60 frame 을 입력하고 동작 상태를 확인한다.

 - 4_keyboard_event.py 까지는 캐릭터의 속도와 이동 좌표를 5로 고정하여 적용하였으나, frame 값을 설정하고 이동 좌표(to_x, to_y)를 고정 값을 쓰게 되면 frame이 바뀔 때 마다 캐릭터의 움직이는 속도가 달라진다.

  : 캐릭터 가 100만큼 이동을 해야하는 경우, 1초에 각 프레임 만큼 동작하기 때문에

     10 fps : 1초 동안에 10번 동작 -> 1번에 5만큼 이동, 10 * 5 = 50

     20 fps : 1초 동안에 20번 동작 -> 1번에 5만큼 이동, 20 * 5 = 100

    으로 움직이는 거리(속도)가 달라지게 된다.

  : 해당 기능을 개선하기 위해 character_speed 를 정의하고, character_x_pos 와 character_y_pos 를 

        character_x_pos += to_x      ->  character_x_pos += to_x * dt

        character_y_pos += to_y      ->  character_y_pos += to_y * dt

    로 변경하여 입력한다. 

  (....내가 이해한 내용이 정확히 맞는지 알 수 없으나, 내가 이해한 내용으로 추론을 해보면..... 한번의 입력으로 30fps 은 1/30 을 60 fps는 1/60 을 이동한다... 따라서 fps 값인 dt를 곱해주면 똑같은 속도를 유지 할 수 있다...... 차후 내용이 틀리거나 다른 내용을 알게 되면 수정.....이 필요하다....)

 - print("fps : " + str(clock.get_fps())) 으로 사용 중인 프레임 값을 출력 할 수 있다.

반응형

 

[6] collision.py

  : 충돌시 작업(캐릭터와 적 or 캐릭터와 아이템 등)

import pygame


pygame.init() # 초기화 작업(반드시 필요)

# 화면 크기 설정
screen_width = 480 # 가로 크기 픽셀단위
screen_height = 640 # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("Nado Game") #게임 이름

# FPS
clock = pygame.time.Clock()



# 배경 이미지 불러오기
background = pygame.image.load("D:/python/workspace/pygame_basic/background.png") # 이미지 불러오기, 경로 설정시 '\\' 또는 '/' 폴더 위치 표현 가능


# 캐릭터(스프라이트) 불러오기
character = pygame.image.load("D:/python/workspace/pygame_basic/character.png") # 이미지 불러오기, 경로 설정시 '\\' 또는 '/' 폴더 위치 표현 가능
character_size = character.get_rect().size # 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 # 캐릭터의 세로 위치, 화면 크기의 가장 아래

# 이동할 좌표
to_x = 0
to_y = 0

# 이동 속도
character_speed = 0.6

# 적 enemy 캐릭터
enemy = pygame.image.load("D:/python/workspace/pygame_basic/enemy.png") # 이미지 불러오기, 경로 설정시 '\\' 또는 '/' 폴더 위치 표현 가능
enemy_size = enemy.get_rect().size # rect - 사각형 size, 이미지 크기
enemy_width = enemy_size[0] # 적군 캐릭터의 가로 크기
enemy_height = enemy_size[1] # 적군 캐릭터의 세로 크기
enemy_x_pos = (screen_width / 2) - (enemy_width / 2) # 적군 캐릭터의 가로 위치, 화면 크기의 중앙에 위치
enemy_y_pos = (screen_height  / 2) - (enemy_height / 2)# 적군 캐릭터의 세로 위치, 화면 크기의 가장 아래



# 이벤트  루프
running = True # 게임이 진행중인가?
while running:
    dt = clock.tick(60) # 게임화면의 초당 프레임 수 설정

    # 캐릭터 가 100만큼 이동을 해야함
    # 10 fps : 1초 동안에 10번 동작 -> 1번에 10만큼 이동, 10 * 10 = 100
    # 20 fps : 1초 동안에 20번 동작 -> 1번에 5만큼 이동, 20 * 5 = 100

    #print("fps : " + str(clock.get_fps())) # 프레임 값 출력

    for event in pygame.event.get():
        if event.type == pygame.QUIT: # 오른쪽 상단 X 버튼, 창이 닫히는 이벤트가(종료) 가 발생하였는가?
            running = False # 게임이 진행중이 아님

        if event.type == pygame.KEYDOWN: #(KEYDOWN 대문자) , 키가 눌러졌는지 확인
            if event.key == pygame.K_LEFT: # 캐릭터를 왼쪽으로
                to_x -= character_speed 
            elif event.key == pygame.K_RIGHT: # 캐릭터를  오른쪽으로
                to_x += character_speed 
            elif event.key == pygame.K_UP: # 캐릭터를  위쪽으로
                to_y -= character_speed 
            elif event.key == pygame.K_DOWN: # 캐릭터를  아래쪽으로
                to_y += character_speed 

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                to_x = 0
            elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                to_y = 0


    character_x_pos += to_x * dt
    character_y_pos += to_y * dt

    # 가로 경계값 처리
    if character_x_pos <= 0:
        character_x_pos = 0
    elif character_x_pos > screen_width - character_width:
        character_x_pos = screen_width - character_width
    
    # 세로 경계값 처리
    if character_y_pos <=0:
        character_y_pos = 0
    elif character_y_pos > screen_height - character_height:
        character_y_pos = screen_height - character_height
        
    # 충돌 처리를 위한 rect 정보 업데이트
    character_rect = character.get_rect()
    character_rect.left = character_x_pos
    character_rect.top = character_y_pos

    enemy_rect = enemy.get_rect()
    enemy_rect.left = enemy_x_pos
    enemy_rect.top = enemy_y_pos

    # 충돌 체크
    if character_rect.colliderect(enemy_rect):
        print("충돌했어요")
        running = False



    screen.blit(background, (0, 0))  # 배경 그리기 blit 으로 이미지 표시, 튜플 형식으로 표시 위치 설정

    screen.blit(character, (character_x_pos, character_y_pos))
    screen.blit(enemy, (enemy_x_pos, enemy_y_pos)) # 적 그리기
    pygame.display.update() # 게임 화면을 다시 그리기!! (반드시 필요)

# pygame 종료
pygame.quit()

  - 적 캐릭터 정의(enemy) 및 크기, 위치 설정(character 와 유사)

  - screen.blit 통해 화면에 그리기 screen.blit(enemy, (enemy_x_pos, enemy_y_pos))

  - 충돌 처리를 위한 캐릭터와 적의 rect 정보를 정의한다. 

   : rect 는 사각형 기준의 size 정보이다.

  - rect 에 대한 정의(위치 정보) 후, character_rect.colliderect(enemy_rect) 라는 조건을 주게 되면

   : 해당 조건은 character_rect 의 위치 정보가 enemy_rect 의 위치 정보와 충돌(겹치게 되면) 하게 되면

    running 값을 변경하여 게임을 종료 시킨다.

 

[7] text.py

  : text 입력

import pygame


pygame.init() # 초기화 작업(반드시 필요)

# 화면 크기 설정
screen_width = 480 # 가로 크기 픽셀단위
screen_height = 640 # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("Nado Game") #게임 이름

# FPS
clock = pygame.time.Clock()



# 배경 이미지 불러오기
background = pygame.image.load("D:/python/workspace/pygame_basic/background.png") # 이미지 불러오기, 경로 설정시 '\\' 또는 '/' 폴더 위치 표현 가능


# 캐릭터(스프라이트) 불러오기
character = pygame.image.load("D:/python/workspace/pygame_basic/character.png") # 이미지 불러오기, 경로 설정시 '\\' 또는 '/' 폴더 위치 표현 가능
character_size = character.get_rect().size # 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 # 캐릭터의 세로 위치, 화면 크기의 가장 아래

# 이동할 좌표
to_x = 0
to_y = 0

# 이동 속도
character_speed = 0.6

# 적 enemy 캐릭터
enemy = pygame.image.load("D:/python/workspace/pygame_basic/enemy.png") # 이미지 불러오기, 경로 설정시 '\\' 또는 '/' 폴더 위치 표현 가능
enemy_size = enemy.get_rect().size # rect - 사각형 size, 이미지 크기
enemy_width = enemy_size[0] # 적군 캐릭터의 가로 크기
enemy_height = enemy_size[1] # 적군 캐릭터의 세로 크기
enemy_x_pos = (screen_width / 2) - (enemy_width / 2) # 적군 캐릭터의 가로 위치, 화면 크기의 중앙에 위치
enemy_y_pos = (screen_height  / 2) - (enemy_height / 2)# 적군 캐릭터의 세로 위치, 화면 크기의 가장 아래


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

# 총 시간
total_time = 10

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


# 이벤트  루프
running = True # 게임이 진행중인가?
while running:
    dt = clock.tick(60) # 게임화면의 초당 프레임 수 설정

    # 캐릭터 가 100만큼 이동을 해야함
    # 10 fps : 1초 동안에 10번 동작 -> 1번에 10만큼 이동, 10 * 10 = 100
    # 20 fps : 1초 동안에 20번 동작 -> 1번에 5만큼 이동, 20 * 5 = 100

    #print("fps : " + str(clock.get_fps())) # 프레임 값 출력

    for event in pygame.event.get():
        if event.type == pygame.QUIT: # 오른쪽 상단 X 버튼, 창이 닫히는 이벤트가(종료) 가 발생하였는가?
            running = False # 게임이 진행중이 아님

        if event.type == pygame.KEYDOWN: #(KEYDOWN 대문자) , 키가 눌러졌는지 확인
            if event.key == pygame.K_LEFT: # 캐릭터를 왼쪽으로
                to_x -= character_speed 
            elif event.key == pygame.K_RIGHT: # 캐릭터를  오른쪽으로
                to_x += character_speed 
            elif event.key == pygame.K_UP: # 캐릭터를  위쪽으로
                to_y -= character_speed
            elif event.key == pygame.K_DOWN: # 캐릭터를  아래쪽으로
                to_y += character_speed 

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                to_x = 0
            elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                to_y = 0


    character_x_pos += to_x * dt
    character_y_pos += to_y * dt

    # 가로 경계값 처리
    if character_x_pos <= 0:
        character_x_pos = 0
    elif character_x_pos > screen_width - character_width:
        character_x_pos = screen_width - character_width
    
    # 세로 경계값 처리
    if character_y_pos <=0:
        character_y_pos = 0
    elif character_y_pos > screen_height - character_height:
        character_y_pos = screen_height - character_height
        
    # 충돌 처리를 위한 rect 정보 업데이트
    character_rect = character.get_rect()
    character_rect.left = character_x_pos
    character_rect.top = character_y_pos

    enemy_rect = enemy.get_rect()
    enemy_rect.left = enemy_x_pos
    enemy_rect.top = enemy_y_pos

    # 충돌 체크
    if character_rect.colliderect(enemy_rect):
        print("충돌했어요")
        running = False



    screen.blit(background, (0, 0))  # 배경 그리기 blit 으로 이미지 표시, 튜플 형식으로 표시 위치 설정

    screen.blit(character, (character_x_pos, character_y_pos))
    screen.blit(enemy, (enemy_x_pos, enemy_y_pos)) # 적 그리기

    # 타이머 집어넣기
    # 경과 시간 계산
    elapsed_time = (pygame.time.get_ticks() - start_ticks) / 1000 # 남은 시간을 역순으로 보여주기 위해 , /1000 -> 기준 값이 ms 이므로 단위를 s 로 변경
    # 경과 시간(ms)을 1000으로 나누어서 초(s) 단위로 표시
    

    timer = game_font.render(str(int(total_time - elapsed_time)), True, (255, 255, 255)) # 남은 시간을 역순으로 보여주기 위해 
    # 출력할 글자(시간), True, 글자 색상

    screen.blit(timer, (10, 10))
    
    
    # 만약 시간이 0 이하이면 게임 종료
    if total_time - elapsed_time <= 0 :
        print("타임아웃")
        running = False
        


    pygame.display.update() # 게임 화면을 다시 그리기!! (반드시 필요)


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

# pygame 종료
pygame.quit()

 - font 정의 : pygame.font.Font(None, 40) 으로 정의, None : Default 기본 값 사용, 40 : font size

   * 하지만 None으로 사용 후, pyinstaller를 사용하게 될 경우(실행파일), 

     폰트를 None으로 설정하면 오류가 발생하며 파일이 안 켜짐

   * pyinstaller는 파이썬이 깔려있지 않은 환경에서도 프로그램을 실행할 수 있게 파이썬 파일을 exe파일로 변환시켜주는 기능

 - 시간 값 표현을 위해 total_time = 10 으로 설정

 - pygame.time.get_ticks() 를 통해 현재 시간 값을 받아 올 수 있음.

 - game을 시작할 때 현재 시간 값을 start_ticks 로 정의

 - 현재 시간(pygame.time.get_ticks()) - 시작 시간(start_ticks)의 차이를 통해 경과 시간을 확인 할 수 있음. 해당 값은 ms 값이 므로 /1000을 나누어 s(초) 단위로 변환

 - 화면에 보여주게 될 타이머는 남은 시간을 보여주기 위해 total_time 과 elapsed_time 의 차이를 통해 구한다.

   : 정수형으로 나타내기 위해 int 를 사용.

 - gate_font_render 를 해당 글자를 화면에 그려줌.(value, True, Color)로 구성 , blit 도 추가로 진행해야함.

 - screen.blit(timer, (10, 10)) 으로 화면 10, 10 위치에 시간 값을 표시

 - pygame.time.delay(2000) : 게임 종료 전 화면 멈춤 2초(2000ms)

 

[8] frame.py

     : 차후 작업을 위한 기본 frame

import pygame
############################################################
# 기본 초기화 (반드시 해야하는 것들)
pygame.init() # 초기화 작업(반드시 필요)

# 화면 크기 설정
screen_width = 480 # 가로 크기 픽셀단위
screen_height = 640 # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("WhoseTech Game") #게임 이름

# FPS
clock = pygame.time.Clock()

############################################################

# 1. 사용자 게임 초기화 (배경화면, 게임이미지, 좌표, 속도, 폰트 등)

running = True # 
while running:
    dt = clock.tick(30) # 게임화면의 초당 프레임 수 설정

    # 캐릭터 가 100만큼 이동을 해야함
    # 10 fps : 1초 동안에 10번 동작 -> 1번에 10만큼 이동, 10 * 10 = 100
    # 20 fps : 1초 동안에 20번 동작 -> 1번에 5만큼 이동, 20 * 5 = 100

    #print("fps : " + str(clock.get_fps())) # 프레임 값 출력

    # 2. 이벤트 처리(키보드, 마우스 등)
    for event in pygame.event.get():
        if event.type == pygame.QUIT: 
            running = False

    #3. 게임 캐릭터 위치 정의
       
    # 4. 충돌 처리
    
    
    # 5. 화면에 그리기
    pygame.display.update() # 게임 화면을 다시 그리기!! (반드시 필요)


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

# pygame 종료
pygame.quit()

 

이후 퀴즈에서...

반응형

관련글 더보기

댓글 영역