diff --git a/docs/reST/index.rst b/docs/reST/index.rst index 8112c06df8..6b63b6e24c 100644 --- a/docs/reST/index.rst +++ b/docs/reST/index.rst @@ -8,8 +8,6 @@ Pygame-ce Front Page ref/* tutorials/en/* - tutorials/en/**/* - tutorials/ko/**/* tutorials/es/* c_api filepaths @@ -146,9 +144,6 @@ Tutorials :doc:`Display Modes ` Getting a display surface for the screen. -:doc:`한국어 튜토리얼 (Korean Tutorial) ` - 빨간블록 검은블록 - :doc:`Tutorial de Pygame - Ejemplo del Chimpancé, Línea Por Línea ` Los ejemplos de pygame incluyen un sencillo programa con un puño interactivo y un chimpancé. Está inspirado en el molesto banner de flash de principios de la década de 2000. diff --git a/docs/reST/tutorials/assets/AdvancedInputOutput1.webp b/docs/reST/tutorials/assets/AdvancedInputOutput1.webp deleted file mode 100644 index 9b210667f4..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedInputOutput1.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedInputOutput2.webp b/docs/reST/tutorials/assets/AdvancedInputOutput2.webp deleted file mode 100644 index 01279e5881..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedInputOutput2.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedInputOutput3.webp b/docs/reST/tutorials/assets/AdvancedInputOutput3.webp deleted file mode 100644 index d704c35466..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedInputOutput3.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedInputOutput4.webp b/docs/reST/tutorials/assets/AdvancedInputOutput4.webp deleted file mode 100644 index e8ac857332..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedInputOutput4.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedInputOutput5.gif b/docs/reST/tutorials/assets/AdvancedInputOutput5.gif deleted file mode 100644 index 5796b4e1b1..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedInputOutput5.gif and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedOutputAlpha1.webp b/docs/reST/tutorials/assets/AdvancedOutputAlpha1.webp deleted file mode 100644 index e32a382ffa..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedOutputAlpha1.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedOutputAlpha2.webp b/docs/reST/tutorials/assets/AdvancedOutputAlpha2.webp deleted file mode 100644 index f9046bf7d8..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedOutputAlpha2.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedOutputAlpha3.webp b/docs/reST/tutorials/assets/AdvancedOutputAlpha3.webp deleted file mode 100644 index 3b5d8d98c9..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedOutputAlpha3.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedOutputProcess1.webp b/docs/reST/tutorials/assets/AdvancedOutputProcess1.webp deleted file mode 100644 index d253e56bc3..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedOutputProcess1.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedOutputProcess2.webp b/docs/reST/tutorials/assets/AdvancedOutputProcess2.webp deleted file mode 100644 index 6a5c4c30d6..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedOutputProcess2.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedOutputProcess3.webp b/docs/reST/tutorials/assets/AdvancedOutputProcess3.webp deleted file mode 100644 index d533af256e..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedOutputProcess3.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedOutputProcess4.webp b/docs/reST/tutorials/assets/AdvancedOutputProcess4.webp deleted file mode 100644 index df70d6b788..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedOutputProcess4.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedOutputProcess5.webp b/docs/reST/tutorials/assets/AdvancedOutputProcess5.webp deleted file mode 100644 index dff9b625e4..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedOutputProcess5.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/AdvancedOutputProcess6.webp b/docs/reST/tutorials/assets/AdvancedOutputProcess6.webp deleted file mode 100644 index da4bb214bd..0000000000 Binary files a/docs/reST/tutorials/assets/AdvancedOutputProcess6.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/Bagic-INPUT-resultscreen.webp b/docs/reST/tutorials/assets/Bagic-INPUT-resultscreen.webp deleted file mode 100644 index dc13d3a319..0000000000 Binary files a/docs/reST/tutorials/assets/Bagic-INPUT-resultscreen.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/Bagic-INPUT-sourcecode.webp b/docs/reST/tutorials/assets/Bagic-INPUT-sourcecode.webp deleted file mode 100644 index 3b9923b76c..0000000000 Binary files a/docs/reST/tutorials/assets/Bagic-INPUT-sourcecode.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/Bagic-PROCESS-resultscreen.webp b/docs/reST/tutorials/assets/Bagic-PROCESS-resultscreen.webp deleted file mode 100644 index a147cd82d9..0000000000 Binary files a/docs/reST/tutorials/assets/Bagic-PROCESS-resultscreen.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/Bagic-PROCESS-sourcecode.webp b/docs/reST/tutorials/assets/Bagic-PROCESS-sourcecode.webp deleted file mode 100644 index c4bec96d38..0000000000 Binary files a/docs/reST/tutorials/assets/Bagic-PROCESS-sourcecode.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/Bagic-ouput-result-screen.webp b/docs/reST/tutorials/assets/Bagic-ouput-result-screen.webp deleted file mode 100644 index b55ffca4a6..0000000000 Binary files a/docs/reST/tutorials/assets/Bagic-ouput-result-screen.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/Basic-ouput-sourcecode.webp b/docs/reST/tutorials/assets/Basic-ouput-sourcecode.webp deleted file mode 100644 index 5bb415a0aa..0000000000 Binary files a/docs/reST/tutorials/assets/Basic-ouput-sourcecode.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/introduction-Battleship.webp b/docs/reST/tutorials/assets/introduction-Battleship.webp deleted file mode 100644 index b8148e099c..0000000000 Binary files a/docs/reST/tutorials/assets/introduction-Battleship.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/introduction-PuyoPuyo.webp b/docs/reST/tutorials/assets/introduction-PuyoPuyo.webp deleted file mode 100644 index 23db4657f0..0000000000 Binary files a/docs/reST/tutorials/assets/introduction-PuyoPuyo.webp and /dev/null differ diff --git a/docs/reST/tutorials/assets/introduction-TPS.webp b/docs/reST/tutorials/assets/introduction-TPS.webp deleted file mode 100644 index a93eb473df..0000000000 Binary files a/docs/reST/tutorials/assets/introduction-TPS.webp and /dev/null differ diff --git a/docs/reST/tutorials/en/Red_or_Black/1.Prolog/introduction.rst b/docs/reST/tutorials/en/Red_or_Black/1.Prolog/introduction.rst deleted file mode 100644 index eb8421503b..0000000000 --- a/docs/reST/tutorials/en/Red_or_Black/1.Prolog/introduction.rst +++ /dev/null @@ -1,121 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -Prolog? Why Pygame? -==================================== -As we know, every kind of game has 3 sections (Because game is a subgroup of program): **input**, **process** and **output**. If you want to make a game in C **console environment** (Write C source code then execute that on the console) simply, all you have to do is just using lots of scanf(or unnormalized getch function) functions and procedural complex algorithm followed by printf(with blinking clear function) functions with ASCII arts! However, when you get bored of making outdated, graphic-less CUI, discontinuous game, now it’s time to learn GUI based game making tool. You can directly enter into Unity **game engine** or Unreal game engine. However, there are too much barrier to overcome. Quaternion for 3D collision, Mechanim/Legacy animation compatibility, Larger memory/Faster CPU for simulate in high-graphic mod, and etc! So, there is a dilemma between console environment and game engine. Can this dilemma to be solved? - - -.. image:: ../../../assets/introduction-PuyoPuyo.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("introduction-PuyoPuyo.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -(Example of C console game - PuyoPuyo) - - -.. image:: ../../../assets/introduction-TPS.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("introduction-TPS.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -(Example of Unity Engine game - TPS) - -Yes. Pygame can solve that. Pygame is an external library of **Python** which enables you to make a **game**. Pygame has advantages of console environment. For example, single pygame project nearly equals single source code, so we have to focus on writing source code only. (with some sound file or some image file in the same directory). Because Pygame is not a tool but a library, single command “import pygame” makes current source code to use pygame’s everything. That is, Pygame is simple to access. Pygame has advantages of game engine, too. For example, Pygame provide input functions (which check every possible state of keyboard, mouse and even files) and output functions (drawing geometry, fill certain colors or set display) to user. That is, user can run the program on the GUI environment if it based on Pygame. Because Pygame is based on Python, functions in Pygame project can be executed selectively, even almost simultaneously. That is, Pygame is event-driven. - - -.. image:: ../../../assets/introduction-Battleship.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("introduction-Battleship.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -(Example of Pygame - Battleship) - -So, Pygame has both good point of console environment (example of low-level game maker) and game engine (example of high-level game maker). Pygame is good **intersection** between console environment to game engine. That’s enough to use Pygame. No need to master it (if your dream is one-man game developer in advanced game engine, start to learn about that game engine right now!), but at least, try Pygame. (if you are interested in any kind of unique program including game maker or if you want to code any game on advanced environment aside from console environment) diff --git a/docs/reST/tutorials/en/Red_or_Black/2.Print_text/Basic TEMPLATE and OUTPUT.rst b/docs/reST/tutorials/en/Red_or_Black/2.Print_text/Basic TEMPLATE and OUTPUT.rst deleted file mode 100644 index 68d39b74d4..0000000000 --- a/docs/reST/tutorials/en/Red_or_Black/2.Print_text/Basic TEMPLATE and OUTPUT.rst +++ /dev/null @@ -1,130 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -Basic TEMPLATE and OUTPUT -==================================== - -==================================== -–Into Event-driven and GUI -==================================== -As I said, Pygame is based on GUI environment. Furthermore, Pygame is good for making 2D game because of its input/output format. So, you have to say good-bye for print or input standard function of Python (Because they work only on CUI environment). Then, what functions in Pygame replace these functions? First, we have to go back to friendly “Hello World!” project, which is learning about basic template and output. **(Requiring any font file(.ttf) in the same project directory)** - - -.. image:: ../../../assets/Basic-ouput-sourcecode.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("Basic-ouput-sourcecode.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -.. image:: ../../../assets/Bagic-ouput-result-screen.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("Bagic-ouput-result-screen.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -(Source Code for Hello World Project and its result screen) - -Wow, it’s complicated in compare to python’s print(“Hello World”) (Just a single line command). It’s because text in GUI environment has 5 components: text contents, font, size, color and location. If you want to print any text into screen, you have to set other 4 components, not only string (unless when it is in GUI environment). Only ``pygame.display.set_caption(“Hello World Project”)`` function in #7 do the same function as python’s print(“Hello World Project”). The only difference is that output string is always on window caption (title of current program) - -First, look at the template of source code before understanding how to output something, source code can be dived into 4 sections: Header(#1-#2), Initial statement(#3-#12), Always statement(#13-#20) and Event statement(#16-#19). - -In **Header**, importing modules will be executed. ``import pygame, sys`` is always needed. Needless to say, because this is pygame project and game has to be terminated when player want to exit(``sys.exit()`` at #19). ``from pygame.locals import*`` is also necessary to use useful constants just like ``QUIT`` at #17. -In **Initial statement** (commands before infinite loop), some global values will be initialized and some functions will be called for one time. Global values just like colors has to be initialized here in order to increase readability. Remember, this is GUI which is colorful. Color has three components: red, green and blue. So, color value has to be initialized just like ``red = (255, 0, 0)``. Function named ``pygame.init()`` must be called preceding to other pygame functions. Then other pygame functions can be executed. (Other pygame functions will be explained later.) - -In **Always statement** (commands within infinite loop), some global values will be updated routinely and some functions will be called routinely unless they are enclosed into conditional statement. Function named ``pygame.display.update()`` should be called after every processes are done. Because this function is printing the results of processes onto screen(=monitor). If this function is not executed in the last part of Always statement, there will be a probability that current screen and internal data does not match. (Other pygame functions will be explained later.) - -In **Event statement** (commands within loop which check every possible events), there will be suitable conditional statements when certain event is triggered. ``pygame.event.get()`` function returns a list of events occurred by processes in Always statement. And this list is automatically arranged by time (oldest to newest). So, using for-in statement, every triggered event caused by Always statement can be resolved procedurally. (Remind that this is the trait of event-driven.) For example, commands in #17-#19 will deal with QUIT event. In this case, pygame will be terminated then system will be terminated because system must be terminated after pygame is terminated! (Other events will be explained later.) - -Regarding this template is fixed, then we can add special functions in correct place to print “Hello World!”. First, we need to set **font** and **size**. ``pygame.font.Font(“HoonWhiteCatR,ttf”, 32)`` function at #9 will set not only font by ttf file but also size (32). Return value of this function need to be stored into object(= myTextFont). Then member function of myTextFont named ``render(“Hello World!”, True, red, green)`` at #10 will return a value(= myText). render function can set **text contents** and **color**(red is color of text, green is color of area outside of text). Then member function of myText named ``get_rect()`` at #11 will return a value(= myTextArea). myTextArea means the area allocated for printing text. When get_rect() is called, a rectangle area is returned corresponding to text’s length and font size. Now, all we have to do is locating this area somewhere. If we change member value of myTextArea named ``center`` at #12 into center of screen, then the text’s center **location** will be center of the screen. - -But how to determine where is the center of screen? First, we have to decide the range of screen, by using ``pygame.display.set_mode((640,480))`` in #8, canvas(where all values which has size, color, position will be drawn when display.update is called) will be generated and its size becomes 640 x 480. Then, its center is exactly (320,240). If the total size is given, we can decide any position even accounting some margin with little calculation (Remind that in 2D GUI, everything has x and y which has to be printed) (Just like turtle graphic, if it goes **right, x increases**, if it goes **down**, **y increase**. Don’t confused!). And we know that all functions I mentioned will be putted into Initial statement, because this information are fixed while the program go on. -Although everything is fixed, we have to design that fill and blit functions to be putted into Always statement, because of these functions’ trait. ``fill(white)`` function in #14 means filling canvas by single color(white). ``blit(myText, myTextArea)`` function in #15 means drawing specific object(= myText) on specific location(= myTextArea) of canvas. Notice that drawing(blit) has to be done after filling(fill). When everything is drawn on canvas, result of canvas will be display onto window when display.update is executed. - -That was the explanation of the entire source code, which has 20 lines. It seems it takes too much time to understand source code with only 20 lines. However, adding or changing from this source code is not that hard because we understand the template of this source code and step of printing. What about adding process logic in this source code? That will be next project. - - :: - - 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 diff --git a/docs/reST/tutorials/en/Red_or_Black/3.Move_text/Basic PROCESS.rst b/docs/reST/tutorials/en/Red_or_Black/3.Move_text/Basic PROCESS.rst deleted file mode 100644 index 83c61b2d9d..0000000000 --- a/docs/reST/tutorials/en/Red_or_Black/3.Move_text/Basic PROCESS.rst +++ /dev/null @@ -1,152 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -Basic PROCESS -==================================== - -==================================== --Setting for Animation -==================================== -Previous project looks like a single image instead of game. Because there is no input neither process to control output. Of course, clicking exit button on window is not counted because it is just shutting down the entire program. First, we will let text “Hello World!” to move automatically (and now project will be looks like an animation rather than single image), which means adding first processing logic on this project. How to move text? We know that location of text is initialized in Initial statement. So, location of text should be updated in Always statement, with adding some variable to process something. - - -.. image:: ../../../assets/Bagic-PROCESS-sourcecode.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("Bagic-PROCESS-sourcecode.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -.. image:: ../../../assets/Bagic-PROCESS-resultscreen.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("Bagic-PROCESS-resultscreen.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -(Source Code for Moving World Project and its result screen) - -(Not the entire source code of Moving World Project, but part) - -(Moving World! moves automatically just like Arkanoid ball or DVD screensaver.) - - -New line #1 - #5 were appended at the end of Initial statement. Also, multiple if-else phases (#6 - #9) were inserted at the beginning of Always statement, with line #11 at the end of always statements. We can understand what commands of #2 - #10 do. They just change variables for position of “Moving World” when Always statement being started. But there is a problem. How fast is “Moving World?” It is sure that displacement of “Moving World” is sqrt(2) (simple Pythagorean equation). But how often displacement of “Moving World” is changed? It can’t be determined without calculating time complexity of Always statement! (Because it depends on how often Always statement being started) And time complex will be differ to computer to computer, so can’t be fixed. - -We need to add the conception of **fixed speed** into this project. How? Look at #1 and #11. There is ``pygame.time.Clock()`` on Initial statement and ``tick(60)`` on Always statement. 60 means FPS (frame rate per second). We know that FPS means how often display is changed in 1 second. What function means change (= update) display in pygame? That’s right. Pygame.display.update() function. So, FPS means how often Always statement being executed in 1 second. Because there is 1 Pygame.display.update() function in 1 always statements. (So, FPS means **selective delay** according to current program’s process speed, **not selective acceleration**, so FPS cannot work if FPS is too high.) If we let fps(= **time**) to be fixed in this project, we can change **velocity** of certain game object by finding appropriate value for **displacement**. pygame.time.Clock() is needed to fix the speed of project before game started. Notice that tick function has to be called when Pygame.display.update() is called. Because tick counts the number of update function. It is one of the exception of function that can be executed after Pygame.display.update(). - -Okay, we learn that “Fixing time” is needed when screen is updated. Every screen of dynamic game is frequently changed unless it is static game. So, we have to know that. However, this project isn’t look like a game because its result can be anticipated easily (there is no input to change result) Now, input logic will be inserted. - - - :: - - import pygame, sys - from pygame.locals import* - - white = (255,255,255) - red = (255,0,0) - green = (0,255,0) - pygame.init() - pygame.display.set_caption("Moving World Project") - myScreen = pygame.display.set_mode((640, 480)) - myTextFont = pygame.font.Font("HoonWhitecatR.ttf", 32) - myText = myTextFont.render("Moving World!", True, red, green) - myTextArea = myText.get_rect() - myTextArea.center = (320, 240) - fpsClock = pygame.time.Clock() #1 - x = 0 #2 - y = 0 #3 - moveRight = 1 #4 - moveUp= 1 #5 - - while True: - if (moveRight == 1): #6 - x = x + 1 - if (x >= 320 - 75): - moveRight = 0 - elif (moveRight == 0): #7 - x = x - 1 - if (x <= -320 + 75): - moveRight = 1 - - if (moveUp == 1): #8 - y = y + 1 - if (y >= 240 - 15): - moveUp = 0 - elif (moveUp == 0): #9 - y = y - 1 - if (y <= -240 + 15): - moveUp = 1 - - - - myTextArea.center = (320 + x, 240 + y) #10 - - myScreen.fill(white) - myScreen.blit(myText, myTextArea) - - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - - pygame.display.update() - fpsClock.tick(60) #11 diff --git a/docs/reST/tutorials/en/Red_or_Black/4.Control_text/Basic INPUT.rst b/docs/reST/tutorials/en/Red_or_Black/4.Control_text/Basic INPUT.rst deleted file mode 100644 index 4f40435c4e..0000000000 --- a/docs/reST/tutorials/en/Red_or_Black/4.Control_text/Basic INPUT.rst +++ /dev/null @@ -1,156 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -Basic INPUT -==================================== - -==================================== --New Input is new Event -==================================== -Usually, we learn how to output something first (Think about Hello World!), learning how to input something is always second. Why? Because input is not the requirement for some program in contrast to output is the requirement for every program. (That’s definition of program. more than or same as 0 input, more than or same as 1 output.) However, every game needs input. That’s why we said “I like playing games”. Playing means moving your part of body (maybe your finger). Anyway, let’s add input logic to make this project into real game. - - -.. image:: ../../../assets/Bagic-INPUT-sourcecode.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("Bagic-INPUT-sourcecode.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -.. image:: ../../../assets/Bagic-INPUT-resultscreen.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("Bagic-INPUT-resultscreen.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -(Source Code for Controlling World Project and its result screen) - -(Not the entire source code of Controlling World Project, but part) - -(Controlling World! moves when player press one of four direction arrow of keyboard) - - -There are 2 big difference in comparison to before project. First big difference is line #5, which adds checking ``KEYDOWN`` **event** is triggered or not. Other lines are just changing previous algorithm to act differently. We know that same command can make big difference in entire program when it is executed before Event statement of after Event statement. Pay attention that process about changing location appear after Event statement. (**Update after set**. That is second big difference). Variable ``event.key`` means latest pressed key on keyboard. Look at the specific key name. K_UP, K_LEFT, K_DOWN, K_RIGHT. Very intuitive **K_ series**. (Given by pygame.locals which we added at the Header) Furthermore, there are other key named K_8, K_a, K_L, K_LCTRL, K_DELETE, or K_F4. We can understand meaning of these keys without extra explanation. Full key list can be found in -`https://pyga.me/docs/ref/key.html#pygame.key.name`. - -Notice that KEYDOWN means “this key was not pressed before, but **now is pressed**” and meaning of **“hold” is not included** here. In the case of hold, new event-handling about checking ``KEYUP`` (it means “this key was pressed before, but now is not pressed”) is needed with some processing (which needs extra variable and algorithm). This will be mentioned at advanced part. - -Adding input was easy because it’s just adding if phase with certain event parameter. Now game project is done because project has output, process and input step-by-step! Really? No. This project can’t be called as a game because there is no **interaction** between at least two **game objects**, no **rule** for playing this (neither constrains (ex. HP, time) nor score). Mostly, not **enjoyable** (no motivation, no variety of input and output, no attractive contents) Firstly, we have to learn more advanced input (for example, handling for mouse status), process (for example, idea for functionalization) and output (for example, printing image/sound or visualizing internal data) to flourish game interface/system. Don’t stay in the level of printing const text or inputting single pressed key. Of course, experiences of this level are surely helpful for advanced level. So, let’s go to advanced level! - - - - :: - - import pygame, sys - from pygame.locals import* - - white = (255,255,255) - red = (255,0,0) - green = (0,255,0) - pygame.init() - pygame.display.set_caption("Controlling World Project") - myScreen = pygame.display.set_mode((640, 480)) - myTextFont = pygame.font.Font("HoonWhitecatR.ttf", 32) - myText = myTextFont.render("Controlling World!", True, red, green) - myTextArea = myText.get_rect() - myTextArea.center = (320, 240) - fpsClock = pygame.time.Clock() - x = 0 - y = 0 - moveRight = 0 #1 - moveDown = 0 #2 - - while True: - moveRight = 0 #3 - moveDown = 0 #4 - myTextArea.center = (320 + x, 240 + y) - myScreen.fill(white) - myScreen.blit(myText, myTextArea) - - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - elif event.type == KEYDOWN: #5 - if event.key == K_UP: - moveDown = -1 - moveRight = 0 - elif event.key == K_LEFT: - moveDown = 0 - moveRight = -1 - elif event.key == K_DOWN: - moveDown = 1 - moveRight = 0 - elif event.key == K_RIGHT: - moveDown = 0 - moveRight = 1 - - if(moveRight == 1): #6 - x = x + 10 - elif(moveRight == -1): #7 - x = x - 10 - if(moveDown == 1): #8 - y = y + 10 - elif(moveDown == -1): #9 - y = y - 10 - - pygame.display.update() diff --git a/docs/reST/tutorials/en/Red_or_Black/5.HP_bar/Advanced OUTPUT with Advanced PROCESS.rst b/docs/reST/tutorials/en/Red_or_Black/5.HP_bar/Advanced OUTPUT with Advanced PROCESS.rst deleted file mode 100644 index 9a968fa666..0000000000 --- a/docs/reST/tutorials/en/Red_or_Black/5.HP_bar/Advanced OUTPUT with Advanced PROCESS.rst +++ /dev/null @@ -1,276 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -========================================= -with Advanced PROCESS - Functionalization -========================================= - -First, Let’s print visualized geometry, not text. How about HP bar? If max HP of game is fixed and current HP of game can vary from 0 to max HP, what will be simplest way to print both two data? - -.. image:: ../../../assets/AdvancedOutputProcess1.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputProcess1.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedOutputProcess2.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputProcess2.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedOutputProcess3.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputProcess3.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -Yeah, just re-rendering text when certain variable is changed. How to change variable? That logic is inside of Event statement. (Pressing up or down to adjust HP.) Same method as before. But they are still text, which means they are not visualized enough. How to visualize these two data more detail (max HP, current HP)? We can use idea of magazine (gun’s magazine). HP is integer value, which is discrete. So, it can be printed as below: - -.. image:: ../../../assets/AdvancedOutputProcess4.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputProcess4.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedOutputProcess5.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputProcess5.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedOutputProcess6.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputProcess6.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -Much better, isn’t it? Drawing logic is inside of #6. Logic is simple, first, draw a **big rectangular** which color is black. Then, check whether draw a **smaller rectangular** which color is red or not depending on current HP. Finally, draw **margin** of current small rectangular. Margin of color is white. We can find there are 4 parameters for location data in ``pygame.draw.rect`` (I mean, third data. First data is canvas data, second data is color data and fourth data is width.) The easiest way to understand 4 parameters is change them. Change one value into 10 or 30 while others are 20! Then it can be understood. Needless to explain. - -Furthermore, now it’s time to functionalize specifically. I push Always statement and Event statement into main function. (#7 is needed to find main function and execute it.) And made new function for drawHP. Functionalization idea for game is not far away from that of normal GUI program. For example, it is better to make **single print function for every single value** which has to be displayed. Of course, setting location for each value has to be done while you are designing the screen. - - :: - - import pygame, sys - from pygame.locals import* - - maxHP = 10 - white = (255,255,255) - gray = (127,127,127) - black = (0,0,0) - red = (255,0,0) - green = (0,255,0) - blue = (0,0,255) - pygame.init() - pygame.display.set_caption("HP bar Project") - width = 640 #1 - height = 480 #2 - myScreen = pygame.display.set_mode((width, height)) - myTextFont = pygame.font.Font("HoonWhitecatR.ttf", 32) - myText = myTextFont.render((str(maxHP) + "/" + str(maxHP)), True, red, gray) - myTextArea = myText.get_rect() - myTextArea.center = (width/2, height/2) #3 - fpsClock = pygame.time.Clock() - - def main(): #4 - HP = 5 - - while True: - myText = myTextFont.render((str(HP) + "/" + str(maxHP)), True, red, gray) - - myScreen.fill(gray) - - myScreen.blit(myText, myTextArea) - drawHP(HP) #5 - - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - elif event.type == KEYDOWN: - if event.key == K_UP: - if HP != 10: - HP = HP + 1 - elif event.key == K_DOWN: - if HP != 0: - HP = HP - 1 - - pygame.display.update() - fpsClock.tick(60) - - def drawHP(HP): #6 - r = int((height - 40) / maxHP) - - pygame.draw.rect(myScreen, black, (20, 20, 20, 20 + ((maxHP - 0.5) * r))) - - for i in range(maxHP): - if HP >= (maxHP - i): - pygame.draw.rect(myScreen, red, (20, 20 + (i * r), 20, r)) - pygame.draw.rect(myScreen, white, (20, 20 + (i * r), 20, r), 1) - - return - - if __name__ == '__main__': #7 - main() diff --git a/docs/reST/tutorials/en/Red_or_Black/6.Buttons/Advanced INPUT with Advanced OUTPUT.rst b/docs/reST/tutorials/en/Red_or_Black/6.Buttons/Advanced INPUT with Advanced OUTPUT.rst deleted file mode 100644 index f077099644..0000000000 --- a/docs/reST/tutorials/en/Red_or_Black/6.Buttons/Advanced INPUT with Advanced OUTPUT.rst +++ /dev/null @@ -1,268 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -with Advanced OUTPUT – Buttons -==================================== - -Even if KEYDOWN event is used, it seems like this is not entirely GUI game because GUI of this game is only used for output(=print), not input. Input for GUI means caring mouse event for specific location. How about making two buttons to increase or decrease HP? - -.. image:: ../../../assets/AdvancedInputOutput1.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedInputOutput1.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedInputOutput2.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedInputOutput2.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -Okay, making two buttons is simple. Look at the button, they have unique visual shape. How can it be? Simple as previous idea: First, draw **big square**. Second, draw **smaller square** which has small width (this square doesn’t have inner color so color of big square can be displayed) so inner square and outer square seems like separated. But these buttons are still for output only. We need to make click area for this. - -.. image:: ../../../assets/AdvancedInputOutput3.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedInputOutput3.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedInputOutput4.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedInputOutput4.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedInputOutput5.gif - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedInputOutput5.gif") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -Now new event ``MOUSEBUTTONUP`` is added at Event statement. Notice that up of mouse is same as down of key. If MOUSEBUTTONUP is activated, ``event.pos`` will be recorded as x and y. Which means, clicked point. So, determining clicked point is whether inside of certain Rect area or not is needed by checking ``collidepoint``. If inside, it means “**user clicked some point which is part of certain area**” then, adequate process (updating value) is needed. -Notice that there are two area for input: -**(270, 425, 45, 45)** and **(325, 425, 45, 45)** at Event Statement. -Notice that also there are two area for output. -**(margin, height - r -10 , r, r)** and **(margin + r + r_margin, height - r - 10, r, r)** at drawButtons. -In the case of button, input and output area for button must be **identical**. (Otherwise, this button will be deceptive!) It will be best idea to set this data as same value without calculating exact location of function (for output) into constant (for input). There is no specific function to tie this area, so you have to care about this. - - :: - - import pygame, sys - from pygame.locals import* - - maxHP = 10 - white = (255,255,255) - gray = (127,127,127) - black = (0,0,0) - red = (255,0,0) - green = (0,255,0) - blue = (0,0,255) - pygame.init() - pygame.display.set_caption("Array buttons Project") - width = 640 - height = 480 - myScreen = pygame.display.set_mode((width, height)) - myTextFont = pygame.font.Font("HoonWhitecatR.ttf", 32) - myText = myTextFont.render((str(maxHP) + "/" + str(maxHP)), True, red, gray) - myTextArea = myText.get_rect() - myTextArea.center = (width/2, height/2) - fpsClock = pygame.time.Clock() - - def main(): - HP = 5 - - while True: - myText = myTextFont.render((str(HP) + "/" + str(maxHP)), True, red, gray) - - myScreen.fill(gray) - - myScreen.blit(myText, myTextArea) - drawHP(HP) - drawButtons() - - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - elif event.type == KEYDOWN: - if event.key == K_UP: - if HP != 10: - HP = HP + 1 - elif event.key == K_DOWN: - if HP != 0: - HP = HP - 1 - elif event.type == MOUSEBUTTONUP: #1 - x, y = event.pos - if pygame.Rect(270, 425, 45, 45).collidepoint(x, y): - if HP != 10: - HP = HP + 1 - elif pygame.Rect(325, 425, 45, 45).collidepoint(x, y): - if HP != 0: - HP = HP - 1 - - pygame.display.update() - fpsClock.tick(60) - - def drawHP(HP): - r = int((height - 40) / maxHP) - - pygame.draw.rect(myScreen, black, (20, 20, 20, 20 + ((maxHP - 0.5) * r))) - - for i in range(maxHP): - if HP >= (maxHP - i): - pygame.draw.rect(myScreen, red, (20, 20 + (i * r), 20, r)) - pygame.draw.rect(myScreen, white, (20, 20 + (i * r), 20, r), 1) - - return - - def drawButtons(): - r = 45 - r_margin = 10 - colors = [red, black] - - num = 2 - margin = int((width - ((r * num) + (r_margin * (num - 1)))) / 2) - for i in range(0, num): - left = margin + (i * r) + (i * r_margin) - up = height - r - 10 - pygame.draw.rect(myScreen, colors[i], (left, up, r, r)) - pygame.draw.rect(myScreen, gray, (left + 2, up + 2, r - 4, r - 4), 2) - - if __name__ == '__main__': - main() diff --git a/docs/reST/tutorials/en/Red_or_Black/7.Game_board/Advanced OUTPUT and plus alpha.rst b/docs/reST/tutorials/en/Red_or_Black/7.Game_board/Advanced OUTPUT and plus alpha.rst deleted file mode 100644 index eb09d5fa3f..0000000000 --- a/docs/reST/tutorials/en/Red_or_Black/7.Game_board/Advanced OUTPUT and plus alpha.rst +++ /dev/null @@ -1,258 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -and plus alpha -==================================== - -Actually, everything doesn’t seem like a game. Now, we will insert a rule into this program. Then. It will become game. Rule is simple: counting red or black from 5x5 2D array and choose the color which has much more number! If correct, HP++, otherwise, HP--. Then new array will be set for next quiz! too simple but game which can be made in this tutorial. First, we need to generate 2D array and print it. How? We learned how to print integer data (which equals single data (0D array)) and two buttons (which equals single array (1D array). Case of 2D array just needs one-more step. - -.. image:: ../../../assets/AdvancedOutputAlpha1.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputAlpha1.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedOutputAlpha2.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputAlpha2.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedOutputAlpha3.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputAlpha3.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -generateboard function returns randomly generated 2D board with the number of red block and black block. Needless to explain. Also, printboard function prints 2D board by same method as 1D array. Output color will be changed by data of board[i][j] is 1 or not. This board is for output only. Processing about margin seems to be annoying because we have to know exact location by calculating. Remember prolog. Output (executing result) of Pygame is GUI but input(coding) of Pygame is CUI. That is Pygame. - -Actually, there are a lot of idea for improving this game. How about changing button into image file? How about adding sound effect when previous chose was correct or not? How about setting time limit? How about adding visual effect when player win(maxHP) or not(minHP)? How about make the board bigger with another colors? How about implement Flood-it game by given interface? There are still lots of selection because this game is simple. - - :: - - import pygame, sys, random - from pygame.locals import* - - maxHP = 10 - white = (255,255,255) - gray = (127,127,127) - black = (0,0,0) - red = (255,0,0) - green = (0,255,0) - blue = (0,0,255) - pygame.init() - pygame.display.set_caption("Red or Black Project") - width = 640 - height = 480 - myScreen = pygame.display.set_mode((width, height)) - myTextFont = pygame.font.Font("HoonWhitecatR.ttf", 32) - myText = myTextFont.render((str(maxHP) + "/" + str(maxHP)), True, red, gray) - myTextArea = myText.get_rect() - myTextArea.center = (width/2, height/2) - fpsClock = pygame.time.Clock() - - def main(): - HP = 5 - board, b_red, b_black = generateBoard(5,5) #1 - - while True: - myText = myTextFont.render((str(HP) + "/" + str(maxHP)), True, red, gray) - - myScreen.fill(gray) - - myScreen.blit(myText, myTextArea) - drawHP(HP) - drawButtons() - drawBoard(board) #2 - - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - - elif event.type == KEYDOWN: - if event.key == K_UP: - if HP != 10: - HP = HP + 1 - elif event.key == K_DOWN: - if HP != 0: - HP = HP - 1 - elif event.type == MOUSEBUTTONUP: - x, y = event.pos - - if pygame.Rect(270, 425, 45, 45).collidepoint(x, y): #3 - if b_red >= b_black: - if HP != 10: - HP = HP + 1 - board, b_red, b_black = generateBoard(5,5) - elif b_red < b_black: - if HP != 0: - HP = HP - 1 - board, b_red, b_black = generateBoard(5,5) - - elif pygame.Rect(325, 425, 45, 45).collidepoint(x, y): #4 - if b_red <= b_black: - if HP != 10: - HP = HP + 1 - board, b_red, b_black = generateBoard(5,5) - elif b_red > b_black: - if HP != 0: - HP = HP - 1 - board, b_red, b_black = generateBoard(5,5) - - pygame.display.update() - fpsClock.tick(60) - - def drawHP(HP): - r = int((height - 40) / maxHP) - - pygame.draw.rect(myScreen, gray, (20, 20, 20, 20 + ((maxHP - 0.5) * r))) - - for i in range(maxHP): - if HP >= (maxHP - i): - pygame.draw.rect(myScreen, blue, (20, 20 + (i * r), 20, r)) - pygame.draw.rect(myScreen, white, (20, 20 + (i * r), 20, r), 1) - - return - - def drawButtons(): - r = 45 - r_margin = 10 - colors = [red, black] - - num = 2 - margin = int((width - ((r * num) + (r_margin * (num - 1)))) / 2) - - for i in range(0, num): - left = margin + (i * r) + (i * r_margin) - up = height - r - 10 - pygame.draw.rect(myScreen, colors[i], (left, up, r, r)) - pygame.draw.rect(myScreen, gray, (left + 2, up + 2, r - 4, r - 4), 2) - - def generateBoard(width, height): #5 - board = [] - b_red = 0 - b_black = 0 - - for x in range(width): - column = [] - for y in range(height): - column.append(random.randint(0, 1)) - board.append(column) - - for x in range(width): - for y in range(height): - if(board[x][y] == 1): - b_red = b_red + 1 - elif(board[x][y] == 0): - b_black = b_black + 1 - - return board, b_red, b_black - - def drawBoard(board): #6 - r = 50 - b_width = 5 - b_height = 5 - l_margin = int((width - (b_width * r)) / 2) - u_margin = int((height - (b_height * r)) / 2) - - for x in range(5): - for y in range(5): - left = x * r + l_margin - up = y * r + u_margin - if board[x][y] == 1: - color = red; - elif board[x][y] == 0: - color = black - pygame.draw.rect(myScreen, color, (left, up, r, r)) - - left = l_margin - up = u_margin - pygame.draw.rect(myScreen, white, (left-1, up-1, r * 5 + 1, r * b_height + 1), 1) - - if __name__ == '__main__': - main() diff --git a/docs/reST/tutorials/en/Red_or_Black/8.Epilog/Epilog.rst b/docs/reST/tutorials/en/Red_or_Black/8.Epilog/Epilog.rst deleted file mode 100644 index b257ee4588..0000000000 --- a/docs/reST/tutorials/en/Red_or_Black/8.Epilog/Epilog.rst +++ /dev/null @@ -1,17 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -Epilog -==================================== - -However, this is end of tutorial. This tutorial covers only a few of Pygame. But don’t worry. Programming is the most creative activity human can do. Immanuel Kant said “Genius is the innate mental aptitude through which nature gives the rule to art”. Programming is making a rule and give it to computer. If rule is made, computer can do anything within rule. So, number of cases incredibly increase. - -What is conclusion? **Output is greater than input**. We can implement much more program within our knowledge. Or, we can learn new knowledge easily by connecting it to old knowledge. That’s trait of programming. And so is game. “Radom” is the key concept for every game. (including simple game made on this tutorial!) number of cases is much greater when random variable is concerned. If random variable starts to affect another random variable and so on, output will be greater like Avalanche. That’s why game is interesting. Concept of “Random” is the only unique characteristic for game in comparison to novel, music or movie. Think about Tetris. How much effort Alexey Leonidovich Pajitnov spent? Do you think it is greater than sum of Tetris player’s playing time above the world, along 35 years? That’s ultimate example of both power of programming and game. - -So, game makers are Avalanche makers. Now it’s time to create any game! Learn! Utilize! Go through trial and errors! diff --git "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/1.\355\224\204\353\241\244\353\241\234\352\267\270/\354\206\214\352\260\234.rst" "b/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/1.\355\224\204\353\241\244\353\241\234\352\267\270/\354\206\214\352\260\234.rst" deleted file mode 100644 index fff06c2afb..0000000000 --- "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/1.\355\224\204\353\241\244\353\241\234\352\267\270/\354\206\214\352\260\234.rst" +++ /dev/null @@ -1,125 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -프롤로그 -==================================== - -==================================== -– 왜 하필 파이게임? -==================================== -게임도 프로그램의 일부이기 때문에, 게임은 입력, 처리 그리고 출력으로 구성된다. C 콘솔 환경에서 게임을 만든다고 가정해 보자(C로 소스코드를 작성한 후 콘솔에서 실행하는 방식). 그러면 입력은 수많은 scanf(또는 엔터 입력 필요 없는 비표준 getch) 함수로, 처리는 항상 절차적으로 실행되는 복잡한 알고리즘으로, 출력은 아스키아트를 이용한 printf(그리고 화면을 지우는 깜빡거리는 clear)함수로 구성할 수 있다. 하지만 이렇게 만든 게임은 구식이고, 그래픽 없는 CUI고, 끉겨 보인다는 단점이 있다. 이런 식의 게임을 만드는 것이 질린다면, 보통 Unity 게임엔진이나 Unreal 게임엔진 등 게임 엔진에도 손을 대보게 된다. 하지만, 게임 엔진은 입문장벽이 높다는 단점이 있다. 복소수좌표를 활용한 공간상에서의 충돌, Mechanin/Legacy 애니메이션 호환성, 더 좋은 그래픽을 위한 더 큰 메모리/더 빠른 CPU… 아무래도 콘솔 환경과 게임 엔진 사이에는 딜레마가 있는 것 같다. 이 딜레마를 해결할 수 있을까? - - -.. image:: ../../../assets/introduction-PuyoPuyo.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("introduction-PuyoPuyo.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -(C 콘솔 환경 게임의 예시 - 뿌요뿌요) - - -.. image:: ../../../assets/introduction-TPS.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("introduction-TPS.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -(유니티 게임 엔진 게임의 예시- TPS) - -다행히 파이게임은 그 딜레마를 해결할 수 있다. 파이게임 이란 프로그래머가 게임을 만들 수 있게 해 주는 파이썬의 외부 라이브러리이다. 파이게임은 콘솔 환경에서의 장점을 가지고 있다. 그 첫째 장점은 하나의 파이게임 프로젝트은 하나의 소스코드와 거의 동치관계라는 것이다. (외부 소리 파일이나 외부 사진 파일을 제외화면) 그래서 프로그래머는 소스 코드를 작성하는 것에만 집중하면 된다. 그리고 둘째 장점은 파이게임은 툴이 아닌 라이브러리이기 때문에, 소스파일에 “import pygame”만 있으면 그 소스파일은 파이게임의 모든 것에 접근할 수 있게 된다. 접근성이 좋다는 것이다. 파이게임은 게임 엔진의 장점도 가지고 있다. 그 첫째 장점은 파이게임이 키보드, 마우스, 파일 등의 상태를 확인하는 입력 관련 함수들과, 도형 그리기, 색 칠하기, 디스플레이 설정 등의 출력 관련 함수들을 제공하기 때문에, CUI가 아닌 GUI 환경에서 실행된다는 것이다. 그리고 둘째 장점은 파이게임이 파이썬에 기반하였기 때문에, 파이게임의 함수들은 절차적이 아닌 이벤트적(여러 함수들이 선택적으로 실행되거나 거의 동시에 실행됨)으로 실행된다는 것이다. - - -.. image:: ../../../assets/introduction-Battleship.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("introduction-Battleship.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -(파이게임 게임의 예시- 배틀십) - -요약하자면, 파이게임은 저급 수준(콘솔 환경은 예시 중 하나)의 게임 제작 프로그램과 고급 수준(게임 엔진은 예시 중 하나)의 게임 제작 프로그램의 장점을 모두 가진다는 것이다. 파이게임은 이 둘 사이의 좋은 연결점이 된다. 이것이 파이게임을 쓸 이유이다. 더 복잡한 게임 엔진을 최대한 활용해 게임을 만드는 1인 개발자가 목표가 아닌 이상 (빨리 그 게임 엔진을 배우는 것이 낫다!), 콘솔 환경용 게임이 아닌 더 발전된 환경에서 게임을 한번쯤은 코딩해 보고 싶다면 (물론, 푹 빠지면 계속 코딩하게 될 것이다!), 한번쯤은 파이게임을 시도해 볼만 하다. diff --git "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/2.\355\205\215\354\212\244\355\212\270 \354\266\234\353\240\245/\352\270\260\354\264\210 \355\205\234\355\224\214\353\246\277\352\263\274 \354\266\234\353\240\245.rst" "b/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/2.\355\205\215\354\212\244\355\212\270 \354\266\234\353\240\245/\352\270\260\354\264\210 \355\205\234\355\224\214\353\246\277\352\263\274 \354\266\234\353\240\245.rst" deleted file mode 100644 index bd69b1b595..0000000000 --- "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/2.\355\205\215\354\212\244\355\212\270 \354\266\234\353\240\245/\352\270\260\354\264\210 \355\205\234\355\224\214\353\246\277\352\263\274 \354\266\234\353\240\245.rst" +++ /dev/null @@ -1,133 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -기본 형식과 기초 출력 -==================================== - -==================================== -–이벤트 기반과 GUI 기반으로의 입문 -==================================== -앞서 말했듯, 파이게임은 GUI를 기반으로 한다. 정확히는, 파이게임은 2D용 입력, 출력 함수를 사용하여 2D GUI를 기반으로 한다. 어찌됐든, CUI환경에서만 먹히는 파이썬의 print함수나 input함수와는 이별을 해야 한다. 그렇다면, 파이게임의 어떤 함수가 print/input함수를 대체하는가? 우선, 프로그래밍 언어의 기본 형식과 출력을 배우는 친숙한 예제인 “Hello World!”프로젝트로 되돌아가야 한다. (이 프로젝트는 같은 디렉토리에 .ttf확장자를 가지는 폰트 파일을 필요로 한다.) - - -.. image:: ../../../assets/Basic-ouput-sourcecode.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("Basic-ouput-sourcecode.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -.. image:: ../../../assets/Bagic-ouput-result-screen.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("Bagic-ouput-result-screen.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -(Hello World 프로젝트의 소스 코드와 실행 결과) - -1줄짜리 print(“Hello World!”)에 비하면 소스 코드가 꽤 복잡하다. 이것은 GUI환경에서 텍스트는 최소 5개의 구성 성분(텍스트 내용, 폰트, 크기, 색상, 좌표)를 가지기 때문이다. GUI환경에서 텍스트는 1개의 구성 성분(텍스트 내용)만을 가지므로, 4개의 구성 성분이 추가된 셈이다. 예외적으로, #7의 pygame.display.set_caption(“Hello World Project”)함수는 print(“Hello World Project”)함수와 동일한 기능을 한다. 하지만, 이 함수 속 문자열은 프로그램의 윈도우 캡션에 고정된 문자열이다. - -우선, 무언가를 출력하기 위해선 소스코드가 어떻게 작성되어야 하는지 그 형식을 살펴보자. 소스코드는 4개의 부분으로 나눠질 수 있다. Header(#1-#2), Initial문(#3-#12), Always문(#13-#20), Event문(#16-#19)가 그것이다. - -Header에선, 모듈들을 import하는 작업이 실행된다. 여기에 import pygame, sys는 항상 필요하다. 이 프로젝트가 파이게임 프로젝트이며, 사용자가 프로그램을 종료하고 싶을 때 종료되어야 하기 때문에(실제로 #19에서 sys.exit()가 실행된다) 추가적인 설명이 필요 없는 당연한 문구이다. from pygame.locals import*는 #17에서의 QUIT같은 유용한 상수들을 선언 없이 사용하기 위해 거의 반필수적으로 필요하다. - -Initial문(무한 반복문 이전의 문장들)에선, 전역 변수가 한번만 초기화되거나 몇몇 함수가 한번만 호출된다. 주로 색상과 같은 전역 변수들이 가독성을 높이기 위해 초기화된다. 파이게임은 여러가지 색상을 사용하는 화려한 GUI임을 까먹어선 안된다. (게임이므로) 하나의 색상은 R값, G값, B값 3개의 구성 요소를 가진다. 그래서 색상 변수는 red = (255, 0, 0)와 같이 선언되어야 한다. pygame.init()과 같은 함수는 나중에 사용할 함수를 위해선 가장 앞서서 호출되어야 한다. (이 외의 함수들은 나중에 언급하겠다.) - -Always문(무한 반복문)에선, 전역 변수가 계속 업데이트되거나 몇몇 함수가 계속 호출된다. (물론, 조건문이 있는 경우 조건이 맞을 때만) pygame.display.update() 라는 함수는 일반적으로 다른 변수/함수의 처리가 끝난 이후에 호출되는데, 이 함수는 처리의 결과물들을 스크린(= 모니터)에 출력하는 함수이기 때문이다. 이 함수가 Always문 마지막에 실행되지 않으면, 출력되는 화면과 게임 내부 데이터가 서로 일치하지 않는 문제가 생길 수 있다. (이 외의 함수들은 나중에 언급하겠다.) - -Event문(모든 이벤트를 체크하는 반복문)에선, 특정 이벤트가 발생하면 이에 대한 처리가 이루어진다. pygame.event.get() 함수는 Always문에서 발생한 이벤트들의 배열을 반환한다. 그리고 이 이벤트들은 자동적으로 발생 시간순으로 정렬된다. 그러므로, for-in문을 쓰면, Always문에서 발생한 모든 이벤트들을 순차적으로 처리할 수 있다 (이벤트 기반). 예를 들어서, #17-#19는 QUIT라는 이벤트를 처리하고 있다. 이 이벤트가 트리거되면, 파이게임이 종료된 이후 시스템이 종료되게 된다. (이 외의 함수들은 나중에 언급하겠다.) - -기본 형식이 고정되어 있다고 가정하면, 이 형식에 일부 함수들을 적절히 삽입하면 “Hello World!”가 출력되게 할 수 있다. 첫째로, 텍스트의 폰트와 크기가 정해져야 한다. pygame.font.Font(“HoonWhiteCatR,ttf”, 32) 라는 #9의 함수는 주어진 이름의 ttf파일로 폰트를 정하고 크기 (이 경우 32)도 정한다. 이 함수의 반환 값은 myTextFont라는 객체에 저장해 두었다. 그리고 myTextFont객체의 render(“Hello World!”, True, red, green)라는 #10의 함수의 반환 값을 myText라는 객체에 저장해 두었다. render 함수는 텍스트 내용과 색상을 정할 수 있다. 이 경우, 텍스트의 색상은 빨간 색, 텍스트가 아닌 구역의 색상은 초록 색이 된다. myText객체의 get_rect() 라는 #11의 함수의 반환 값을 myTextArea라는 객체에 저장해 두는데, myTextArea는 텍스트를 출력하기 위해 할당된 구역을 의미한다. get_rect()라는 함수는 텍스트의 폰트 크기와 텍스트의 길이를 고려하여 적절한 직사각형 공간을 반환한다. 만약 myTextArea라는 객체의 center라는 멤버 변수를 텍스트가 화면 정중앙에 오게끔 수정한다면, (#12) 텍스트의 위치를 화면 정중앙으로 오게 알 수 있다. - -하지만 화면 정중앙을 어떻게 알아낼 수 있을까? 우선, 화면의 전체 크기를 정해야 한다. #8의 pygame.display.set_mode((640,480)) 함수는 캔버스 (크기, 색상, 위치 정보를 가지는 변수들이 display.update함수가 호출되면 그려지는 공간)를 생성하고 그 크기를 640 x 480으로 고정시킨다. 그렇다면, 화면의 정중앙은 (320, 240)이다. 화면의 전체 크기가 확정된다면, 약간의 계산만 하면 모든 종류의 위치를 결정할 수 있게 된다. (2D GUI이므로 출력되는 모든 것은 x, y성분을 가진다) (오른쪽이 x좌표가 크고, 아래쪽이 y좌표가 큼을 헷갈리면 안된다. 앞서서 말한 함수들은 모두 Initial문에 실행되어야 하는 것들이다, 왜나하면 이 정보들은 프로그램 도중 업데이트가 필요 없기 때문이다. - -물론, fill함수나 blit함수는 함수의 특성 때문에 Always문에 실행된다. #14의 fill(white) 함수는 캔버스를 단색(하얀색)으로 채우는 기능을 수행한다. #15의 blit(myText, myTextArea)는 특정 객체(myText)를 특정 위치(myTextArea)에 그리는 기능을 수행한다. blit이 fill 이후에 수행되어야 한다. 모든 것이 캔버스에 그려지고 나면, 캔버스의 결과물은 display.update함수가 실행되면 출력되게 된다. - -이것이 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 diff --git "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/3.\355\205\215\354\212\244\355\212\270 \354\235\264\353\217\231/\352\270\260\354\264\210 \354\262\230\353\246\254.rst" "b/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/3.\355\205\215\354\212\244\355\212\270 \354\235\264\353\217\231/\352\270\260\354\264\210 \354\262\230\353\246\254.rst" deleted file mode 100644 index 7ce0f89cdc..0000000000 --- "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/3.\355\205\215\354\212\244\355\212\270 \354\235\264\353\217\231/\352\270\260\354\264\210 \354\262\230\353\246\254.rst" +++ /dev/null @@ -1,151 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -기초 처리 -==================================== - -==================================== --화면이 움직이기 위한 조건 -==================================== -이전 프로젝트는 게임이 아니라 이미지 한 장 같아 보인다. 출력을 바꾸는 입력이나 처리가 없기 때문이다. 물론, 윈도우의 종료 버튼을 누르는 것은 고려되지 않는다 (프로그램을 종료하는 것에 불과하므로). 우선, 우리는 “Hello World!”가 자동적으로 움직이게 할 것이다. 그러면 이제 프로젝트는 이미지 한 장이 아닌 애니메이션 같아 보일 것이다. 어떻게 텍스트를 움직일까? 우리는 텍스트의 위치가 Initial statement에서 초기화됨을 알고 있다. 그렇다면, 이 위치가 Always statement에서 업데이트되게 하면 된다. 물론, 추가적인 변수가 필요할 것이다. - - -.. image:: ../../../assets/Bagic-PROCESS-sourcecode.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("Bagic-PROCESS-sourcecode.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -.. image:: ../../../assets/Bagic-PROCESS-resultscreen.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("Bagic-PROCESS-resultscreen.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -(Moving World 프로젝트의 소스 코드 일부 와 실행 결과) - -(Moving World가 알카노이드의 공이나 DVD 화면보호기처럼 움직인다.) - - - -#1 - #5가 Initial문의 뒷부분에 추가되었다. 또한, 다중 if-else문은 Always문의 앞부분에 추가되었고, #11이 Always문의 뒷부분에 추가되었다. #2 - #10이 무엇을 처리하는지는 쉽다. Always문이 시작될 때 Moving World의 좌표에 해당되는 변수를 바꾸고 있다. 하지만 문제가 있다. Moving World는 얼마나 빠를까? Moving World의 변위는 루트2 임은 확실하다. (피타고라스 정리를 이용하면) 하지만 얼마나 자주 Moving World의 변위가 바뀌는가? 이것은 Always문의 시간 복잡도를 분석하지 않는 이상 알아낼 수 없다. (이것은 Always문이 시작하는 빈도에 따라 달라지므로) 그리고 시간 복잡도는 컴퓨터마다 다르다. 그래서 이 시간은 고정될 수 없다. - -우리는 이 프로젝트에 고정 속도라는 개념을 추가해야 한다. 어떻게? #1과 #11을 보면, Initial statement에 pygame.time.Clock()함수가, Always문에 tick(60)함수가 있음을 확인할 수 있다. 60이라는 수는 여기서 FPS(Frame Per Second)를 의미한다. FPS가 1초에 화면이 얼마나 자주 바뀌는지를 의미한다. 화면을 바꾸는(업데이트하는) 파이게임의 함수는 무엇인가? 바로 Pygame.display.update() 함수이다. 그러므로, FPS는 1초에 Always문이 실행되는 횟수를 의미하게 된다. 이는 Always문 속에는 단 하나의 Pygame.display.update() 함수가 존재하기 때문이다. FPS는 일종의 선택적인 딜레이 함수와 같은 기능(프로그램 처리 속도에 따라)을 한다, 선택적인 가속 함수가 아니므로, FPS값이 너무 크면 FPS대로 작동하지 않을 수 있다. 우리가 프로젝트 내에서 시간(FPS)을 고정시켜 두면, 특정 게임 오브젝트의 적절한 변위만 찾아내면 그 오브젝트의 속도를 정할 수 있다. pygame.time.Clock()은 게임이 시작되기 이전 속도를 고정시키는 기능을 한다. tick함수는 Pygame.display.update()보다 나중에 와야 한다. 왜냐하면 tick함수는 화면이 몇 번 업데이트되었는지를 계산하기 때문이다. Pygame.display.update() 함수보다 나중에 실행되야 하는 몇 안되는 함수 중 하나이다. - -화면이 업데이트 될 때, 시간을 고정하는 방법을 알았다. 정지된 화면보다는 정신없이 움직이는 화면이 게임에선 많으므로, 이를 반드시 알고 있어야 한다. 그러나, 이 프로젝트는 결과가 너무 쉽게 예측되기 때문에 게임이 아닌 것처럼 보인다는 단점은 아직도 있다. (결과를 바꿀 입력이 없으므로) 이젠, 입력 로직이 추가 되어야만 한다. - - -<참고 코드> :: - - import pygame, sys - from pygame.locals import* - - white = (255,255,255) - red = (255,0,0) - green = (0,255,0) - pygame.init() - pygame.display.set_caption("Moving World Project") - myScreen = pygame.display.set_mode((640, 480)) - myTextFont = pygame.font.Font("HoonWhitecatR.ttf", 32) - myText = myTextFont.render("Moving World!", True, red, green) - myTextArea = myText.get_rect() - myTextArea.center = (320, 240) - fpsClock = pygame.time.Clock() #1 - x = 0 #2 - y = 0 #3 - moveRight = 1 #4 - moveUp= 1 #5 - - while True: - if (moveRight == 1): #6 - x = x + 1 - if (x >= 320 - 75): - moveRight = 0 - elif (moveRight == 0): #7 - x = x - 1 - if (x <= -320 + 75): - moveRight = 1 - - if (moveUp == 1): #8 - y = y + 1 - if (y >= 240 - 15): - moveUp = 0 - elif (moveUp == 0): #9 - y = y - 1 - if (y <= -240 + 15): - moveUp = 1 - - - - myTextArea.center = (320 + x, 240 + y) #10 - - myScreen.fill(white) - myScreen.blit(myText, myTextArea) - - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - - pygame.display.update() - fpsClock.tick(60) #11 diff --git "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/4.\355\205\215\354\212\244\355\212\270 \354\241\260\354\242\205/\352\270\260\354\264\210 \354\236\205\353\240\245.rst" "b/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/4.\355\205\215\354\212\244\355\212\270 \354\241\260\354\242\205/\352\270\260\354\264\210 \354\236\205\353\240\245.rst" deleted file mode 100644 index d0e9c499d4..0000000000 --- "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/4.\355\205\215\354\212\244\355\212\270 \354\241\260\354\242\205/\352\270\260\354\264\210 \354\236\205\353\240\245.rst" +++ /dev/null @@ -1,151 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -기초 입력 -==================================== - -==================================== --새로운 입력은 새로운 이벤트 -==================================== -생각해보면, 우리는 무언가를 출력하는 방법을 먼저 배우고(“Hello World”를 생각해봐라) 무언가를 입력하는 방법은 나중에 배운다. 왜 그런가? 왜냐면 입력은 몇몇 프로그램에선 필수조건이 아니지만, 출력은 모든 프로그램에선 항상 필수조건이기 때문이다. (프로그램의 정의: 0개 이상의 입력, 1개 이상의 출력) 그러나, 모든 게임은 입력이 필요하다. 그것이 우리는 “나는 게임을 Play한다”라고 말하는 이유이다. Play라는 단어는 몸의 일부분(아마도 손가락)을 움직인다는 뜻이다. 어쨌든, 이 프로젝트가 진짜 게임이 되기 위해 입력 로직을 추가해보자. - - -.. image:: ../../../assets/Bagic-INPUT-sourcecode.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("Bagic-INPUT-sourcecode.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -.. image:: ../../../assets/Bagic-INPUT-resultscreen.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 220, 140 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("Bagic-INPUT-resultscreen.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - - -(Controlling World 프로젝트의 소스 코드 일부 와 실행 결과) - -(Controlling World가 키보드 방향키를 누르면 해당 방향으로 움직인다.) - -이전 프로젝트와 비교하여 2개의 큰 차이점이 생겼다. 첫째는 #5에 KEYDOWN 이벤트가 트리거 되었는지 아닌지를 판단하는 것이다. 다른 줄들은 이전의 알고리즘의 약간 다르게 동작하도록 바꾼 것에 불과하다. 똑같은 명령어가 Event문 앞에 있느냐 뒤에 있느냐 결과는 완전히 달라질 수 있음을 우리는 알고 있다. 좌표를 업데이트하는 경우, Event문이 종료되고 이루어짐에 주목해라. (세팅 된 후 업데이트된다. 그것이 두번째 차이점이다.) 객체 event.key는 키보드에 마지막으로 눌린 키를 의미한다. 구체적인 키의 이름을 보아라. K_UP, K_LEFT, K_DOWN, K_RIGHT. 매우 직관적인 K_시리즈이다. (Header의 pygame.locals로부터 이용할 수 있다.) 다른 키의 이름으로는 K_8, K_a, K_L, K_LCTRL, K_DELETE, L_F4등이 있다. 이런 키들도 추가적인 도움 없이 직관적으로 이해할 수 있다. 모든 키 이름 목록은 `https://pyga.me/docs/ref/key.html#pygame.key.name` 에서 확인할 수 있다. - -KEYDOWN은 “이 키는 이전에는 눌리지 않았지만, 지금은 눌렸다.”를 의미하고, “이전부터 지금까지 계속 눌린 채로 있다.”를 의미하지는 않는다. 눌려있는 경우를 다루기 위해서는, KEYUP이라는 이벤트를 추가적으로 확인해야 한다. (변수와 알고리즘이 더 추가된다) 이는 심화 부분에서 다루겠다. - -입력을 추가하는 것은 단순히 이벤트 인자를 추가하는 것이기 때문에 쉽다. 이제 게임 프로젝트는 완성되었다. 왜냐하면 프로젝트가 출력, 처리, 입력을 가지고 있기 때문이다. 맞는가? 아니다. 이 프로젝트는 게임 오브젝트간 상호작용이 전혀 없고, 플레이 규칙(제약조건(HP, 시간 등)도 없고 점수도 없다)이 없고, 즐길 것(동기부여 요소, 입력 출력의 다양성, 컨텐츠)이 없기 때문에 게임이라고 불릴 수 없다. 우선, 게임의 인터페이스/시스템을 풍성하게 하기 위해 우리는 심화된 입력(마우스 상태 반영), 처리(적절한 함수화), 출력(이미지, 소리 및 내부 데이터 시각화 방법)을 알아야 한다. 물론, 기초 단계에서의 경험이 반드시 도움이 된다. 심화 단계로 가보자! - - -<참고 코드> :: - - import pygame, sys - from pygame.locals import* - - white = (255,255,255) - red = (255,0,0) - green = (0,255,0) - pygame.init() - pygame.display.set_caption("Controlling World Project") - myScreen = pygame.display.set_mode((640, 480)) - myTextFont = pygame.font.Font("HoonWhitecatR.ttf", 32) - myText = myTextFont.render("Controlling World!", True, red, green) - myTextArea = myText.get_rect() - myTextArea.center = (320, 240) - fpsClock = pygame.time.Clock() - x = 0 - y = 0 - moveRight = 0 #1 - moveDown = 0 #2 - - while True: - moveRight = 0 #3 - moveDown = 0 #4 - myTextArea.center = (320 + x, 240 + y) - myScreen.fill(white) - myScreen.blit(myText, myTextArea) - - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - elif event.type == KEYDOWN: #5 - if event.key == K_UP: - moveDown = -1 - moveRight = 0 - elif event.key == K_LEFT: - moveDown = 0 - moveRight = -1 - elif event.key == K_DOWN: - moveDown = 1 - moveRight = 0 - elif event.key == K_RIGHT: - moveDown = 0 - moveRight = 1 - - if(moveRight == 1): #6 - x = x + 10 - elif(moveRight == -1): #7 - x = x - 10 - if(moveDown == 1): #8 - y = y + 10 - elif(moveDown == -1): #9 - y = y - 10 - - pygame.display.update() diff --git "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/5.HP\353\260\224/\354\213\254\355\231\224 \354\266\234\353\240\245 \352\267\270\353\246\254\352\263\240 \354\213\254\355\231\224 \354\262\230\353\246\254.rst" "b/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/5.HP\353\260\224/\354\213\254\355\231\224 \354\266\234\353\240\245 \352\267\270\353\246\254\352\263\240 \354\213\254\355\231\224 \354\262\230\353\246\254.rst" deleted file mode 100644 index 0033513b5a..0000000000 --- "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/5.HP\353\260\224/\354\213\254\355\231\224 \354\266\234\353\240\245 \352\267\270\353\246\254\352\263\240 \354\213\254\355\231\224 \354\262\230\353\246\254.rst" +++ /dev/null @@ -1,275 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -그리고 심화 처리 - 함수화 -==================================== - -우선, 텍스트가 아닌, 도형을 시각화 하겠다. HP 바는 어떤가? 만약 HP의 최대값이 고정되어 있고 오직 현재 HP 값만이 변한다면, 이 두 데이터를 출력하는 가장 쉬운 방법은 무엇인가? - -.. image:: ../../../assets/AdvancedOutputProcess1.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputProcess1.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedOutputProcess2.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputProcess2.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedOutputProcess3.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputProcess3.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -변수의 값이 변할 때마다 텍스트를 다시 렌더링 하기만 하면 된다. 변수의 값은 어떻게 바꾸는가? 그것은 Event문에서 이루어진다. (키보드 위 또는 아래를 눌러 HP를 조절하게 하였다.) 이전과 동일한 방법이다. 하지만, 이것들은 여전히 텍스트이다. 아직 충분히 시각화 되지 않는다. 이 데이터들을 어떻게 더 상세하게 시각화 할까? 총 탄창에서 아이디어를 따올 수 있다. HP는 정수 값이고, 불연속적 값을 가지므로, 아래와 같이 출력될 수 있다. - -.. image:: ../../../assets/AdvancedOutputProcess4.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputProcess4.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedOutputProcess5.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputProcess5.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedOutputProcess6.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputProcess6.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -훨씬 나아졌다. 그리는 로직은 #6을 확인하면 된다. 로직은 단순하다. 먼저, 큰 검은 색 직사각형을 그린다. 그 다음, 현재 HP을 따져서 작은 빨간 색 직사각형들을 0개 또는 최대 개수만큼 그린다. 마지막으로, 작은 직사각형들에 하얀 테두리를 그린다. pygame.draw.rect 함수에선 위치 변수로 4개의 매개 변수가 사용된 것을 확인할 수 있는데 (첫번째 변수는 캔버스 변수이고, 두번째 변수는 색상 변수, 네번째 변수는 두께 변수이다.) 이 4개의 매개 변수의 용도가 무엇인지는 직접 설명하는 것보다, 직접 값을 변경하면서 확인하는 것이 가장 쉽게 이해할 수 있다. 3개의 값이 20일 때 하나의 값 만을 10또는 30으로 바꿔 보아라! - -그리고, 이제는 본격적으로 함수화를 해야 한다. Always문과 Event문을 main함수에 담았는데, 이 경우 main함수를 프로그램이 찾을 수 있도록 #7에서 추가적인 처리를 해야 한다. 그 다음 drawHP라는 새로운 함수를 만들었다. 게임에서의 함수화 아이디어는 GUI 프로그램을 만들 때의 함수화 아이디어와 크게 다르지 않다. 예를 들면, 하나의 변수를 출력하는 하나의 출력 함수를 각각 만들어 두는 것이 좋을 것이다. 물론, 각각의 변수가 출력 될 좌표를 정하는 것은 화면 전체를 디자인할 때 선행되어야 할 것이다. - -<참고 코드> :: - - import pygame, sys - from pygame.locals import* - - maxHP = 10 - white = (255,255,255) - gray = (127,127,127) - black = (0,0,0) - red = (255,0,0) - green = (0,255,0) - blue = (0,0,255) - pygame.init() - pygame.display.set_caption("HP bar Project") - width = 640 #1 - height = 480 #2 - myScreen = pygame.display.set_mode((width, height)) - myTextFont = pygame.font.Font("HoonWhitecatR.ttf", 32) - myText = myTextFont.render((str(maxHP) + "/" + str(maxHP)), True, red, gray) - myTextArea = myText.get_rect() - myTextArea.center = (width/2, height/2) #3 - fpsClock = pygame.time.Clock() - - def main(): #4 - HP = 5 - - while True: - myText = myTextFont.render((str(HP) + "/" + str(maxHP)), True, red, gray) - - myScreen.fill(gray) - - myScreen.blit(myText, myTextArea) - drawHP(HP) #5 - - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - elif event.type == KEYDOWN: - if event.key == K_UP: - if HP != 10: - HP = HP + 1 - elif event.key == K_DOWN: - if HP != 0: - HP = HP - 1 - - pygame.display.update() - fpsClock.tick(60) - - def drawHP(HP): #6 - r = int((height - 40) / maxHP) - - pygame.draw.rect(myScreen, black, (20, 20, 20, 20 + ((maxHP - 0.5) * r))) - - for i in range(maxHP): - if HP >= (maxHP - i): - pygame.draw.rect(myScreen, red, (20, 20 + (i * r), 20, r)) - pygame.draw.rect(myScreen, white, (20, 20 + (i * r), 20, r), 1) - - return - - if __name__ == '__main__': #7 - main() diff --git "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/6.\353\262\204\355\212\274\353\223\244/\354\213\254\355\231\224 \354\236\205\353\240\245 \352\267\270\353\246\254\352\263\240 \354\213\254\355\231\224 \354\266\234\353\240\245.rst" "b/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/6.\353\262\204\355\212\274\353\223\244/\354\213\254\355\231\224 \354\236\205\353\240\245 \352\267\270\353\246\254\352\263\240 \354\213\254\355\231\224 \354\266\234\353\240\245.rst" deleted file mode 100644 index ba068bd05b..0000000000 --- "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/6.\353\262\204\355\212\274\353\223\244/\354\213\254\355\231\224 \354\236\205\353\240\245 \352\267\270\353\246\254\352\263\240 \354\213\254\355\231\224 \354\266\234\353\240\245.rst" +++ /dev/null @@ -1,268 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -그리고 심화 출력 – 버튼 -==================================== - -KEYDOWN이 사용되었지만, 아직도 이 게임이 완전한 GUI가 아닌 것처럼 보이는 이유는 GUI가 입력은 없고 오직 출력(프린트)하는 데에만 사용되었기 때문이다. GUI에서의 입력이란 특정한 위치에서의 마우스 이벤트를 처리하는 것이다. HP를 증가시키거나 감소시키는 버튼 2개를 만드는 것은 어떨까? - -.. image:: ../../../assets/AdvancedInputOutput1.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedInputOutput1.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedInputOutput2.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedInputOutput2.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -버튼 2개를 만드는 것은 쉽다. 버튼을 보면, 뭔가 특이한 효과가 적용되어 있음을 알 수 있다. 어떻게 한 것인가? 이전의 아이디어처럼 단순하다. 첫째, 큰 정사각형을 그린다. 둘째, 내용은 없고 두께만 있는 작은 정사각형을 그린다. 하지만 이 버튼들은 아직 출력용이다. 이 버튼들을 위한 클릭 가능 공간을 만들어야 한다. - -.. image:: ../../../assets/AdvancedInputOutput3.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedInputOutput3.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedInputOutput4.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedInputOutput4.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedInputOutput5.gif - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedInputOutput5.gif") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -이제 Event문에 MOUSEBUTTONUP이 추가되었다. 마우스가 UP 된 것은 키보드가 DOWN된 것과 동일한 의미를 가진다. 만약 MOUSEBUTTONUP이 활성화되면, event.pos는 x값과 y값을 기록해야 하는데, 이 것은 클릭 지점을 나타낸다. 그러므로, 클릭이 특정 정사각형 내부에서 일어났는지 아닌 지는 collidepoint를 확인하면 된다. 만약 내부였다면, “사용자가 특정 영역 내부를 클릭했다”를 의미하게 된다. 그 다음, 변수를 업데이트하는 적절한 처리만이 필요하게 된다. -입력을 위한 두 변수가 존재하고, (Event문에 있음) -(270, 425, 45, 45)와 (325, 425, 45, 45). -출력을 위한 두 변수도 존재함을 확인하라. (drawButtons에 있음) -(margin, height - r -10 , r, r)과 (margin + r + r_margin, height - r - 10, r, r). -버튼의 경우, 입력 영역과 출력 영역이 동일해야 한다. 그렇지 않다면, 버튼의 판정 범위는 오해의 소지가 될 수 있다! 변수(출력 용)들을 구체적인 계산을 통해 상수(입력 용) 값을 알아내기 싫다면, 이 변수들을 동일한 변수로 두는 것이 좋은 생각일 것이다. 두 영역을 하나로 묶을 수 있는 함수는 없으므로, 이 점은 항상 신경 써야 한다. - -<참고 코드> :: - - import pygame, sys - from pygame.locals import* - - maxHP = 10 - white = (255,255,255) - gray = (127,127,127) - black = (0,0,0) - red = (255,0,0) - green = (0,255,0) - blue = (0,0,255) - pygame.init() - pygame.display.set_caption("Array buttons Project") - width = 640 - height = 480 - myScreen = pygame.display.set_mode((width, height)) - myTextFont = pygame.font.Font("HoonWhitecatR.ttf", 32) - myText = myTextFont.render((str(maxHP) + "/" + str(maxHP)), True, red, gray) - myTextArea = myText.get_rect() - myTextArea.center = (width/2, height/2) - fpsClock = pygame.time.Clock() - - def main(): - HP = 5 - - while True: - myText = myTextFont.render((str(HP) + "/" + str(maxHP)), True, red, gray) - - myScreen.fill(gray) - - myScreen.blit(myText, myTextArea) - drawHP(HP) - drawButtons() - - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - elif event.type == KEYDOWN: - if event.key == K_UP: - if HP != 10: - HP = HP + 1 - elif event.key == K_DOWN: - if HP != 0: - HP = HP - 1 - elif event.type == MOUSEBUTTONUP: #1 - x, y = event.pos - if pygame.Rect(270, 425, 45, 45).collidepoint(x, y): - if HP != 10: - HP = HP + 1 - elif pygame.Rect(325, 425, 45, 45).collidepoint(x, y): - if HP != 0: - HP = HP - 1 - - pygame.display.update() - fpsClock.tick(60) - - def drawHP(HP): - r = int((height - 40) / maxHP) - - pygame.draw.rect(myScreen, black, (20, 20, 20, 20 + ((maxHP - 0.5) * r))) - - for i in range(maxHP): - if HP >= (maxHP - i): - pygame.draw.rect(myScreen, red, (20, 20 + (i * r), 20, r)) - pygame.draw.rect(myScreen, white, (20, 20 + (i * r), 20, r), 1) - - return - - def drawButtons(): - r = 45 - r_margin = 10 - colors = [red, black] - - num = 2 - margin = int((width - ((r * num) + (r_margin * (num - 1)))) / 2) - for i in range(0, num): - left = margin + (i * r) + (i * r_margin) - up = height - r - 10 - pygame.draw.rect(myScreen, colors[i], (left, up, r, r)) - pygame.draw.rect(myScreen, gray, (left + 2, up + 2, r - 4, r - 4), 2) - - if __name__ == '__main__': - main() diff --git "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/7.\352\262\214\354\236\204\355\214\220/\354\213\254\355\231\224 \354\266\234\353\240\245 \352\267\270\353\246\254\352\263\240 \354\241\260\352\270\210 \353\215\224.rst" "b/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/7.\352\262\214\354\236\204\355\214\220/\354\213\254\355\231\224 \354\266\234\353\240\245 \352\267\270\353\246\254\352\263\240 \354\241\260\352\270\210 \353\215\224.rst" deleted file mode 100644 index dbe3e9db71..0000000000 --- "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/7.\352\262\214\354\236\204\355\214\220/\354\213\254\355\231\224 \354\266\234\353\240\245 \352\267\270\353\246\254\352\263\240 \354\241\260\352\270\210 \353\215\224.rst" +++ /dev/null @@ -1,258 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -그리고 조금 더! -==================================== - -사실, 모든 것들이 게임 같아 보이진 않는다. 이제, 이 프로그램에 규칙을 추가하려 한다. 그러면, 이 프로그램은 게임이 된다. 규칙은 간단하다: 5x5 2차원 배열에서 빨간 블록, 검은 블록의 수를 세고, 더 많은 색상의 블록을 고르는 것이다! 정답이라면 HP는 증가하고 오답이라면, HP는 감소한다. 그 다음, 다음 문제를 위한 새로운 2차원 배열이 그려진다! 대단히 단순하지만 이 튜토리얼 내에서 만들어 질 수 있는 게임이다. 우선, 2차원 배열을 만들고 출력해야 한다. 어떻게? 우리는 정수 데이터(0차원 배열과 같음)나 두 버튼(1차원 배열과 같음)을 출력하는 법을 알 고 있다. 2차원 배열은 요소 하나만 더 추가되면 된다. - -.. image:: ../../../assets/AdvancedOutputAlpha1.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputAlpha1.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedOutputAlpha2.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputAlpha2.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -.. image:: ../../../assets/AdvancedOutputAlpha3.webp - :class: inlined-right - -.. code-block:: python - :linenos: - - import sys, pygame - pygame.init() - - size = width, height = 320, 240 - speed = [2, 2] - black = 0, 0, 0 - - screen = pygame.display.set_mode(size) - - ball = pygame.image.load("AdvancedOutputAlpha3.webp") - ballrect = ball.get_rect() - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: sys.exit() - - ballrect = ballrect.move(speed) - if ballrect.left < 0 or ballrect.right > width: - speed[0] = -speed[0] - if ballrect.top < 0 or ballrect.bottom > height: - speed[1] = -speed[1] - - screen.fill(black) - screen.blit(ball, ballrect) - pygame.display.flip() - -generateboard 함수는 무작위로 만들어진 2차원 배열과 빨간 블록, 검은 블록의 개수를 반환한다. 더 설명할 필요도 없다. 또한, printboard 함수는 1차원 배열처럼 2차원 배열을 출력한다. 출력 색상은 board[i][j]가 1인지 아닌 지에 따라 달라진다. 이 게임판은 단순히 출력 용이다. 테두리를 처리하려면 부분의 크기를 가지고 전체 크기를 계산해야 해서 짜증날 수 있다. 이것은 프롤로그에서 언급한 대로, 파이게임 갖는 특성 (실행 결과는 GUI이지만 코드 작성은 CUI) 때문이다. - -사실, 이 구현한 게임은 개선의 여지가 많다. 버튼을 이미지 파일로 바꾸면? 정답이거나 오답일 때 효과음을 넣으면? 시간 제한을 넣으면? 정답이거나 오답일 때 시각적 효과를 넣으면? 게임판을 더 크게 하고 색상을 더 다양히 넣는다면? 이 인터페이스를 가지고 Flood-it을 구현한다면? 구현한 게임이 단순하기 때문에 선택지는 많다. - -<참고 코드> :: - - import pygame, sys, random - from pygame.locals import* - - maxHP = 10 - white = (255,255,255) - gray = (127,127,127) - black = (0,0,0) - red = (255,0,0) - green = (0,255,0) - blue = (0,0,255) - pygame.init() - pygame.display.set_caption("Red or Black Project") - width = 640 - height = 480 - myScreen = pygame.display.set_mode((width, height)) - myTextFont = pygame.font.Font("HoonWhitecatR.ttf", 32) - myText = myTextFont.render((str(maxHP) + "/" + str(maxHP)), True, red, gray) - myTextArea = myText.get_rect() - myTextArea.center = (width/2, height/2) - fpsClock = pygame.time.Clock() - - def main(): - HP = 5 - board, b_red, b_black = generateBoard(5,5) #1 - - while True: - myText = myTextFont.render((str(HP) + "/" + str(maxHP)), True, red, gray) - - myScreen.fill(gray) - - myScreen.blit(myText, myTextArea) - drawHP(HP) - drawButtons() - drawBoard(board) #2 - - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - - elif event.type == KEYDOWN: - if event.key == K_UP: - if HP != 10: - HP = HP + 1 - elif event.key == K_DOWN: - if HP != 0: - HP = HP - 1 - elif event.type == MOUSEBUTTONUP: - x, y = event.pos - - if pygame.Rect(270, 425, 45, 45).collidepoint(x, y): #3 - if b_red >= b_black: - if HP != 10: - HP = HP + 1 - board, b_red, b_black = generateBoard(5,5) - elif b_red < b_black: - if HP != 0: - HP = HP - 1 - board, b_red, b_black = generateBoard(5,5) - - elif pygame.Rect(325, 425, 45, 45).collidepoint(x, y): #4 - if b_red <= b_black: - if HP != 10: - HP = HP + 1 - board, b_red, b_black = generateBoard(5,5) - elif b_red > b_black: - if HP != 0: - HP = HP - 1 - board, b_red, b_black = generateBoard(5,5) - - pygame.display.update() - fpsClock.tick(60) - - def drawHP(HP): - r = int((height - 40) / maxHP) - - pygame.draw.rect(myScreen, gray, (20, 20, 20, 20 + ((maxHP - 0.5) * r))) - - for i in range(maxHP): - if HP >= (maxHP - i): - pygame.draw.rect(myScreen, blue, (20, 20 + (i * r), 20, r)) - pygame.draw.rect(myScreen, white, (20, 20 + (i * r), 20, r), 1) - - return - - def drawButtons(): - r = 45 - r_margin = 10 - colors = [red, black] - - num = 2 - margin = int((width - ((r * num) + (r_margin * (num - 1)))) / 2) - - for i in range(0, num): - left = margin + (i * r) + (i * r_margin) - up = height - r - 10 - pygame.draw.rect(myScreen, colors[i], (left, up, r, r)) - pygame.draw.rect(myScreen, gray, (left + 2, up + 2, r - 4, r - 4), 2) - - def generateBoard(width, height): #5 - board = [] - b_red = 0 - b_black = 0 - - for x in range(width): - column = [] - for y in range(height): - column.append(random.randint(0, 1)) - board.append(column) - - for x in range(width): - for y in range(height): - if(board[x][y] == 1): - b_red = b_red + 1 - elif(board[x][y] == 0): - b_black = b_black + 1 - - return board, b_red, b_black - - def drawBoard(board): #6 - r = 50 - b_width = 5 - b_height = 5 - l_margin = int((width - (b_width * r)) / 2) - u_margin = int((height - (b_height * r)) / 2) - - for x in range(5): - for y in range(5): - left = x * r + l_margin - up = y * r + u_margin - if board[x][y] == 1: - color = red; - elif board[x][y] == 0: - color = black - pygame.draw.rect(myScreen, color, (left, up, r, r)) - - left = l_margin - up = u_margin - pygame.draw.rect(myScreen, white, (left-1, up-1, r * 5 + 1, r * b_height + 1), 1) - - if __name__ == '__main__': - main() diff --git "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/8.\354\227\220\355\225\204\353\241\234\352\267\270/\354\227\220\355\225\204\353\241\234\352\267\270.rst" "b/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/8.\354\227\220\355\225\204\353\241\234\352\267\270/\354\227\220\355\225\204\353\241\234\352\267\270.rst" deleted file mode 100644 index 20517bb99b..0000000000 --- "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/8.\354\227\220\355\225\204\353\241\234\352\267\270/\354\227\220\355\225\204\353\241\234\352\267\270.rst" +++ /dev/null @@ -1,17 +0,0 @@ -==================================== -Author: Youngwook Kim (Korean) -==================================== - -==================================== -Contact: rumia0601@gmail.com -==================================== - -==================================== -에필로그 -==================================== - -그러나, 튜토리얼은 여기에서 끝이 난다. 이 튜토리얼은 파이게임의 극소수만을 다뤘다. 하지만 걱정하지 마라. 프로그램은 사람이 할 수 있는 가장 창의적인 활동이다. 임마누엘 칸트는 “천재성이란 어떤 대상에 규칙을 부여할 수 있는 능력이다”라고 말했다. 프로그래밍은 규칙을 만들어서 컴퓨터에게 입력시키는 것이다. 규칙이 만들어진다면, 컴퓨터는 규칙 내에서 무엇이든지 할 수 있다. 그러므로, 경우의 수가 매우 커지게 된다. - -결론이 무엇인가? 출력이 입력보다 크다는 것이다. 우리는 우리의 지식만으로 지식보다 더 폭넓은 프로그램을 구현할 수 있다. 또는 우리는 새로운 지식을 기존의 지식에 연결시키면서 습득할 수도 있다. 그것이 프로그래밍의 특성이다. 게임도 마찬가지이다. “난수”라는 개념은 모든 게임(이미 구현한 게임도 포함!)에서 대단히 중요한 개념이다. 난수까지 고려되었을 때 경우의 수는 매우 커지게 된다. 만약 하나의 난수가 다른 난수까지 영향을 미치게 된다면, “눈사태”와 같은 효과가 나게 된다. 그것이 게임이 흥미로운 이유이다. “난수”라는 개념은 소설, 음악, 영화 등은 가질 수 없는 게임만의 특성이다. 테트리스를 생각해 보아라. 알렉세이 파지트노프가 테트리스를 위해 얼만큼의 시간을 투자했을까? 이 시간이 35년 넘게 전세계 사람들이 플레이 한 시간보다 클까? 이것이 바로 프로그래밍과 게임이 갖는 두 특성이 완벽히 발휘된 예시이다. - -그러므로, 게임을 만드는 것은 눈사태를 일으키는 것과 같다. 이제 아무 게임이나 만들 시간이다! 배우고, 활용하고, 시행 착오를 겪어 보자! diff --git "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/\352\260\234\354\232\224.rst" "b/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/\352\260\234\354\232\224.rst" deleted file mode 100644 index 6dfe791961..0000000000 --- "a/docs/reST/tutorials/ko/\353\271\250\352\260\204\353\270\224\353\241\235 \352\262\200\354\235\200\353\270\224\353\241\235/\352\260\234\354\232\224.rst" +++ /dev/null @@ -1,31 +0,0 @@ -한국어 튜토리얼 -============================= - -한국어 튜토리얼 ------------------------------ - -| - -:doc:`1 부 <1.프롤로그/소개>` - 프롤로그/소개 - -:doc:`2 부 <2.텍스트 출력/기초 템플릿과 출력>` - 텍스트 출력 - -:doc:`3 부 <3.텍스트 이동/기초 처리>` - 텍스트 이동 - -:doc:`4 부 <4.텍스트 조종/기초 입력>` - 텍스트 조종 - -:doc:`5 부 <5.HP바/심화 출력 그리고 심화 처리>` - HP바 - -:doc:`6 부 <6.버튼들/심화 입력 그리고 심화 출력>` - 버튼들 - -:doc:`7 부 <7.게임판/심화 출력 그리고 조금 더>` - 게임판 - -:doc:`8 부 <8.에필로그/에필로그>` - 에필로그