앞서말했듯,파이게임은图形用户界面를기반으로한다。정확히는,파이게임은2D용입력,출력함수를사용하여2D图形用户界面를기반으로한다。어찌됐든、CUI환경에서만먹히는파이썬의Print함수나Input함수와는이별을해야한다。그렇다면,파이게임의어떤함수가打印/输入함수를대체하는가?우선,프로그래밍언어의기본형식과출력을배우는친숙한예제인“你好,世界!”프로젝트로되돌아가야한다.(이프로젝트는같은디렉토리에.ttf확장자를가지는폰트파일을필요로한다。)

../../../../_images/Basic-ouput-sourcecode1.png
 1import sys, pygame
 2pygame.init()
 3
 4size = width, height = 220, 140
 5speed = [2, 2]
 6black = 0, 0, 0
 7
 8screen = pygame.display.set_mode(size)
 9
10ball = pygame.image.load("Basic-ouput-sourcecode.png")
11ballrect = ball.get_rect()
12
13while True:
14    for event in pygame.event.get():
15        if event.type == pygame.QUIT: sys.exit()
16
17    ballrect = ballrect.move(speed)
18    if ballrect.left < 0 or ballrect.right > width:
19        speed[0] = -speed[0]
20    if ballrect.top < 0 or ballrect.bottom > height:
21        speed[1] = -speed[1]
22
23    screen.fill(black)
24    screen.blit(ball, ballrect)
25    pygame.display.flip()
../../../../_images/Bagic-ouput-result-screen1.png
 1import sys, pygame
 2pygame.init()
 3
 4size = width, height = 220, 140
 5speed = [2, 2]
 6black = 0, 0, 0
 7
 8screen = pygame.display.set_mode(size)
 9
10ball = pygame.image.load("Bagic-ouput-result-screen.png")
11ballrect = ball.get_rect()
12
13while True:
14    for event in pygame.event.get():
15        if event.type == pygame.QUIT: sys.exit()
16
17    ballrect = ballrect.move(speed)
18    if ballrect.left < 0 or ballrect.right > width:
19        speed[0] = -speed[0]
20    if ballrect.top < 0 or ballrect.bottom > height:
21        speed[1] = -speed[1]
22
23    screen.fill(black)
24    screen.blit(ball, ballrect)
25    pygame.display.flip()

(Hello World프로젝트의소스코드와실행결과)

1줄짜리打印(“Hello World!”)에비하면소스코드가꽤복잡하다.이것은图形用户界面환경에서텍스트는최소5개의구성성분(텍스트내용,폰트,크기,색상,좌표)를가지기때문이다。Gui환경에서텍스트는1개의구성성분(텍스트내용)만을가지므로,4개의구성성분이추가된셈이다。예외적으로,#7set_의(“Hello World Project”)함수는Print(“Hello World Project”)함수와동일한기능을한다。하지만,이함수속문자열은프로그램의윈도우캡션에고정된문자열이다.

우선,무언가를출력하기위해선소스코드가어떻게작성되어야하는지그형식을살펴보자.소스코드는4개의부분으로나눠질수있다.Header(#1-#2)、初始문(#3-#12)、Always문(#13-#20)、Event문(#16-#19)가그것이다。

标题에선,모듈들을导入하는작업이실행된다。여기에导入PYGAME,sys는항상필요하다。이프로젝트가파이게임프로젝트이며,사용자가프로그램을종료하고싶을때종료되어야하기때문에(실제로#19에서sys.Exit()가실행된다)추가적인설명이필요없는당연한문구이다。进口*는#17에서의退出같은유용한상수들을선언없이사용하기위해거의반필수적으로필요하다。

初始문(무한반복문이전의문장들)에선,전역변수가한번만초기화되거나몇몇함수가한번만호출된다。주로색상과같은전역변수들이가독성을높이기위해초기화된다.파이게임은여러가지색상을사용하는화려한图形用户界面임을까먹어선안된다。(게임이므로)하나의색상은R값,G값,B값3개의구성요소를가진다.그래서색상변수는红色=(255,0,0)와같이선언되어야한다。Pygame.init()과같은함수는나중에사용할함수를위해선가장앞서서호출되어야한다。(이외의함수들은나중에언급하겠다.)

一直都是문(무한반복문)에선,전역변수가계속업데이트되거나몇몇함수가계속호출된다。(물론,조건문이있는경우조건이맞을때만)pygame.display.update()라는함수는일반적으로다른변수/함수의처리가끝난이후에호출되는데,이함수는처리의결과물들을스크린(=모니터)에출력하는함수이기때문이다。이함수가Always문마지막에실행되지않으면,출력되는화면과게임내부데이터가서로일치하지않는문제가생길수있다。(이외의함수들은나중에언급하겠다.)

Event문(모든이벤트를체크하는반복문)에선,특정이벤트가발생하면이에대한처리가이루어진다。Get()함수는Always문에서발생한이벤트들의배열을반환한다。그리고이이벤트들은자동적으로발생시간순으로정렬된다.그러므로,For-in문을쓰면,Always문에서발생한모든이벤트들을순차적으로처리할수있다(이벤트기반)。예를들어서,#17-#19는退出라는이벤트를처리하고있다。이이벤트가트리거되면,파이게임이종료된이후시스템이종료되게된다.(이외의함수들은나중에언급하겠다.)

기본형식이고정되어있다고가정하면,이형식에일부함수들을적절히삽입하면“你好,世界!”가출력되게할수있다.첫째로,텍스트의폰트와크기가정해져야한다.字体(“HoonWhite CatR,ttf”,32)라는#9의함수는주어진이름의ttf파일로폰트를정하고크기(이경우32)도정한다。이함수의반환값은myTextFont라는객체에저장해두었다。그리고myTextFont객체의Render(“Hello World!”,真、红、绿)라는#10의함수의반환값을myText라는객체에저장해두었다。渲染함수는텍스트내용과색상을정할수있다。이경우,텍스트의색상은빨간색,텍스트가아닌구역의색상은초록색이된다.MyText객체의Get_Rect()라는#11의함수의반환값을myTextArea라는객체에저장해두는데,myTextArea는텍스트를출력하기위해할당된구역을의미한다。GET_RECT()라는함수는텍스트의폰트크기와텍스트의길이를고려하여적절한직사각형공간을반환한다。만약myTextArea라는객체의Center라는멤버변수를텍스트가화면정중앙에오게끔수정한다면,(第12位)텍스트의위치를화면정중앙으로오게알수있다。

하지만화면정중앙을어떻게알아낼수있을까?우선,화면의전체크기를정해야한다.#8의pygame.display.set_함수는캔버스(크기,색상,위치정보를가지는변수들이((640,480))함수가호출되면그려지는공간)를생성하고그크기를Display。更新으로고정시킨다640 x 480。그렇다면,화면의정중앙은(320,240)이다.화면의전체크기가확정된다면,약간의계산만하면모든종류의위치를결정할수있게된다.(2D图形用户界面이므로출력되는모든것은x,y성분을가진다)(오른쪽이x좌표가크고,아래쪽이y좌표가큼을헷갈리면안된다.앞서서말한함수들은모두初始문에실행되어야하는것들이다,왜나하면이정보들은프로그램도중업데이트가필요없기때문이다。

물론,Fill함수나Bit함수는함수의특성때문에Always문에실행된다.#14의Fill(白色)함수는캔버스를단색(하얀색)으로채우는기능을수행한다。#15의blit(我的文本,我的文本区域)는특정객체(我的文本)를특정위치(我的文本区域)에그리는기능을수행한다。Bit이Fill이후에수행되어야한다。모든것이캔버스에그려지고나면,캔버스의결과물은显示。更新함수가실행되면출력되게된다。

이것이20줄짜리소스코드를위한설명이었다。20줄짜리소스코드치곤작동원리를이해하는데시간이오래걸리는것같다。하지만,이소스코드에무언가를추가하거나수정하는것은그다지어렵지않을것이다.이소스코드의기본형식과출력을위한기본단계를이해했다면말이다.여기에처리로직을추가하는것은어떨까?다음프로젝트에서진행될것이다.

<참고코드>::

import pygame, sys #1
from pygame.locals import* #2

white = (255,255,255) #3
red = (255,0,0) #4
green = (0,255,0) #5
pygame.init() #6
pygame.display.set_caption("Hello World Project") #7
myScreen = pygame.display.set_mode((640, 480)) #8
myTextFont = pygame.font.Font("HoonWhitecatR.ttf", 32) #9
myText = myTextFont.render("Hello World!", True, red, green) #10
myTextArea = myText.get_rect() #11
myTextArea.center = (320, 240) #12

while True: #13
    myScreen.fill(white) #14
    myScreen.blit(myText, myTextArea) #15

    for event in pygame.event.get(): #16
        if event.type == QUIT: #17
            pygame.quit() #18
            sys.exit() #19

    pygame.display.update() #20



Edit on GitHub