Lecture 이미지와 시간

Lecture • Views 337 • Comments 0 • Last Updated at 1 day ago  
  • 이미지
  • 파이게임

이미지 모듈 함수

파이게임에서 이미지를 로딩은 pygame.image 모듈이 있다.

함수 설명 함수 설명
pygame.image.load 이미지 로드 pygame.image.save 이미지 저장
pygame.image.get_extended 이미지 형식을 로드 pygame.image.tostring 이미지를 문자열 버퍼로 전송
pygame.image.fromstring 문자열 버퍼로부터 새 표면 생성 pygame.image.frombuffer

이미지 로딩

특정한 이미지를 로딩은:

image_surf = pygame.image.load("myimage.bmp").convert()
player = pygame.image.load('player.bmp').convert()
background = pygame.image.load('liquid.bmp').convert()

로드 함수는 파일 이름만 가져와 로드된 이미지가 있는 새 Surface를 반환한다.

로드한 후 Surface 메서드인 convert()를 호출한다. Convert는 이미지를 디스플레이와 동일한 픽셀 형식으로 변환된다. 이미지는 화면에서 동일한 형식이 되므로 매우 빠르게 blit된다. 변환하지 않으면 blit() 함수가 더 느려진다.

이미지 읽고 표현하기

screen = pygame.display.set_mode(스크린크기)
p_img = pygame.image.load(이미지이름)  #1
p_img = pygame.transform.scale(p_img, 새로운 크기)  #2
while True:
   screen.blit(p_img,위치) #3
   pygame.display.update()
pygame.quit()
  • 1 : 이미지를 로드한다. 이미지이름에는 위치도 포함된다.
  • 2 : 이미지의 크기를 원하는 크기로 조정한다.
  • 3 : blit함수는 그림을 위치에 그려준다.

이미지 움직이기

화면에서 10개의 다른 이미지가 움직이기를 원한다고 가정해 보겠습니다. 이를 처리하는 좋은 방법은 파이썬 클래스를 사용하는 것이다.

게임 객체를 나타내는 클래스를 만든다. 이 객체는 자체를 이동하는 함수를 갖는다. 객체를 그리거나 이동하는 함수는 한 번에 한 프레임(또는 한 단계)만 이동하는 방식으로 작동해야 한다.

클래스를 만드는 파이썬 코드는 다음과 같습니다.

class GameObject:
    def __init__(self, image, height, speed):
        self.speed = speed
        self.image = image
        self.pos = image.get_rect().move(0, height)
    def move(self):
        self.pos = self.pos.move(self.speed, 0)
        if self.pos.right > 600:
            self.pos.left = 0

그래서 우리 클래스에는 두 가지 함수가 있습니다. init 함수는 객체를 구성합니다. 객체를 배치하고 속도를 설정합니다. move 메서드는 객체를 한 단계 이동합니다. 너무 멀리 이동하면 객체를 왼쪽으로 다시 이동합니다.

예제

# pg_init07.py

import pygame
from pygame.locals import *
 
pygame.init()
screen = pygame.display.set_mode((500,400))
clock = pygame.time.Clock()

p_img = pygame.image.load('tiger.bmp')
#p_img = pygame.transform.scale(p_img, (100,100))

white = (255,255,255)
black = (0,0,0)
x = 0
y = 0
vel = 5

running = True
left_key, right_key, up_key, down_key = False, False, False, False

while running:
    clock.tick(60)  
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:  #1
            if event.key == pygame.K_LEFT:
                left_key = True
            if event.key == pygame.K_RIGHT:
                right_key = True
            if event.key == pygame.K_UP:
                up_key = True
            if event.key == pygame.K_DOWN:
                down_key = True
        if event.type == pygame.KEYUP:  #2
            if event.key == pygame.K_LEFT:
                left_key = False
            if event.key == pygame.K_RIGHT:
                right_key = False
            if event.key == pygame.K_UP:
                up_key = False
            if event.key == pygame.K_DOWN:
                down_key = False            
            
    if left_key:
        x = x - vel
    if right_key:
        x = x + vel
    if up_key:
        y = y - vel
    if down_key:
        y = y + vel
    
    screen.fill(white)
    screen.blit(p_img, (x,y))  #3
    pygame.display.update()
pygame.quit()
  • 키가 눌려있는 동안 vel의 픽셀 만큼 움직인다.
  • 키가 떨어지면 움직임이 없어진다.
  • 이미지의 위치(x,y)에 그림을 그려진다.

배경화면 만들기

  • 배경화면은 이미지를 읽어 들여 창의 크기와 같게 만들면 배경화면이 된다.
import pygame
 
screen = pygame.display.set_mode((500,400))
bg = pygame.image.load("배경이미지.jpg")
bg = pygame.transform.scale(bg, ('사이즈'))  #배경 이미지를 창의 크기에 맞게 스케일을 바꿔준다. 

running = True

while running:
   for event in pygame.event.get():
      if event.type == pygame.QUIT:
         running = False
   screen.fill(white)
   screen.blit(bg, (0,0))
   
pygame.quit()  

tick함수

위 예제에서 tick(숫자)에서 괄호안의 숫자는 fps(frame per seconds)로 일초당 프레임 수를 나타낸다. fps가 5일때의 그림의 움직임이 부자연스러움이 보이지만 60일때는 그림의 움직임이 자연스럽다.

fps에 따라 캐릭터의 이동 속도가 달라진다. 캐릭터의 이동은 while문이 한번 실행될때마다 vel만큼 이동된다. 1초에 while문이 fps만큼 실행되니 캐릭터 이동 속도는 fps의 역수가 곱해져야 한다.

# fps가 dt=1/fps  x = x + vel * dt
# pg_image_01.py

import pygame
import time
import numpy as np

pygame.init()

win = pygame.display.set_mode((500,400)) #1
 
pygame.display.set_caption('두번째 예제') #2

x = 0
y = 0
white, black = (255,255,255), (0,0,0)
vel = 5
left_key, right_key, up_key, down_key = False, False, False, False
im = pygame.image.load('tiger.bmp')
im_resize = pygame.transform.scale(im, (100,100))
clock = pygame.time.Clock()
count = True
fps = 50
dt = 10/fps
running = True
while running:
    #pygame.time.delay(20)
    clock.tick(fps)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            break
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                left_key = True
            elif event.key == pygame.K_RIGHT:
                right_key =True
            elif event.key == pygame.K_UP:
                up_key =True
            elif event.key == pygame.K_DOWN:
                down_key =True
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                left_key = False
            elif event.key == pygame.K_RIGHT:
                right_key = False
            elif event.key == pygame.K_UP:
                up_key = False
            elif event.key == pygame.K_DOWN:
                down_key = False
    if left_key:
        x -= vel*dt
    if right_key:
        x += vel*dt
        if count:
            ts = time.time_ns()
            count = False
    if up_key:
        y -= vel*dt
    if down_key:
        y += vel*dt
    if x > 400:
        ts = (time.time_ns() - ts)/1000000
        print(f'elapsed time : {ts}[ms]') 
        running = False
    win.fill(white) #7
    win.blit(im_resize,(x,y))
    pygame.display.update() #5
pygame.quit() #3 
first article
last article
Comments
Feel free to ask a question, answer or comment, etc.