사각형 조작에 대해서 어느정도 파악을 했으니 마무리를 할 차례다. 도형이 움직이는 것과 이미지가 움직이는 것이 무슨 연관이 있는지도 보겠다.

 

1. 움직이는 도형

 

이번엔 움직이는 도형을 만들어보자. 키로 조작하는 도형은 이벤트처리기에서 사용자의 키보드 입력을 받아야 했다. 이것을 이벤트 처리기가 필요가 없다. While 루프가 도는 동안 태우기만 하면 된다. 움직이면서 도형이 윈도우창을 벗어나지 못하도록 if 문 처리를 해줘야 한다.

 

지금 아래에 보이는 도형은 직사각형과 타원형(ellipse)메소드로 설정한 원이다. (타원을 정사각형안에 넣으면 원이된다.)

 

움직이는 도형

import pygame
from pygame.locals import *
from pygame.rect import *
import pyc

size = width, height = 800,600
screen = pygame.display.set_mode(size)

rect1 = Rect(100,100,200,150)
rect2 = Rect(150,200,150,150)

speed = [2,8]
speed0 = [7,2]

clock = pygame.time.Clock()

pygame.init()

running = True
while running:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False

    rect1.move_ip(speed)
    rect2.move_ip(speed0)

    if rect1.left < 0:
        speed[0] *= -1
    if rect2.left < 0:
        speed0[0] *= -1
    if rect1.right > width:
        speed[0] *= -1
    if rect2.right > width:
        speed0[0] *= -1
    if rect1.top < 0:
        speed[1] *= -1
    if rect2.top < 0:
        speed0[1] *= -1
    if rect1.bottom > height:
        speed[1] *= -1
    if rect2.bottom > height:
        speed0[1] *= -1

    screen.fill(pyc.GRAY)
    pygame.draw.rect(screen,pyc.GREEN, rect1)
    pygame.draw.ellipse(screen,pyc.BLUE,rect2)
    pygame.display.flip()


pygame.quit()

스피드 백터의 설정값에 따라 한번의 이동에 x축이 더 많이 움직이기도 y축이 많이 움직이기도 한다. 도형은 윈도우의 테두리에 부딪히면 방향을 바꾼다. (-로 반전한다) 방향이 틀리면 도형들을 영영 잃어버릴 수도 있다. 무한루프로 돌기 때문에 날아가면 무한대 연산만 하다가 오류로 종료될 것이다.

 

지난 포스트에서도 이야기 했지만 그냥 실행하면 속도가 무척 빠르다. 어느정도 스피드를 맞춰준다. Clock 객체로 FPS 60 정도 맞추면 저정도 부드러울 것이다. 여기서 속도를 올리고 싶으면 speed 벡터 값을 조정한다. 너무 빨리 움직이게 해도 모니터에 잔상만 남는다.

 

그리는 메소드는 draw.rect와 draw.ellipse 인데 형식은 똑같다. Rect 객체만 있으면 동일한 방식으로 움직이는게 가능하다. display.flip() 은 display.update() 와 비슷한 기능이다. 메모리에 그린 도형들을 화면에 옮겨준다.

 

if문에서 어떻게 도형이 윈도우 창에서 빠져나가지 못하게 막았는지 잘 살펴본다. 창을 못 빠져나가고 무한루프를 돌으니까 그냥 놔두면 무한히 움직인다.

 

2. 움직이는 이미지(볼)

움직이는 볼의 원리도 사각형을 취급하는 것과 똑같다. 아래 예제는 Pygame 의 개발자 Pete 의 예제에서 배경색상을 조금 변형했다. 볼의 이미지는 png 파일이다. 소스코드를 보면서 설명한다.

 

움직이는 볼

앞쪽은 딱히 볼게 없다. 키보드 조작에 따른 색상변화를 주기 위한 코드다. myball 변수를 보자. pygame 모듈에서 image를 load 한다. ball.gif(위에 png 그림) 이 파일을 잡아서 Surface 객체로 리턴한다. (Surface 객체는 파이게임 창을 오픈할때 Screen을 표시하는 객체로 쓴다.) 다시 Surface 객체의 메소드로 Rect 의 인스턴스를 반환한다.

 

스피드는 1번 도형처럼 벡터이다. (x,y) 

import pygame as pyg
import sys
from pygame.locals import *

size = width, height = 700, 350

BLACK = (0,0,0)
WHITE = (255,255,255)

RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

YELLOW = (255, 255, 0)

C1_BLUE = (204, 204, 255) # Custom blue color 1

key_dict = {K_k:BLACK, K_r:RED, K_g:GREEN,K_b:BLUE,K_y:YELLOW,K_w:WHITE}

myball = pyg.image.load("ball.gif")
rect = myball.get_rect()
speed = [2,5]


screen = pyg.display.set_mode(size)
bgColor = C1_BLUE
caption = 'BG Color : ' + str(bgColor)
pyg.display.set_caption(caption)
screen.fill(bgColor)
pyg.display.update()

pyg.init()


clock = pyg.time.Clock()

running = True
while running:
    clock.tick(60)

    for pyEvent in pyg.event.get():
        if pyEvent.type == QUIT:
            running = False
        if pyEvent.type == KEYDOWN:
            if pyEvent.key in key_dict:
                bgColor = key_dict[pyEvent.key]
                caption = 'BG Color : ' + str(bgColor)
                pyg.display.set_caption(caption)
            else:
                bgColor = C1_BLUE

    rect = rect.move(speed)
    if rect.left < 0 or rect.right > width:
        speed[0] = -speed[0]
    if rect.top < 0 or rect.bottom > height:
        speed[1] = -speed[1]
    screen.fill(bgColor)
    pyg.draw.rect(screen,BLACK,rect,1)
    screen.blit(myball,rect)
    pyg.display.flip()

pyg.quit()

 

마지막 부분을 보면 rect 인스턴스로 어떻게 이미지를 이동하는지 나와있다. if문은 윈도우 창틀에 닫았을 때의 행동이다. 방향을 반전시킨다.

 

먼저 배경색을 채우고, 사각형을 그린다. 보더를 1로 잡으면 얇은 실선의 사각형을 그린다. 다음 문장인 screen.blit 에서 이미지를 그린다. Surface 인스턴스 하나와 rect (사각형 좌표)를 인자로 그릴 수 있다.

 

한줄위의 draw.rect나 blit 이나 어느 한쪽을 안그려도 작동을 한다. 여기서 둘을 붙이는 것은 사각형을 다루는 것 처럼 이미지를 사용할 수 있기 때문이다. Rect의 속성들을 사용하면 도형의 꼭지점과 중심이 어디인지 바로 파악이 된다. 윈도우창에 도착했을 때 Rect의 속성들로 검사할 수 있기 때문이다.

 

또 이미지의 충돌관련 사항들을 파악하기 위해서 사각형의 영역을 활용할 수도 있다. Rect 객체를 활용하여 게임 알고리즘을 만들수 있다.

 

rect = rect.move(speed)
    if rect.left < 0 or rect.right > width:
        speed[0] = -speed[0]
    if rect.top < 0 or rect.bottom > height:
        speed[1] = -speed[1]
    screen.fill(bgColor)
    pyg.draw.rect(screen,BLACK,rect,1)
    screen.blit(myball,rect)
    pyg.display.flip()

 

Rect 객체와 이미지를 연결시켜 사용하는 방법을 알았으니 다음 포스트에는 이미지에 대한 내용을 업데이트 할 예정이다.

공유하기

facebook twitter kakaoTalk kakaostory naver band