로그인 등에서 서버로부터 전달받은 쿠키를 유지해야하는 경우, requests 모듈을 사용하는 것이 낫다.


사전 설치 요구사항


requests 모듈 사용시, 추가적인 requests 모듈 설치를 필요로 한다.

pip install requests


기본 HTTP 요청

import requests
 
r = requests.get('http://httpbin.org/ip') 

print(r.text)
print(r.status_code)
 
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('http://httpbin.org/get', params=payload)
 
print(r.url)
print(r.text)
print(r.status_code)
  • https 접속을 위해서는 url 안에 직접 ’https://~’와 같은 형식으로 입력하면 된다.
  • 특정 포트 지정시는 아래와 같이 사용한다.
  • r = requests.get('http://httpbin.org:8080/ip') 
    


POST 요청

import requests

r = requests.post('http://httpbin.org/post', data = {'key':'value'})

print(r.text)
print(r.status_code)


헤더 추가

import requests
 
url = 'http://httpbin.org/get'
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get(url, headers=headers)


참고 사이트


<테스트 환경>
 - OS : Windows 7
 - Python 버전 : 2.7
,


기본 HTTP 요청하기

import httplib

conn = httplib.HTTPConnection("httpbin.org")

conn.request("GET", "/ip")
r1 = conn.getresponse()
print r1.status, r1.reason
data1 = r1.read()
print data1

conn.request("GET", "/get")
r2 = conn.getresponse()
print r2.status, r2.reason
data2 = r2.read()
print data2

conn.close()
  • https 접속을 하려면, httplib.HTTPConnection 대신에 httplib.HTTPSConnection을 사용한다.

> conn = httplib.HTTPSConnection("httpbin.org")

  • 특정 포트 지정시는 아래와 같은 방법 중 한가지를 사용한다.

> conn = httplib.HTTPConnection("httpbin.org:80")

> conn = httplib.HTTPConnection("httpbin.org", 80)


POST 요청하기

import httplib, urllib

conn = httplib.HTTPConnection("httpbin.org")

params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
headers = {"Content-type": "application/x-www-form-urlencoded",
           "Accept": "text/plain"}
conn.request("POST", "/post", params, headers)
response = conn.getresponse()
print response.status, response.reason
data = response.read()
print data

params = "test string"
headers = {"Content-type": "text/html"}
conn.request("POST", "/post", params, headers)
response = conn.getresponse()
print response.status, response.reason
data = response.read()
print data

conn.close()


참고 사이트

  • http://httpbin.org : 각종 HTTP 요청들에 대한 응답을 테스트할 수 있는 사이트


<테스트 환경>

 - OS : Windows 7
 - Python 버전 : 2.7


,


PIP는 파이썬으로 작성된 패키지 소프트웨어를 설치, 관리하는 패키지 관리 시스템이다. 파이썬 2.7.9 이후 버전과 파이썬 3.4 이후 버전은 pip를 기본적으로 포함한다.



사전 준비사항


1) 파이썬 2.7.9 혹은 3.4 이후 버전


기본적으로 pip가 포함되어 있지만, 파이썬 실행 파일과 경로가 다르기 때문에 <파이썬 설치 경로>/scripts를 PATH 환경 변수에 추가해야 한다.


2) 파이썬 2.7.9 혹은 3.4 이전 버전


아래 PIP 사이트에서 get-pip.py 파일을 받아 실행하면 설치할 수 있다. 설치 후 역시 PATH 환경 변수에 추가가 필요하다.


 - https://pip.pypa.io/en/stable/installing/


python get-pip.py





사용 방법


1) 패키지 설치


pip install some-package-name


2) 패키지 제거


pip uninstall some-package-name



,

Python에서 한글로 된 주석 및 코드를 사용하기 위해서는 소스 앞부분에 다음과 같이 인코딩 방식을 지정하여야 한다.


1. 완성형

# -*- coding: euckr -*-


2. 확장 완성형 (윈도우)

# -*- coding: cp949 -*-


3. UTF-8

# -*- coding: utf-8 -*-


일단, 여기까지만 하면 위 세가지 인코딩 방식에 대해서 한글로 된 주석을 사용할 수 있다.


주석이 아닌 실제 문자열 변수에 한글 문자열 상수를 대입하는 것과 같이 소스 코드 내에서 사용하는 경우, ANSI 계열(완성형, 확장완성형)에서는 위와 같이 지정만해도 문제없이 사용이 가능하다.


하지만 UTF-8의 경우, 이와 같은 지정만으로는 제대로 되지 않는데, 파이썬이 기본적으로 문자열 상수를 ANSI로 받아들이려 하기 때문이다.

이런 문제를 해결하는 방법 중 한가지는 문자열 상수 사용시에 u를 따옴표 앞에 붙이는 것이다.

str = "한글 포함 상수"

대신에

str = u"한글 포함 상수"

를 사용한다


이 방법은 ANSI 계열에 사용했을 때도 역시 정상 동작한다.


<테스트 환경>
OS : Windows 7
Python 버전 : 2.7


,

버튼을 누르면 특정 프로그램이 실행되는 Launcher 어플의 Template입니다.


# -*- coding: utf-8 -*-
#!/usr/bin/python

import wx
import subprocess

BUTTON_ID_1 = 101
BUTTON_ID_2 = 102
BUTTON_ID_3 = 103
BUTTON_ID_4 = 104

COMMAND_PATH_1 = "" # 첫번째 버튼으로 실행할 실행파일 경로 예) "C:\\Windows\\explorer.exe"
COMMAND_PATH_2 = "" # 두번째 버튼으로 실행할 실행파일 경로
COMMAND_PATH_3 = "" # 세번째 버튼으로 실행할 실행파일 경로
COMMAND_PATH_4 = "" # 네번째 버튼으로 실행할 실행파일 경로

COMMAND_PARAM_1 = "" # 첫번째 버튼으로 실행할 실행파일 파라미터
COMMAND_PARAM_2 = "" # 두번째 버튼으로 실행할 실행파일 파라미터
COMMAND_PARAM_3 = "" # 세번째 버튼으로 실행할 실행파일 파라미터
COMMAND_PARAM_4 = "" # 네번째 버튼으로 실행할 실행파일 파라미터

def ShellExecute(path, param="", cwd=None, nonExecutable = False):
    # path  : 실행 파일 경로
    # param : 파라미터
    # cwd   : 현재 디렉토리
    # nonExecutable : True일 경우, 실행 파일이 아니어도 연결 프로그램으로 실행 가능
    try:
        if param == "":
            subprocess.Popen([path], cwd = cwd, shell=nonExecutable)
        else:
            subprocess.Popen([path, param], cwd = cwd, shell=nonExecutable)
    except OSError:
        wx.MessageBox(u"Launch Failed!", u"Info")

class MainWindow(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size = (320, 240),
            style = wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
            
        vbox = wx.BoxSizer(wx.VERTICAL)

        button = wx.Button(self, id = BUTTON_ID_1, label = u"Button 1", size = (-1, 50))
        vbox.Add(button, 0, wx.EXPAND | wx.ALL)
        self.Bind(wx.EVT_BUTTON, self.OnButton, button)
        
        button = wx.Button(self, id = BUTTON_ID_2, label = u"Button 2", size = (-1, 50))
        vbox.Add(button, 0, wx.EXPAND | wx.ALL)
        self.Bind(wx.EVT_BUTTON, self.OnButton, button)

        button = wx.Button(self, id = BUTTON_ID_3, label = u"Button 3", size = (-1, 50))
        vbox.Add(button, 0, wx.EXPAND | wx.ALL)
        self.Bind(wx.EVT_BUTTON, self.OnButton, button)

        button = wx.Button(self, id = BUTTON_ID_4, label = u"Button 4", size = (-1, 50))
        vbox.Add(button, 0, wx.EXPAND | wx.ALL)
        self.Bind(wx.EVT_BUTTON, self.OnButton, button)

        self.SetSizer(vbox, True)
        self.Layout()
        
    def OnButton(self, event):
        buttonId = event.GetId()
        
        if buttonId == BUTTON_ID_1:
            ShellExecute(COMMAND_PATH_1, COMMAND_PARAM_1)
        if buttonId == BUTTON_ID_2:
            ShellExecute(COMMAND_PATH_2, COMMAND_PARAM_2)
        if buttonId == BUTTON_ID_3:
            ShellExecute(COMMAND_PATH_3, COMMAND_PARAM_3)
        if buttonId == BUTTON_ID_4:
            ShellExecute(COMMAND_PATH_4, COMMAND_PARAM_4)

            
app = wx.App(False)
frame = MainWindow(None, -1, u"Title")
frame.Show(1)
app.MainLoop()




<테스트 환경>
OS : Windows 7
Python 버전 : 2.7
wxPython 버전 : 2.8.12.1


,


PyOpenGL

Python용 OpenGL 라이브러리.


http://pyopengl.sourceforge.net/



PGU

pyGame과 함께 쓰일 수 있는 확장 라이브러리. 타일 에디터/엔진(tile/isometric/hexagonal), 레벨 에디터, 확장된 GUI/HTML 렌더링/텍스트 렌더링, 상태 엔진 등을 제공


https://code.google.com/p/pgu/



Soya3D

Python용 high-level 3D 엔진.


http://home.gna.org/oomadness/en/soya3d/



,


Sprite를 사용하면 이미지, 위치, 충돌 처리를 통합해서 처리할 수 있습니다.


Sprite를 단독으로 사용하는 경우

# 스프라이트 클래스 정의
class SimpleSprite(pygame.sprite.Sprite):

    def __init__(self, image, position): # 생성자 파라미터로 스프라이트에 사용될 이미지 경로와 스프라이트 초기 위치를 받는다
        pygame.sprite.Sprite.__init__(self)
        self.user_src_image = pygame.image.load(image) # 스프라이트에 사용될 이미지를 저장할 사용자 변수
        self.user_position = position # 스프라이트의 위치를 저장할 사용자 변수
        self.user_rotation = 30 # 스프라이트의 회전 각도를 저장할 사용자 변수

    def update(self): # 스프라이트의 상태를 업데이트 하는 함수. 필요에 따라 파라미터가 추가될 수도 있다.

        # 여기에 게임 상태에 따라 스프라이트의 위치(user_position), 회전 각도(user_rotation), 이미지(user_src_image)를 변경시키는 코드가 들어가야 한다.
        # {{
        # ...
        # }}

        # 출력에 사용될 이미지, 위치를 정한다
        self.image = pygame.transform.rotate(self.user_src_image, self.user_rotation) # 이미지를 회전 각도 만큼 회전시킨다
        self.rect = self.image.get_rect()
        self.rect.center = self.user_position # 이미지의 출력 위치를 정한다

...

# 초기화시 해야할 부분
simple = SimpleSprite('simple.png', (100, 100))
simple_group = pygame.sprite.RenderPlain(simple)

# -> RenderPlain 클래스는 여러개의 스프라이트를 묶어주는 역활을 하며,
# 상태 업데이트나 화면에 그릴 때에 RenderPlain 클래스를 통해서 하게된다.

...

# 게임 상태 업데이트시 해야할 부분
simple_group.update() # RenderPlain 객체를 통해 업데이트한다

...

# 게임 상태 화면에 출력시 해야할 부분
simple_group.draw(screen) # RenderPlain 객체를 통해 출력한다




Sprite를 그룹으로 사용하는 경우

# 스프라이트 클래스 정의
class SimpleSprite(pygame.sprite.Sprite):

    def __init__(self, image, position): # 생성자 파라미터로 스프라이트에 사용될 이미지 경로와 스프라이트 초기 위치를 받는다
        pygame.sprite.Sprite.__init__(self)
        self.user_src_image = pygame.image.load(image) # 스프라이트에 사용될 이미지를 저장할 사용자 변수
        self.user_position = position # 스프라이트의 위치를 저장할 사용자 변수
        self.user_rotation = 30 # 스프라이트의 회전 각도를 저장할 사용자 변수

    def update(self): # 스프라이트의 상태를 업데이트 하는 함수. 필요에 따라 파라미터가 추가될 수도 있다.

        # 여기에 게임 상태에 따라 스프라이트의 위치(user_position), 회전 각도(user_rotation), 이미지(user_src_image)를 변경시키는 코드가 들어가야 한다.
        # {{
        # ...
        # }}

        # 출력에 사용될 이미지, 위치를 정한다
        self.image = pygame.transform.rotate(self.user_src_image, self.user_rotation) # 이미지를 회전 각도 만큼 회전시킨다
        self.rect = self.image.get_rect()
        self.rect.center = self.user_position # 이미지의 출력 위치를 정한다

...

# 초기화시 해야할 부분
multiple = [
         SimpleSprite('simple.png', (100, 100)),
         SimpleSprite('simple.png', (100, 200)),
         SimpleSprite('simple.png', (100, 300))
]
multiple_group = pygame.sprite.RenderPlain(*multiple) # 그룹으로 사용시 * 연산자가 들어가야 한다

# -> RenderPlain 클래스는 여러개의 스프라이트를 묶어주는 역활을 하며,
# 상태 업데이트나 화면에 그릴 때에 RenderPlain 클래스를 통해서 하게된다.

...

# 게임 상태 업데이트시 해야할 부분
multiple_group.update() # RenderPlain 객체를 통해 업데이트한다

...

# 게임 상태 화면에 출력시 해야할 부분
multiple_group.draw(screen) # RenderPlain 객체를 통해 출력한다




Sprite와 Sprite 그룹 사이의 충돌 체크

class BlockSprite(pygame.sprite.Sprite):

    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
        self.user_image_normal = pygame.image.load("block_normal.png"); # 보통 상태에서 표시할 이미지를 로딩
        self.user_image_hit = pygame.image.load("block_hit.png"); # 충돌시에 표시할 이미지를 로딩
        self.user_position = position;

        # 충돌을 체크하는 spritecollide 함수 호출시 rect 정보가 사용되는데
        # udpate가 spritecollide 이후에 호출되기 때문에 생성자에서 rect 초기값을 설정하여야 한다.
        self.image = self.user_image_normal
        self.rect = self.image.get_rect()
        self.rect.center = self.user_position

    def update(self, hit_list): # 충돌된 객체 리스트를 파라미터로 추가한다

        if self in hit_list: # 자기 자신의 리스트에 포함 여부에 따라 상태 업데이트를 한다
            self.image = self.user_image_hit # 이미지를 충돌 상태 이미지로 설정
        else:
            self.image = self.user_image_normal # 이미지를 보통 상태 이미지로 설정

        self.rect = self.image.get_rect()
        self.rect.center = self.user_position

...

blocks = [
         BlockSprite((100, 100)),
         BlockSprite((100, 200)),
         BlockSprite((100, 300))
]
block_group = pygame.sprite.RenderPlain(*blocks)

...

collisions = pygame.sprite.spritecollide(simple, block_group, False)
# 첫번째 파라미터로 단일 스프라이트 객체가, 두번째 파라미터로 스프라이트의 그룹 객체가 온다.
# 두번째 파라미터의 스프라이트 그룹에 포함된 객체 중에서 첫번째 파라미터의 객체와 충돌하는
# 객체의 리스트를 반환한다.
# 세번째 파라미터는 스프라이트 그룹내 충돌된 스프라이트의 자동 제거 여부로,
# True로 할 경우, 충돌 발생시 바로 그룹에서 제거된다.

block_group.update(collisions) # 충돌된 객체 리스트를 스프라이트 객체로 넘겨서 처리한다.

...

block_group.draw(screen)




Sprite 객체 외부에서 충돌 처리


다른 스프라이트 객체를 참조하거나 전체 스프라이트에 공통으로 처리해야하는 경우, 다음과 같은 방법으로 스프라이트 객체 외부에서 처리할 수 있다.

collisions = pygame.sprite.spritecollide(simple, block_group, False)
if collisions:
    for block in block_group.sprites():
        block.image = block.user_image_hit # 그룹내 모든 스프라이트의 이미지를 바꾼다




배경 이미지 사용시

배경 이미지 사용시, 매번 전체 이미지를 blit하지않고, 다음과 같은 방법으로 Sprite에 해당하는 영역만 효율적으로 복원할 수 있다.

# 메인 루프 바깥에서 배경 이미지를 출력
background = pygame.image.load('background.png')
screen.blit(background, (0,0))

...

# 메인 루프 안에서 Sprite 영역만 복원해줌. (기존에 screen.fill(...) 호출하던 부분)
simple_group.clear(screen, background)
block_group.clear(screen, background)




종합 예제


플레이어를 이동시켜 장애물에 충돌시켜 볼 수 있는 예제 소스이다.

다음의 이미지 파일들이 소스와 같은 경로에 있어야 한다.


simple.png : 플레이어 이미지

block_normal.png : 장애물 이미지 (보통 상태)

block_hit.png : 장애물 이미지 (충돌 상태)

background.png : 배경 이미지


# -*- coding: utf-8 -*-

import math, sys
import pygame
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode((1024, 768), DOUBLEBUF)
clock = pygame.time.Clock()

class SimpleSprite(pygame.sprite.Sprite):

    def __init__(self, image, position):
        pygame.sprite.Sprite.__init__(self)
        self.user_src_image = pygame.image.load(image)
        self.user_position = position
        self.user_rotation = 30
        self.user_speed = 0
        self.user_rotation_speed = 0

    def update(self, deltat):
        # 속도, 회전 속도에 따라 위치 정보를 업데이트한다
        self.user_rotation += self.user_rotation_speed
        x, y = self.user_position
        rad = self.user_rotation * math.pi / 180
        x += -self.user_speed * math.sin(rad)
        y += -self.user_speed * math.cos(rad)
        self.user_position = (x, y)

        self.image = pygame.transform.rotate(self.user_src_image, self.user_rotation)
        self.rect = self.image.get_rect()
        self.rect.center = self.user_position

class BlockSprite(pygame.sprite.Sprite):

    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
        self.user_image_normal = pygame.image.load("block_normal.png");
        self.user_image_hit = pygame.image.load("block_hit.png");
        self.user_position = position;

        self.image = self.user_image_normal
        self.rect = self.image.get_rect()
        self.rect.center = self.user_position

    def update(self, hit_list):
       
        if self in hit_list:
            self.image = self.user_image_hit
        else:
            self.image = self.user_image_normal

        self.rect = self.image.get_rect()
        self.rect.center = self.user_position

rect = screen.get_rect()
simple = SimpleSprite('simple.png', rect.center)
simple_group = pygame.sprite.RenderPlain(simple)

blocks = [
    BlockSprite((200, 200)),
    BlockSprite((800, 200)),
    BlockSprite((200, 600)),
    BlockSprite((800, 600))
]
block_group = pygame.sprite.RenderPlain(*blocks)

background = pygame.image.load('background.png')
screen.blit(background, (0,0))

while True:
    deltat = clock.tick(30)
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

        # 키입력에 따라 속도, 회전 속도를 설정
        if hasattr(event, 'key'):
            down = event.type == KEYDOWN
            if event.key == K_RIGHT:
                simple.user_rotation_speed = down * -5 # 시계 방향이 마이너스인 것에 유의
            elif event.key == K_LEFT:
                simple.user_rotation_speed = down * 5
            elif event.key == K_UP:
                simple.user_speed = down * 10
            elif event.key == K_DOWN:
                simple.user_speed = down * -10

    simple_group.update(deltat)

    collisions = pygame.sprite.spritecollide(simple, block_group, False)
    block_group.update(collisions)

    simple_group.clear(screen, background)
    block_group.clear(screen, background)
    simple_group.draw(screen)
    block_group.draw(screen)
    pygame.display.flip()




<테스트 환경>
OS : Windows 7
Python 버전 : 2.7
pyGame 버전 : 1.9.1


,

Python에서 게임 제작에 사용할 수 있는 pyGame 라이브러리 기본 기능에 대해 긴 설명없이 빠르게 훓어볼 수 있도록 정리해보았습니다.


우선 Python에서 UTF-8 한글로 된 주석을 사용하기 위해서는 소스 앞부분에 다음 구문을 추가하여야 한다

# -*- coding: utf-8 -*-


->



모듈 import

import pygame                   # pygame 모듈을 import
from pygame.locals import *     # pygame.locals 하위 모듈을 import


pyGame 라이브러리 초기화

라이브러리 초기화를 하지 않을 경우, 일부 기능이 정상 동작하지 않을 수 있다.

pygame.init()


디스플레이 초기화

# 1) 화면 해상도를 480*320으로 초기화. 윈도우 모드, 더블 버퍼 모드로 초기화하는 경우
screen = pygame.display.set_mode((480, 320), DOUBLEBUF)
pygame.display.set_caption('Hello World!')  # 타이틀바의 텍스트를 설정

# 2) 화면 해상도를 480*320, 전체 화면 모드, 하드웨어 가속 사용, 더블 버퍼 모드로 초기화하는 경우
screen = pygame.display.set_mode((480, 320), FULLSCREEN | HWSURFACE | DOUBLEBUF)


두번째 파라미터는 다음과 같은 flag들을 | 연산자로 조합하여 사용할 수 있다.


FULLSCREEN : 전체 화면 모드를 사용
HWSURFACE : 하드웨어 가속 사용. 전체 화면 모드에서만 가능
OPENGL : OpenGL 사용 가능한 디스플레이를 초기화
DOUBLEBUF : 더블 버퍼 모드를 사용. HWSURFACE or OPENGL에서 사용을 추천



메인 루프

pyGame의 메인 루프는 아래와 같이 크게 세 부분으로 나뉘어진다.

while True:
  for event in pygame.event.get():
      # 이벤트를 처리하는 부분 -> 키보드, 마우스 등의 이벤트 처리 코드가 들어감
      ...

  # 게임의 상태를 업데이트하는 부분
  ...

  # 게임의 상태를 화면에 그려주는 부분 -> 화면을 지우고, 그리고, 업데이트하는 코드가 들어감
  ...


종료 이벤트 처리

import sys


# 윈도우의 닫기 버튼이 눌렸을 때, 프로그램을 종료하도록 처리
for event in pygame.event.get():
  if event.type == QUIT:
    pygame.quit()
    sys.exit()


키 이벤트 처리

for event in pygame.event.get():
  if not hasattr(event, 'key'):                    # 키 관련 이벤트가 아닐 경우, 건너뛰도록 처리하는 부분
    continue
  if event.type == KEYDOWN:
    if event.key == K_RIGHT:
      # 오른쪽 키에 대한 처리
      ...
    elif event.key == K_LEFT:
      # 왼쪽 키에 대한 처리
      ...
    elif event.key == K_UP:
      # 위쪽 키에 대한 처리
      ...
    elif event.key == K_DOWN:
      # 아래 키에 대한 처리
      ...
    elif event.key == K_ESCAPE:
      # ESC 키에 대한 처리
      ...


마우스 이벤트 처리

LEFT = 1  # 왼쪽 버튼에 대한 버튼 인덱스
RIGHT = 3  # 오른쪽 버튼에 대한 버튼 인덱스

if event.type == MOUSEBUTTONDOWN and event.button == LEFT:
  # 왼쪽 버튼이 눌렸을 때의 처리
  print "left mouse up (%d, %d)" % event.pos
elif event.type == MOUSEBUTTONUP and event.button == LEFT:
  # 왼쪽 버튼이 떨어졌을 때의 처리
  print "left mouse down (%d, %d)" % event.pos
elif event.type == pygame.MOUSEMOTION:
  # 마우스 이동시의 처리
  print "mouse move (%d, %d)" % event.pos


색 정의

BLACK = (0, 0, 0)  # R, G, B
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
BLUE_A = (0, 0, 255, 127)  # R, G, B, Alpha(투명도, 255 : 완전 불투명)


사각형 정의

rectangle = (0, 10, 100, 100)  # 왼쪽 X, 위 Y, 너비, 높이


화면의 업데이트

# 전체 화면을 업데이트할 경우
pygame.display.flip()                           # 화면 전체를 업데이트

# 화면의 일부만 업데이트할 경우
pygame.display.update(rectangle)                # 업데이트할 rectangle을 지정
pygame.display.update(rectangle_list)           # 업데이트할 rectangle을 여러개 지정


프레임 수 맞추기

메인 루프 안에서 FPS(초당 프레임수)를 맞추기 위한 딜레이를 추가해주는 코드. 파라미터로 딜레이 시간이 아닌 목표로 하는 FPS 값이 들어간다.

TARGET_FPS = 30
clock = pygame.time.Clock()

while True:
  ...

  clock.tick(TARGET_FPS)  # 30 FPS를 맞추기 위한 딜레이를 추가


화면 지우기

# 화면을 그리기에 앞서 지우기 위해 호출한다

screen.fill(BLACK)


기본 도형 그리기

# 네 점을 지나는 폴리곤을 그린다
pygame.draw.polygon(screen, RED, ((10, 10), (20, 10), (30, 20), (10, 20)))     

# 두 점을 지나는 선을 그린다
pygame.draw.line(screen, BLUE, (10, 10), (20, 20))                             

# 사각형을 그린다 (왼쪽, 위, 너비, 높이 순)
pygame.draw.rect(screen, RED, (10, 10, 100, 50))                               

# (100, 100)을 중심으로 하는 반지름 10인 원을 그린다
pygame.draw.circle(screen, BLUE, (100, 100), 10)                               

# 사각형 안을 지나는 타원을 그린다
pygame.draw.ellipse(screen, RED, (10, 10, 100, 50))                            

# 두 점을 지나는 두께 4의 선을 그린다 (모든 그리기 함수에 두께가 추가될 수 있다)
pygame.draw.line(screen, BLUE, (10, 10), (20, 20), 4)                          


점 찍기

pixelArray = pygame.PixelArray(screen)
pixelArray[10][100] = RED
pixelArray[50][100] = BLUE
del pixelArray  # 사용 후, 반드시 PixelArray를 del해줘야 Surface가 lock되는 것을 방지할 수 있다


이미지 파일 다루기

# 이미지 파일 그리기
img = pygame.image.load('image.jpg')
screen.blit(img, (50, 100))             # 지정한 좌표가 이미지의 왼쪽 위에 위치하도록 출력된다

# 이미지 파일 회전하여 그리기
img = pygame.image.load('image.jpg')
x = 100
y = 100
degree = 45                             # 회전할 각도를 도(degree) 단위로 지정
rotated = pygame.transform.rotate(img, degree)
rect = rotated.get_rect()
rect.center = (x, y)                    # 지정한 좌표가 이미지의 중심에 오도록 출력된다
screen.blit(rotated, rect)


투명도 처리

pygame.display.set_mode()로 얻어진 기본 Surface에 출력할 경우 투명도는 적용되지 않기 때문에, 아래와 같이 별도의 Surface를 생성하여 처리하여야 한다.

t_surface = screen.convert_alpha()              # 기본 Surface(screen)로부터 투명도 처리를 위한 Surface 생성

...


t_surface.fill((0, 0, 0, 0))                    # t_surface 전체를 투명한 검정색으로 지운다

pygame.draw.rect(t_surface, (0, 0, 255, 127), (30, 30, 40, 40))  # t_surface에 투명도를 적용하여 그려줌
screen.blit(t_surface, (0, 0))                  # t_surface를 기본 Surface에 blit


텍스트 출력하기

fontObj = pygame.font.Font('myfont.ttf', 32)                  # 현재 디렉토리로부터 myfont.ttf 폰트 파일을 로딩한다. 텍스트 크기를 32로 한다
textSurfaceObj = fontObj.render('Hello Font!', True, GREEN)   # 텍스트 객체를 생성한다. 첫번째 파라미터는 텍스트 내용, 두번째는 Anti-aliasing 사용 여부, 세번째는 텍스트 컬러를 나타낸다
textRectObj = textSurfaceObj.get_rect();                      # 텍스트 객체의 출력 위치를 가져온다
textRectObj.center = (150, 150)                               # 텍스트 객체의 출력 중심 좌표를 설정한다
screen.blit(textSurfaceObj, textRectObj)                      # 설정한 위치에 텍스트 객체를 출력한다


# Font 객체 생성의 다른 예
fontObj = pygame.font.Font(None, 32)                                    # 폰트 파일에 None을 지정할 경우 기본 폰트가 사용된다
fontObj = pygame.font.Font('C:\\Windows\\Fonts\\tahoma.ttf', 32)        # 윈도우 경로에 있는 폰트를 사용할 경우

# render 함수 사용의 다른 예
textSurfaceObj = fontObj.render('Hello font!', True, GREEN, BLUE)       # 텍스트 색을 녹색, 배경색을 파란색으로 설정한다


사운드 출력하기

Wav, Ogg 형식의 사운드 파일을 지원한다.

soundObj = pygame.mixer.Sound('beeps.wav')              # 사운드 파일을 로딩한다
soundObj.play()                                         # 사운드 파일을 플레이한다 (플레이가 끝나는 것을 기다리지 않고 바로 리턴된다)


# 5초 후에 플레이를 정지하는 경우
import time

soundObj.play()
time.sleep(5)
soundObj.stop()


# 반복해서 플레이하는 경우 (BGM)
pygame.mixer.music.load('background.mp3')
pygame.mixer.music.play(-1, 0, 0)



종합 예제

# -*- coding: utf-8 -*-

import sys
import pygame
from pygame.locals import *

# 초당 프레임수를 정의
TARGET_FPS = 30

clock = pygame.time.Clock()


# 색 정의
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)


# 마우스 버튼 인덱스 정의
LEFT = 1  # 왼쪽 버튼에 대한 버튼 인덱스
RIGHT = 3  # 오른쪽 버튼에 대한 버튼 인덱스

# 라이브러리 및 디스플레이 초기화
pygame.init()
screen = pygame.display.set_mode((480, 320), DOUBLEBUF)

# 이미지 파일을 로딩
img = pygame.image.load('image.jpg')

# 폰트 로딩 및 텍스트 객체 초기화
fontObj = pygame.font.Font('myfont.ttf', 32)
textSurfaceObj = fontObj.render('Hello Font!', True, GREEN)
textRectObj = textSurfaceObj.get_rect();
textRectObj.center = (150, 200)

# 사운드 파일을 로딩
soundObj = pygame.mixer.Sound('beeps.wav')

# 메인 루프
while True:
  for event in pygame.event.get():
    # 이벤트를 처리하는 부분
    if event.type == QUIT:
      pygame.quit()
      sys.exit()


    # 키보드 이벤트 처리
    if event.type == KEYDOWN:
      if event.key == K_RIGHT:
        # 오른쪽 키가 눌리면 사운드를 플레이한다
        soundObj.play()


    # 마우스 이벤트 처리
    if event.type == MOUSEBUTTONDOWN and event.button == LEFT:
      # 왼쪽 버튼이 눌렸을 때의 처리
      print "left mouse up (%d, %d)" % event.pos
    elif event.type == MOUSEBUTTONUP and event.button == LEFT:
      # 왼쪽 버튼이 떨어졌을 때의 처리
      print "left mouse down (%d, %d)" % event.pos
    elif event.type == pygame.MOUSEMOTION:
      # 마우스 이동시의 처리
      print "mouse move (%d, %d)" % event.pos


  # 게임의 상태를 업데이트하는 부분

  # 게임의 상태를 화면에 그려주는 부분


  screen.fill(BLACK)  # 화면을 검은색으로 지운다

  pygame.draw.line(screen, GREEN, (10, 0), (20, 10))  # 두 점을 지나는 선을 그린다

  # 수동으로 점 찍기
  pixelArray = pygame.PixelArray(screen)
  pixelArray[5][5] = RED
  pixelArray[10][10] = RED
  del pixelArray

  # 이미지 파일 그리기
  screen.blit(img, (50, 100))
 
  # 이미지 파일 회전하여 그리기
  x = 200
  y = 100
  degree = 30
  rotated = pygame.transform.rotate(img, degree)
  rect = rotated.get_rect()
  rect.center = (x, y)
  screen.blit(rotated, rect)

  # 텍스트 오브젝트를 출력
  screen.blit(textSurfaceObj, textRectObj)

  pygame.display.flip()  # 화면 전체를 업데이트
  clock.tick(TARGET_FPS)  # 프레임 수 맞추기



<테스트 환경>
OS : Windows 7
Python 버전 : 2.7
pyGame 버전 : 1.9.1


,