http___programarcadegames.com_index.php_chapter_introduction_to_graphics_lang_tr_2.xml
1.1 2.1 3.1 4.1 5.1 5.2 5.3 6.1 6.2 6.3 6.4 7.1 7.2 8.1 8.2 8.3 8.4 9.1 10.1 11.1 12.1 13.1 14.1 14.2 14.3 15.1 16.1 16.2 16.3 17.1 17.2 17.3 17.4 17.5 18.1 19.1 19.2 19.3 19.4 19.5 20.1 21.1 21.2 21.3 22.1 22.2 23.1 24.1 24.2 24.3 24.4 25.1 25.2 25.3 25.4 27.1 28.1 29.1 30.1 30.2 30.3 30.4 31.1 32.1 32.2 32.3 33.1 33.2 33.3 34.1 35.1 35.2 36.1 37.1 38.1 39.1 40.1 41.1 42.1 42.2 42.3 42.4 43.1 44.1 44.2 45.1 45.2 46.1 47.1 48.1 49.1 50.1 50.2 50.3 51.1 51.2 51.3 51.4 51.5 51.6 52.1 52.2 52.3 52.4 52.5 52.6 52.7 52.8 52.9 52.10 52.11 52.12 53.1 54.1 55.1 55.2 55.3 55.4 56.1 57.1 58.1 59.1 59.2 59.3 60.1 60.2 60.3 60.4 61.1 61.2 61.3 61.4 61.5 61.6 62.1 62.2 63.1 63.2 63.3 63.4 63.5 64.1 65.1 66.1 66.2 66.3 67.1 67.2 67.3 67.4 67.5 67.6 67.7 67.8 67.9 67.10 67.11 67.12 67.13 67.14 67.15 67.16 67.17 67.18 67.19 68.1 69.1 70.1 71.1 72.1 74.1 75.1 75.2 76.1 77.1 78.1 79.1 80.1 81.1 82.1 83.1 84.1 85.1 86.1
Program Arcade GamesWith Python And Pygame Chapter 10: Controllers and Graphics How do we get objects to move using the keyboard, mouse, or a game controller? 10.1 Introduction So far, we've shown how to animate items on the screen, but not how to interact with them. How do we use a mouse, keyboard, or game controller to control the action on-screen? Thankfully this is pretty easy. To begin with, it is necessary to have an object that can be moved around the screen. The best way to do this is to have a function that takes in an x and y coordinate, then draws an object at that location. So back to Chapter 9! Let's take a look at how to write a function to draw an object. All the Pygame draw functions require a screen parameter to let Pygame know which window to draw on. We will need to pass this in to any function we create to draw an object on the screen. The function also needs to know where to draw the object on the screen. The function needs an x and y. We pass the location to the function as a parameter. Here is example code that defines a function that will draw a snowman when called: def draw_snowman(screen, x, y): # Draw a circle for the head pygame.draw.ellipse(screen, WHITE, [35 + x, y, 25, 25]) # Draw the middle snowman circle pygame.draw.ellipse(screen, WHITE, [23 + x, 20 + y, 50, 50]) # Draw the bottom snowman circle pygame.draw.ellipse(screen, WHITE, [x, 65 + y, 100, 100]) Then, in the main program loop, multiple snowmen can be drawn, as seen in Figure 10.1. # Snowman in upper left draw_snowman(screen, 10, 10) # Snowman in upper right draw_snowman(screen, 300, 10) # Snowman in lower left draw_snowman(screen, 10, 300) A full working example is available on-line at: ProgramArcadeGames.com/python_examples/f.php?file=functions_and_graphics.py Chances are, from a prior lab you already have a code that draws something cool. But how do you get that into a function? Let's take an example of code that draws a stick figure: # Head pygame.draw.ellipse(screen, BLACK, [96,83,10,10], 0) # Legs pygame.draw.line(screen, BLACK, [100,100], [105,110], 2) pygame.draw.line(screen, BLACK, [100,100], [95,110], 2) # Body pygame.draw.line(screen, RED, [100,100], [100,90], 2) # Arms pygame.draw.line(screen, RED, [100,90], [104,100], 2) pygame.draw.line(screen, RED, [100,90], [96,100], 2) This code can easily be put in a function by adding a function def and indenting the code under it. We'll need to bring in all the data that the function needs to draw the stick figure. We need the screen variable to tell the function what window to draw on, and an x and y coordinate for where to draw the stick figure. But we can't define the function in the middle of our program loop! The code should be removed from the main part of the program. Function declarations should go at the start of the program. We need to move that code to the top. See Figure 10.3 to help visualize. def draw_stick_figure(screen,x,y): # Head pygame.draw.ellipse(screen, BLACK, [96,83,10,10], 0) # Legs pygame.draw.line(screen, BLACK, [100,100], [105,110], 2) pygame.draw.line(screen, BLACK, [100,100], [95,110], 2) # Body pygame.draw.line(screen, RED, [100,100], [100,90], 2) # Arms pygame.draw.line(screen, RED, [100,90], [104,100], 2) pygame.draw.line(screen, RED, [100,90], [96,100], 2) Right now, this code takes in an x and y coordinate. Unfortunately it doesn't actually do anything with them. You can specify any coordinate you want, the stick figure always draws in in the same exact spot. Not very useful. The next code example literally adds in the x and y coordinate to the code we had before. def draw_stick_figure(screen, x, y): # Head pygame.draw.ellipse(screen, BLACK,[96+x,83+y,10,10],0) # Legs pygame.draw.line(screen, BLACK, [100+x,100+y], [105+x,110+y], 2) pygame.draw.line(screen, BLACK, [100+x,100+y], [95+x,110+y], 2) # Body pygame.draw.line(screen, RED, [100+x,100+y], [100+x,90+y], 2) # Arms pygame.draw.line(screen, RED, [100+x,90+y], [104+x,100+y], 2) pygame.draw.line(screen, RED, [100+x,90+y], [96+x,100+y], 2) But the problem is that the figure is already drawn a certain distance from the origin. It assumes an origin of (0, 0) and draws the stick figure down and over about 100 pixels. See Figure 10.4 and how the stick figure is not drawn at the (0, 0) coordinate passed in. By adding x and y in the function, we shift the origin of the stick figure by that amount. For example, if we call: draw_stick_figure(screen, 50, 50) The code does not put a stick figure at (50, 50). It shifts the origin down and over 50 pixels. Since our stick figure was already being drawn at about (100, 100), with the origin shift the figure is about (150, 150). How do we fix this so that the figure is actually drawn where the function call requests? Find the smallest x value, and the smallest y value as shown in Figure 10.5. Then subtract that value from each x and y in the function. Don't mess with the height and width values. Here's an example where we subtracted the smallest x and y values: Or, to make a program simpler, do the subtraction yourself: def draw_stick_figure(screen, x, y): # Head pygame.draw.ellipse(screen, BLACK, [1+x,y,10,10], 0) # Legs pygame.draw.line(screen, BLACK ,[5+x,17+y], [10+x,27+y], 2) pygame.draw.line(screen, BLACK, [5+x,17+y], [x,27+y], 2) # Body pygame.draw.line(screen, RED, [5+x,17+y], [5+x,7+y], 2) # Arms pygame.draw.line(screen, RED, [5+x,7+y], [9+x,17+y], 2) pygame.draw.line(screen, RED, [5+x,7+y], [1+x,17+y], 2) 10.2 Mouse Great, now we know how to write a function to draw an object at specific coordinates. How do we get those coordinates? The easiest to work with is the mouse. It takes one line of code to get the coordinates: pos = pygame.mouse.get_pos() The trick is that coordinates are returned as a list, or more specifically a non-modifiable tuple. Both the x and y values are stored in the same variable. So if we do a print(pos) we get what is shown in Figure 10.6. The variable pos is a tuple of two numbers. The x coordinate is in position 0 of array and the y coordinate is in the position 1. These can easily be fetched out and passed to the function that draws the item: # Game logic pos = pygame.mouse.get_pos() x = pos[0] y = pos[1] # Drawing section draw_stick_figure(screen, x, y) Getting the mouse should go in the “game logic” part of the main program loop. The function call should go in the “drawing” part of the main program loop. The only problem with this is that the mouse pointer draws right on top of the stick figure, making it hard to see, as shown in Figure 10.7. The mouse can be hidden by using the following code right before the main program loop: # Hide the mouse cursor pygame.mouse.set_visible(False) A full working example can be found here: ProgramArcadeGames.com/python_examples/f.php?file=move_mouse.py 10.3 Keyboard Controlling with the keyboard is a bit more complex. We can't just grab the x and y from the mouse. The keyboard doesn't give us an x and y. We need to: - Create an initial x and y for our start position. - Set a “velocity” in pixels per frame when an arrow key is pressed down. (keydown) - Reset the velocity to zero when an arrow key is released. (keyup) - Adjust the x and y each frame depending on the velocity. It seems complex, but this is just like the bouncing rectangle we did before, with the exception that the speed is controlled by the keyboard. To start with, set the location and speed before the main loop starts: # Speed in pixels per frame x_speed = 0 y_speed = 0 # Current position x_coord = 10 y_coord = 10 Inside the main while loop of the program, we need to add some items to our event processing loop. In addition to looking for a pygame.QUIT event, the program needs to look for keyboard events. An event is generated each time the user presses a key. A pygame.KEYDOWN event is generated when a key is pressed down. A pygame.KEYUP event is generated when the user lets up on a key. When the user presses a key, the speed vector is set to 3 or -3 pixels per frame. When the user lets up on a key the speed vector is reset back to zero. Finally, the coordinates of the object are adjusted by the vector, and then the object is drawn. See the code example below: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True # User pressed down on a key elif event.type == pygame.KEYDOWN: # Figure out if it was an arrow key. If so # adjust speed. if event.key == pygame. K_LEFT: x_speed = -3 elif event.key == pygame. K_RIGHT: x_speed = 3 elif event.key == pygame. K_UP: y_speed = -3 elif event.key == pygame. K_DOWN: y_speed = 3 # User let up on a key elif event.type == pygame.KEYUP: # If it is an arrow key, reset vector back to zero if event.key == pygame. K_LEFT or event.key == pygame. K_RIGHT: x_speed = 0 elif event.key == pygame. K_UP or event.key == pygame. K_DOWN: y_speed = 0 # Move the object according to the speed vector. x_coord += x_speed y_coord += y_speed # Draw the stick figure draw_stick_figure(screen, x_coord, y_coord) For a full example see: ProgramArcadeGames.com/python_examples/f.php?file=move_keyboard.py Note that this example does not prevent the character from moving off the edge of the screen. To do this, in the game logic section, a set of if statements would be needed to check the x_coord and y_coord values. If they are outside the boundaries of the screen, then reset the coordinates to the edge. The exact code for this is left as an exercise for the reader. The table below shows a full list of key-codes that can be used in Pygame: 10.4 Game Controller Game controllers require a different set of code, but the idea is still simple. To begin, check to see if the computer has a joystick, and initialize it before use. This should only be done once. Do it ahead of the main program loop: # Current position x_coord = 10 y_coord = 10 # Count the joysticks the computer has joystick_count = pygame.joystick.get_count() if joystick_count == 0: # No joysticks! print("Error, I didn't find any joysticks.") else: # Use joystick #0 and initialize it my_joystick = pygame.joystick. Joystick(0) my_joystick.init() A joystick will return two floating point values. If the joystick is perfectly centered it will return (0, 0). If the joystick is fully up and to the left it will return (-1, -1). If the joystick is down and to the right it will return (1, 1). If the joystick is somewhere in between, values are scaled accordingly. See the controller images starting at Figure 10.8 to get an idea how it works. Inside the main program loop, the values of the joystick returns may be multiplied according to how far an object should move. In the case of the code below, moving the joystick fully in a direction will move it 10 pixels per frame because the joystick values are multiplied by 10. # This goes in the main program loop! # As long as there is a joystick if joystick_count != 0: # This gets the position of the axis on the game controller # It returns a number between -1.0 and +1.0 horiz_axis_pos = my_joystick.get_axis(0) vert_axis_pos = my_joystick.get_axis(1) # Move x according to the axis. We multiply by 10 to speed up the movement. # Convert to an integer because we can't draw at pixel 3.5, just 3 or 4. x_coord = x_coord + int(horiz_axis_pos * 10) y_coord = y_coord + int(vert_axis_pos * 10) # Clear the screen screen.fill(WHITE) # Draw the item at the proper coordinates draw_stick_figure(screen, x_coord, y_coord) For a full example, see ProgramArcadeGames.com/python_examples/f.php?file=move_game_controller.py. Controllers have a lot of joysticks, buttons, and even “hat” switches. Below is an example program and screenshot that prints everything to the screen showing what each game controller is doing. Take heed that game controllers must be plugged in before this program starts, or the program can't detect them. """ Sample Python/Pygame Programs Simpson College Computer Science http://programarcadegames.com/ http://simpson.edu/computer-science/ Show everything we can pull off the joystick """ import pygame # Define some colors BLACK = (0, 0, 0) WHITE = (255, 255, 255) class TextPrint(object): """ This is a simple class that will help us print to the screen It has nothing to do with the joysticks, just outputting the information. """ def __init__(self): """ Constructor """ self.reset() self.x_pos = 10 self.y_pos = 10 self.font = pygame.font. Font(None, 20) def print(self, my_screen, text_string): """ Draw text onto the screen. """ text_bitmap = self.font.render(text_string, True, BLACK) my_screen.blit(text_bitmap, [self.x_pos, self.y_pos]) self.y_pos += self.line_height def reset(self): """ Reset text to the top of the screen. """ self.x_pos = 10 self.y_pos = 10 self.line_height = 15 def indent(self): """ Indent the next line of text """ self.x_pos += 10 def unindent(self): """ Unindent the next line of text """ self.x_pos -= 10 pygame.init() # Set the width and height of the screen [width,height] size = [500, 700] screen = pygame.display.set_mode(size) pygame.display.set_caption("My Game") # Loop until the user clicks the close button. done = False # Used to manage how fast the screen updates clock = pygame.time. Clock() # Initialize the joysticks pygame.joystick.init() # Get ready to print textPrint = TextPrint() # -------- Main Program Loop ----------- while not done: # EVENT PROCESSING STEP for event in pygame.event.get(): if event.type == pygame.QUIT: done = True # Possible joystick actions: JOYAXISMOTION JOYBALLMOTION JOYBUTTONDOWN # JOYBUTTONUP JOYHATMOTION if event.type == pygame.JOYBUTTONDOWN: print("Joystick button pressed.") if event.type == pygame.JOYBUTTONUP: print("Joystick button released.") # DRAWING STEP # First, clear the screen to white. Don't put other drawing commands # above this, or they will be erased with this command. screen.fill(WHITE) textPrint.reset() # Get count of joysticks joystick_count = pygame.joystick.get_count() textPrint.print(screen, "Number of joysticks: {}".format(joystick_count)) textPrint.indent() # For each joystick: for i in range(joystick_count): joystick = pygame.joystick. Joystick(i) joystick.init() textPrint.print(screen, "Joystick {}".format(i)) textPrint.indent() # Get the name from the OS for the controller/joystick name = joystick.get_name() textPrint.print(screen, "Joystick name: {}".format(name)) # Usually axis run in pairs, up/down for one, and left/right for # the other. axes = joystick.get_numaxes() textPrint.print(screen, "Number of axes: {}".format(axes)) textPrint.indent() for i in range(axes): axis = joystick.get_axis(i) textPrint.print(screen, "Axis {} value: {:>6.3f}".format(i, axis)) textPrint.unindent() buttons = joystick.get_numbuttons() textPrint.print(screen, "Number of buttons: {}".format(buttons)) textPrint.indent() for i in range(buttons): button = joystick.get_button(i) textPrint.print(screen, "Button {:>2} value: {}".format(i, button)) textPrint.unindent() # Hat switch. All or nothing for direction, not like joysticks. # Value comes back in an array. hats = joystick.get_numhats() textPrint.print(screen, "Number of hats: {}".format(hats)) textPrint.indent() for i in range(hats): hat = joystick.get_hat(i) textPrint.print(screen, "Hat {} value: {}".format(i, str(hat))) textPrint.unindent() textPrint.unindent() # ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT # Go ahead and update the screen with what we've drawn. pygame.display.flip() # Limit to 60 frames per second clock.tick(60) # Close the window and quit. # If you forget this line, the program will 'hang' # on exit if running from IDLE. pygame.quit() 10.5 Review 10.5.1 Multiple Choice Quiz Click here for a multiple-choice quiz. 10.5.2 Short Answer Worksheet Click here for the chapter worksheet. Click here for the chapter lab. You are not logged in. Log in here and track your progress. English version by Paul Vincent Craven Spanish version by Antonio Rodríguez Verdugo Russian version by Vladimir Slav Turkish version by Güray Yildirim Portuguese version by Armando Marques Sobrinho and Tati Carvalho Dutch version by Frank Waegeman Hungarian version by Nagy Attila Finnish version by Jouko Järvenpää French version by Franco Rossi Korean version by Kim Zeung-Il Chinese version by Kai Lin
1.1 2.1 3.1 4.1 5.1 6.1 7.1 8.1 9.1 10.1 11.1 12.1 13.1 14.1 15.1 16.1 17.1 18.1 19.1 20.1 21.1 22.1 23.1 24.1 25.1 26.1 27.1 28.1 29.1 30.1 31.1 32.1 33.1 34.1 35.1 36.1 37.1 38.1 39.1 41.1 42.1 43.1 44.1 45.1 46.1 47.1 48.1 49.1 50.1 51.1 52.1 53.1 54.1 55.1 56.1 57.1 58.1 59.1 60.1 61.1 62.1 63.1 64.1 65.1 66.1 67.1 68.1 69.1 70.1 71.1 72.1 73.1 74.1 75.1 76.1 77.1 78.1 79.1 80.1 81.1 82.1 83.1 84.1 85.1 86.1 87.1 88.1 89.1 90.1 91.1 92.1 93.1 94.1 95.1 96.1 97.1 98.1 99.1 100.1 101.1 102.1 103.1 104.1 105.1 106.1 107.1 108.1 109.1 110.1 111.1 112.1 113.1 114.1 115.1 116.1 117.1 118.1 119.1 120.1 121.1 122.1 123.1 124.1 125.1 126.1 127.1 128.1 129.1 130.1 131.1 132.1 133.1 134.1 135.1 136.1 137.1 138.1 139.1 140.1 141.1 143.1 144.1 145.1 146.1 147.1 148.1 149.1 150.1
Arcade Türü Oyun Programlamayıve Bilgisayar Bilimleri Öğrenin Chapter 5: Grafiklere Giriş Doğrudan grafik çizimlerine geçmek mükemmel olmakla birlikte, ilk olarak öğrenilecek birkaç şey var: - Bilgisayar x ve y koordinatlarını nasıl ele alır? Bu matematik derslerinde öğrendiğiniz koordinat sistemi gibi değildir. - Renkler nasıl belirtilir? Seçilebilecek milyonlarca renk olmakla birlikte, bilgisayara hangi rengin kullanılacağını söylemek sadece "kırmızı" demek kadar kolay değildir. - Çizim için boş bir pencere nasıl açılır? Her ressam bir tuvale ihtiyaç duyar. Bunun ardından, bu bölümde çizgilerin, dikdördgenlerin, elipslerin ve kavislerin nasıl çizileceğini gösterilecektir. 5.1 Bilgisayarın koordinat sistemleri Şekil 5.1'de de görüldüğü üzere (Wikimedia Commons'tan alınan grafik), Kartezyen koordinat sistemi çoğu insanın grafik çizerken kullandığı sistemdir. Bu okulun matematik derslerinde öğretilen standart sistemdir. Bilgisayar benzer, fakat biraz farklı bir koordinat sistemi kullanır. Neden farklı olduğunu anlamak birazcık bilgisayar tarihi gerektirir. 80'lerin başındayken, çoğu bilgisayar sistemi metin-bazlıydı ve grafikleri desteklemiyordu. Şekil 5.2 (Wikimedia Commons'un grafiği) , Apple ][ üzerinde çalışan eski bir elektronik çizelge programını gösteriyor. Metin ekrana yerleştirilirken, programcılar üst kısmı 1. satır olarak adlandırmaya başladı. Ekran aşağı doğru 24 satır ve karşıya doğru 40 satır devam etti. Düz metinde bile, ilkel grafikleri yapmak sadece klavyede bulunan Şekil 5.3'te de görülen karakterlerle mümkündü. Bu kadarkterler de üstte birinci satırdan başlıyordu. Karakter seti, kutuları ve diğer ilkel şekil çizimlerini içerecek şekilde genişletildi. Karakterler farklı renklerde çizilebildi. Şekil 5.4'deki gibi grafikler daha üst seviyeye ulaştı. İnternette “ASCII art” araması yaparak çok daha fazla örnek bulunabilir. Bilgisayarlar pikselleri ayrı ayrı kontrol edebilecek seviyeye geldiğinde, metin-bazlı koordinat sistemleri bitti. $x$ koordinatları Kartezyen koordinat sistemiyle aynı şekilde çalışırken $y$ koordinatları tersine çevrilmiştir. $y$ koordinatının sıfırı Kartezyen grafiklerde olduğu gibi ekranın altından başlayacağına, ekranın üst kısmına $y$ koordinatının sıfırı denilmiştir. $y$ değerleri büyüdükçe bilgisayar koordinat pozisyonu ekranda aşağı kayar. Tıpkı Kartezyen grafikler yerine metindeki satırlar gibi. Ayrıca, ekranın Kartezyen koordinat sisteminin daima sağ üst çeyreğe odaklandığı yerde sağ alt çeyreği kapladığına dikkat edin. Negatif koordinatlarla öğeleri çizmek mümkündür, fakat onlar ekran dışına çizilmiş olacaklardır. Şeklenin bir kısmı ekranda gösterilmeyecekse bu kullanışlı olabilir. Bilgisayar neyin ekran dışında olduğunu hesaplar ve programcı onun hakkında çok fazla endişelenmeye ihtiyaç duymaz. 5.2 Pygame Kütüphanesi Grafiklerin daha rahat çalışılır hale gelmesi için, Pygame'i kullanacağız. Pygame farklı kişiler tarafından yazılan bir kod kütüphanesidir ve şunları yapmayı kolaylaştırır: - Grafik şekilleri çizmek - Bitmap resimleri göstermek - Animasyon yapmak - Klavye, fare ve oyun kolu etkileşimi - Ses dosyası oynatmak - Nesnelerin çarpıştığını tespit etmek Pygame'i hala yüklemediyseniz, Pygame kurulum yönergeleri burada mevcuttur. Pygame bilgisayarınızda yüklü değilse, import pygame'i çalıştırmayı denerken bir hata ile karşılaşacaksınız. Örnek Pygame programımıza koyulacak ilk şey Pygame kütüphanesini yükleyecek ve başlatacak Python kodudur. Pygame kullanan her program şu satırlarla başlamalıdır: # 'pygame' adı verilen fonksiyon kütüphanesini import et import pygame # Oyun motorunu başlat pygame.init() Önemli: import pygame komutu pygame isimli bir kütüphane dosyasını arar. Programcı pygame.py adıyla bir program oluşturmuşsa, bilgisayar bu dosyayı Pygame yerine import edecektir! Bu işlem pygame.py dosyası silinene kadar bütün pygame programlarının çalışmasını engelleyecekir. 5.3 Renkler Alttaki Python kodu programa kullanılacak olan renkleri tanımlamak için ekleniyor. Renkler üç rengin listesi olarak tanımlanır: kırmızı, yeşil ve mavi. Sayıların aralığı 0 ile 255 arasındadır. Sıfır o renkten hiç olmadığını belirtirken 255 ekranın o renkten mümkün olduğunca çok göstermesi anlamına gelir. Renkler birleşir ve böylece eğer üç renk de belirtilmişse, ekranın rengi beyaz olarak gözükür. Python'da listeler köşeli parantezler arasında yer alır. Farklı sayılar virgüllerle ayrılır. Altta değişkenler üreten ve onlara üçer sayıdan oluşan listeler atayan bir örnek yer almaktadır. Bu listeler daha sonra renkleri belirtmede kullanılacaktır. # Define some colors black = ( 0, 0, 0) white = ( 255, 255, 255) green = ( 0, 255, 0) red = ( 255, 0, 0) IDLE'de yer alan etkileşimli kabuğu kullanarak bu değişkenleri tanımlamayı ve ekrana yazdırmayı deneyin. Eğer yukarıdaki beş renk beklediğiniz renkler değilse kendi renklerinizi tanımlayabilirsiniz. Bir renk seçmek için, bir online "renk seçici" bulun. Örneğin: http://www.colorpicker.com/ Ekstra: Bazı renk seçiciler renkleri hegzadesimal(onaltılık) olarak belirtiler. Eğer sayılarınız 0x ile başlıyorsa onaltılık sayıları girebilirsiniz. Mesela: white=[0xFF, 0xFF, 0xFF] Sonunda, program eğrileri çizerken $\pi$ değerini kullanmaya ihtiyaç yuarcaktır. Yani şu an, $\pi$ değerini içeren bir değişken tanımlamak için iyi bir zaman. 5.4 Pencere açmak Şimdiye kadar oluşturduğumuz programlar sadece yazılan metni ekrana yazdırıyordu. Bu programlar Windows veya Mac'lerde olan modern programlar gibi pencereler açmazlar. Bir pencere açmak için gerekli kod karışık değildir. Alttaki, 700 piksel genişliğinde ve 500 piksel yüksekliğinde bir pencere oluşturmak için gerekli kodtur. # Ekranın genişliğini ve yüksekliğini belirle size=[700,500] screen=pygame.display.set_mode(size) Neden set_mode? Neden open_window değil? Bunun sebebi bu komutun aslında bir pencere açmaktan çok daha fazlasını yapması. O ayrıca tam ekran modta çalışan oyunlar oluşturabilir. Başlat menüsünü, durum çubuklarını siler ve ekrandaki her şeyin kontrolünü oyuna verir. Bu mod kullanım için biraz daha karışık olduğu ve çoğu kişi yine de pencereli oyun yapmayı tercih ettiği için tam ekran oyunlar hakkında detaylı bir tartışmayı pas geçeceğiz. Fakat tam ekran oyunlar hakkında daha fazla bilgi edinmek istiyorsanız, pygame'in display komutu adresinden dökümantasyona göz atabilirsiniz.. Ayrıca, neden size=700,500 değil de size=[700,500]? Python normalde iki değişkeni (yükseklik ve genişlik) tek bir değişkenin içerisinde saklayamaz. Bunu yapmanın tek yolu numaraların bir listede saklanmasıdır. Listeler birden çok sayının köşeli parantezler içerisine yazılması sonucu oluşturulur. Bu sonraki bölümlerde detaylı olarak tartışılmıştır, fakat pencere boyutunu ayarlarken aklınızda tutun. Pencerenin başlık çubuğundaki başlığını ve küçültüldüğünde görünecek başlığını ayarlamak için alttaki kodu kullanın: pygame.display.set_caption("Professor Craven's Cool Game") 5.5 Kullanıcı ile etkileşim Şu ana kadar yazılan kodla program bir pencere oluşturup hemen ardından onu tutabilir. Kullanıcı pencereyle etkileşime geçemez, kapatamaz bile. Tüm bunların programlanması gereklidir. Kullanıcı "çıkış."a basana kada programın bekleyeceği bir bir döngünün koda eklenmesi gerekmektedir. Bu programın en karmaşık kısmıdır ve bunun tamamen anlaşılması şu an için gerekli değildir. Gerekli olan ise bunun ne olduğu hakkında bir fikir sahibi olmaktır. Sonuç olarak, bunu çalışırken ve sorular sorarken biraz zaman harcayın. # Kullanıcı kapatma butonuna basana kadar çalışacak döngü done=False # Ekranın ne hızla güncelleneceğini yönetmek için kullanılır clock=pygame.time.Clock() # -------- Ana Program Döngüsü ----------- while done==False: # TÜM EVENT PROCESSING (OLAY İŞLEME) BU İÇERİĞİN ALTINDA YER ALMALIDIR. for event in pygame.event.get(): # Kullanıcı bir şey yaptı if event.type == pygame.QUIT: # Kullanıcı kapata bastıysa done=True # Bittiğimizi ve döngüden çıkılması gerektiğini belirt. # TÜM EVENT PROCESSING (OLAY İŞLEME) BU İÇERİĞİN ÜSTÜNDE YER ALMALIDIR # TÜM OYUN MANTIĞI BU YORUMUN ALTINDA YER ALMALIDIR # TÜM OYUN MANTIĞI BU YORUMUN ALTINDA ÜSTÜNDE ALMALIDIR # ÇİZİLECEK TÜM KOD BU YORUMUN ALTINDA YER ALMALIDIR # ÇİZİLECEK TÜM KOD BU YORUMUN ÜSTÜNDE YER ALMALIDIR # Saniyede 20 yenileme sınırı clock.tick(20) Son olarak, klavye ve fare tıklamalarını işleyecek olan kodumuzu ekleyeceğiz. Bu kod event processing(olay işleme) ile ilgili yorumların arasında yer alacak. Kurşunlar atıldığında nesnelerin nasıl hareket edeceğini belirleyen kod oyun mantığı ile ilgili yorumların arasında yer alacak. Bunun hakkında sonraki bölümlerde konuşacağız. Çizim yapacak olan kod uygun çizim-kodu yorumlarının arasında yer alacak. Oyunun her bir frame'i (çerçevesi) için sıralama ve basit oyun mantığı: - Bitmediği sürece: - Pencere istekleri, kullanıcının bastığı tuşları ve fare tıklamaları gibi her event'i işleme koy. - Nesnelerin nereye hareket ettiği, çarpıştıklarında nelerin meydana geleceği vb. olayları belirleyen hesaplamalar çalışacak. - Ekranı temizle ve her şeyi çiz. Bu aşamalar birbirine karışmadıysa bunlar programın okunmasını ve anlaşılmasını daha kolay bir hale getirir. Birazcık hesaplama, biraz çizim, biraz daha hesaplama, biraz daha çizim yapmayın. Ayrıca, bunun ilk bölümde yaptığımız hesap makinesine nasıl benzediğine bir bakın. Kullanıcıdan giriş alınıyor, hesaplamalar yapılıyor ve çıktı cevap oluyor. Aynı kalıp buraya uygulandı. Resmi ekrana çizdiren kod while döngüsünün içerisinde yer alır. Saatin işareti 10 olarak ayarlandığında, penceredeki içerik saniyede 10 kez çizilecektir. Bu çok hızlı gerçekleşirse bilgisayar ağır işlemeye vaşlar çünkü zamanın tümü ekranın yenilenmesinde kullanılır. Eğer çizim döngünün dışında yapılırsa, pencere düzgün şekilde yeniden çizim yapamayacaktır. Eğer döngünün dışında yapılırsa, ekran başlangıçta grafikleri gösterebilir fakat ekran simge durumuna getirilirse veya önde başka bir pencere yer alırsa tekrardan gözükmeye başlamayacaktır. 5.6 Programı sonlandırmak Şu an, Pygame programında IDLE ortamında çalışırken "Kapat" butonuna tıklamak hala programın çökmesine sebep olacaktır. Kapat tuşuna basıldığında çöken bir programı kapatmak çok şey istediği için bu zor bir durumdur. Sorun, döngüden çıkılmış olsa bile, program bilgisayara pencereyi kapatmasını henüz söylememiştir. Alttaki komutu çalıştırarak programa açık tüm pencerelerini kapaması ve dilendiği şekilde çıkılması söylenmiş olur. pygame.quit () 5.7 Ekranı temizlemek Alttaki kod ekranda olabilecek her şeyi beyaz bir arkaplanla temizliyor. white değişkeninin daha önce 3 RGB değerinin listesi olarak tanımlandığını hatırlayın. # Ekranı temizle ve ekran arkaplanını ayarla screen.fill(white) Bu çizim komutu tartışılmadan önce yapılmalıdır. Ekranı program grafikleri çizdikten sonra temizlemek kullanıcının sadece boş bir pencere görmesiyle sonuçlanacaktır. Bir pencere ilk oluşturulduğunda siyah bir arkaplana sahiptir. Ekranı başlangıçta temizlemek yine de önemlidir çünkü ekranı temiz başlamaktan alıkoyacak şeyler meydana gelebilir. Bir program boş bir çerçeveyi çizime hazır tuttuğunu varsaymamalıdır. 5.8 Ekranı çevirmek Çok önemli! Ekranı çizimin ardından çevirmelisiniz. (Ç.N çevirmek = flip) Bilgisayar grafikleri çizdiğinizde ekranda titremeye yol açacağı için onları göstermeyecektir. Bu program çizimi bitirene kadar ekranda göstermeyi bekletir. Alttaki komut grafiği ekrana "çevirir". Bu komutun içeri aktarılmasındaki başarısızlık, programın sadece boş bir ekran göstermesi anlamına gelir. Bu flipten sonra gelen hiçbir çizim kodu gösterilmeyecektir. # Devam et ve ekranı çizdiğimiz şekilde güncelle. pygame.display.flip() 5.9 Boş bir ekran açmak Bu kod bir Pygame programı için temel şablon olarak kullanılabilir. Boş bir ekran açar ve kullanıcı kapat butonuna basana kadar bekler. """ Show how to use a sprite backed by a graphic. Sample Python/Pygame Programs Simpson College Computer Science http://programarcadegames.com/ http://simpson.edu/computer-science/ Explanation video: http://youtu.be/vRB_983kUMc """ import pygame # Define some colors BLACK = ( 0, 0, 0) WHITE = ( 255, 255, 255) GREEN = ( 0, 255, 0) RED = ( 255, 0, 0) pygame.init() # Set the width and height of the screen [width, height] size = (700, 500) screen = pygame.display.set_mode(size) pygame.display.set_caption("My Game") #Loop until the user clicks the close button. done = False # Used to manage how fast the screen updates clock = pygame.time.Clock() # -------- Main Program Loop ----------- while not done: # --- Main event loop for event in pygame.event.get(): # User did something if event.type == pygame.QUIT: # If user clicked close done = True # Flag that we are done so we exit this loop # --- Game logic should go here # --- Drawing code should go here # First, clear the screen to white. Don't put other drawing commands # above this, or they will be erased with this command. screen.fill(WHITE) # --- Go ahead and update the screen with what we've drawn. pygame.display.flip() # --- Limit to 60 frames per second clock.tick(60) # Close the window and quit. # If you forget this line, the program will 'hang' # on exit if running from IDLE. pygame.quit() 5.10 Çizgi çizdirmek http://www.pygame.org/docs/ref/draw.html Dikdördgenler, çokgenler, daireler, elipsler, kavisler ve doğrular. Ayrıca bitmap grafikleri ve yazıları da anlatacağız. Alttaki kod ekrana bir doğrunun nasıl çizdirildiğini gösteriyor. Ekrana (0,0)'dan (100,100)'e kadar 5 piksel genişliğinde yeşil bir çizgi çizdiriyor. green'in daha önce üç RGB değerinin listesi olarak tanımladığımız bir değişken olduğunu unutmayın. # (0,0)'dan (100,100)'e 5 piksel genişliğinde # yeşil bir doğru çiz. pygame.draw.line(screen,green,[0,0],[100,100],5) Önceki örnekte yer alan temel şablonu kullanın ve doğru çizdirecek kodlar ekleyin. Kodu tam olarak nereye koyacağınızı öğrenmek için yorumları okuyun. Farklı kalınlıklarda, renkerde ve yerlerde doğrular çizmeyi deneyin. Birkaç doğru çizin. 5.11 Döngüler ve ötelemelerle doğrular çizmek Programlar bir şeyleri tekrar tekrar yapabilir. Alttaki kod bir doğruyu döngü kullanarak tekrar ve tekrar çiziyor. Programlar bu tekniği çok sayıda doğru çizerken ve hatta bütün bir arabayı çizerken kullanabilir. Doğru çizme komutunu döngünün içine koymak birden çok doğrunun ekrana bastırılmasına sebep olacaktır. Fakat burada yakalanması gereken bir şey var. Eğer her doğru aynı başlangıç ve biriş koordinatlarına sahipse her doğru diğer doğrunun üzerine çizilecektir. Bu da sanki tek bir doğru çizilmiş gibi görünecektir. Bunu ayarlamak için, döngü her döndüğünde koordinatları uyarlamak gereklidir. Yani, döngünün ilk seferinde y_offset değişkeninin değeri sıfırdır. Kodun içerisinde alttaki kod (0,10)'dan (100,110)'e kadar çizilir. Sonraki seferde y_offset değeri 10 artırılmıştır. Bu bir sonraki doğrunun (0,20) ve (100,120) koordinatlarına sahip olmasını sağlar. Bu her seferinde doğruların 10'ar piksel kaymasını sağlayan döngüyle devam eder. # Ekrana (0,10)'dan (100,110)'a birkaç yeşil doğru çiz # Döngü kullan ve genişlik 5 piksel olsun for y_offset in range(0,100,10): pygame.draw.line(screen,red,[0,10+y_offset],[100,110+y_offset],5) Bu kodu farklı konum değişiklikleri ile çalıştırın ve deneyin. x_offset değişkeni tanımlayıp ona farklı değerler vererek deneyin. Onun tam olarak nasıl çalıştığını anlayana kadar farklı değerlerle deneyin. 5.12 Dikdördgen çizme When drawing a rectangle, the computer needs coordinates for the upper left rectangle corner (the origin), and a height and width. Bir dikdördgen çizerken, bilgisayar dikdördgenin üst kısmı için (merkez) koordinatlara, yükseklik ve genişliğe ihtiyaç duyar. Şekil 5.7 (20,20) merkezli 250 piksel genişlikte, 100 piksel yükseklikte bir dikdördgeni (ve bir elipsi, daha sonra açıklanacaktır) gösteriyor. Bilgisayar bir dikdördgeni belirtirken bu dört sayının listesine (x,y,genişlik,yükseklik) sırasıyla ihtiyaç duyar. Alttaki kod örneği bu dikdördgeni çizdiriyor. Listedeki ilk iki sayı sol üst köşeyi (20,20) olarak belirliyor. Sonraki iki sayıdan ilki genişliği 250 piksel yapıyor ve diğeri yüksekliği 100 piksel yapıyor. Sonda yer alan 2, çizgi genişliğini 2 piksel olarak belirliyor. Bu sayı ne kadar büyükse, dikdördgenin etrafındaki çizgi o kadar kalın olur. Bu sayı sıfırsa, dikdördgenin etrafında kenarlık olmaz. Onun yerine, dikdördgen belirtilen renkle boyanır. # Dikdördgen çizdir pygame.draw.rect(screen,black,[20,20,250,100],2) 5.13 Elips çizimi Elipsler tıpkı dikdördgenler gibi çizdirilir. Dikdördgenin kenarları belirtilir ve bilgisayar elipsi bu sınırların içerisine çizer. Elipslerle çalışırken yapılan en yaygın hata başlangıç merkezi olarak belirtilen noktanın elipsin merkezi olacağını sanmaktır. Gerçekte, başlangıç noktasına hiçbir şey çizilmez. Bu nokta, elipsi içine alan dikdördgenin sol üst noktasıdır. Şekil 5.7'e tekrar bakacak olursak, elipsin 250 piksel genişliğinde ve 100 piksel uzunluğunda bir elips görürüz. Elipsi içeren 250x100 dikdördgenin sol üst köşesi (20,20)'de yer alır. Aslında (20,20)'ye hiçbir şeyin çizilmediğine dikkat edin. Her ikisi de üstte çizili olduğu için bunları kullanarak elipsin nasıl belirtildiğini anlamak daha kolaydır. # Bir dikdördgeni dış sınırlar kabul ederek bir elips çiz pygame.draw.ellipse(screen,black,[20,20,250,100],2) 5.14 Yay çizmek Peki ya program elipsin sadece bir kısmını çizmeye ihtiyaç duyarsa? Bu arc komutuyla yapılabilir. Bu komut ellipse komutuna benzerdir fakat yayın başlangıç ve bitiş açılarını da içerir. Açılar radyan cinsindendir. Alttaki kod örneği bir çemberin dört farklı çeyreğini gösteren dört yay çiziyor. Her çeyrek yay bölümlerinin daha kolay anlaşıldığından emin olmak için farklı bir renkle çiziliyor. Kodun sonucu Şekil 5.8'de görülüyor. # Elipsin bir parçası olan yay çiz. Hangi açının çizileceğini # belirlemek için radyan cinsinden açılar kullan. pygame.draw.arc(screen,green,[100,100,250,200], pi/2, pi, 2) pygame.draw.arc(screen,black,[100,100,250,200], 0, pi/2, 2) pygame.draw.arc(screen,red, [100,100,250,200],3*pi/2, 2*pi, 2) pygame.draw.arc(screen,blue, [100,100,250,200], pi, 3*pi/2, 2) 5.15 Çokgen çizilmesi Kodun sonraki satırı bir çokgen çiziyor. Üçgen şekli (100,100) (0,200) ve (200,200)'de yer alan üç nokta ile tanımlanıyor. İstenildiği kadar çok noktanın listeye eklenmesi mümkündür. Noktaların nasıl listelendiğine dikkat edin. Her nokta iki sayıdan oluşan bir listedir ve noktalar kendileri de tüm noktaları tutan başka bir listenin içindedir. Kodun yaptığı çizim Şekil 5.9'de görülebilir. # Bu komut polygon komutunu kullanarak bir üçgen çizer pygame.draw.polygon(screen,black,[[100,100],[0,200],[200,200]],5) 5.16 Yazılar Yazılar birazcık daha karışıktır. Yapmanız gereken üç şey vardır. İlk olarak, program kullanılacak fontla ilgili yazı türü ve büyüklük gibi bilgileri tutan bir değişken oluşturur. İkinci olarak, program metnin resmini oluşturur. Bunu düşünmenin tek yolu programın gereken karakterlerle mürekkebe bandırılmış ve kağıda basmaya hazır bir "damga" oluşturmasıdır. İşimizin bitmesi için yapılacak üçüncü şey ise bu resmin nereye damgalanacağını (ya da "blit"leneceği) programa söyletmektir. İşte bir örnek: # Select the font to use. Default font, 25 pt size. # Kullanılacak yazı tipini seç. Varsayılan yazı tipi, 25 pt boyutunda. font = pygame.font.Font(None, 25) # Yazıyı resme çevir(Ç.N render işlemi). "True"nun anlamı yumuşatılmış yazıdır. # Black renktir. black değişkeni yukarıda # [0,0,0] listesi olarak tanımlanmıştı. # Not: Bu satır harflerin bir resmini oluşturuyor, # fakat onları henüz ekrana koymuyor. text = font.render("My text",True,black) # Yazının resmini ekrana 250x250 konumundan koy screen.blit(text, [250,250]) Skoru ekran mı koymak istiyorsunuz? Bu az daha karışıktır. Bu kod çalışmaz: text = font.render("Score: ",score,True,black) Fazladan ekrana yazılacak öğeler eklemek ve bunları virgülle ayırmak sadece print ifadesinde işe yarar. Skor "Score" stringine eklenmelidir. Fakat bu da çalışmaz: text = font.render("Score: "+score,True,black) Skor bir tamsayıysa(integer), bilgisayar bunu bir stringe nasıl ekleyeceğini bilmez. Siz, programcı, skoru bir stringe çevirmek zorundasınız. Ardından, stringleri birbirine ekleyebilirsiniz. Şunun gibi: text = font.render("Score: "+str(score),True,black) Şimdi skorun nasıl yazdırılacağını biliyorsunuz. Bir zamanlayıcıyı ekranda göstermek istiyorsanız, bu daha sonraki bir bölümde tartışılan print formatlamayı gerektirir. timer.py örneği için örnek kodu inceleyin. 5.17 Tamamını Listeleme Bu, bu bölümde tartışılan programın tamamının listelenmesidir. Bu program, diğer programlarla birlikte, http://cs.simpson.edu/cmsc150/index.php?chapter=example_code adresinden indirilebilir. """ Simple graphics demo Sample Python/Pygame Programs Simpson College Computer Science http://programarcadegames.com/ http://simpson.edu/computer-science/ """ # Import a library of functions called 'pygame' import pygame # Initialize the game engine pygame.init() # Define some colors BLACK = ( 0, 0, 0) WHITE = ( 255, 255, 255) BLUE = ( 0, 0, 255) GREEN = ( 0, 255, 0) RED = ( 255, 0, 0) PI = 3.141592653 # Set the height and width of the screen size = (400, 500) screen = pygame.display.set_mode(size) pygame.display.set_caption("Professor Craven's Cool Game") #Loop until the user clicks the close button. done = False clock = pygame.time.Clock() # Loop as long as done == False while not done: for event in pygame.event.get(): # User did something if event.type == pygame.QUIT: # If user clicked close done = True # Flag that we are done so we exit this loop # All drawing code happens after the for loop and but # inside the main while not done loop. # Clear the screen and set the screen background screen.fill(WHITE) # Draw on the screen a line from (0,0) to (100,100) # 5 pixels wide. pygame.draw.line(screen, GREEN, [0, 0], [100, 100], 5) # Draw on the screen several lines from (0,10) to (100,110) # 5 pixels wide using a loop for y_offset in range(0, 100, 10): pygame.draw.line(screen, RED, [0, 10 + y_offset], [100, 110 + y_offset], 5) # Draw a rectangle pygame.draw.rect(screen, BLACK, [20, 20, 250, 100], 2) # Draw an ellipse, using a rectangle as the outside boundaries pygame.draw.ellipse(screen, BLACK, [20, 20, 250, 100], 2) # Draw an arc as part of an ellipse. # Use radians to determine what angle to draw. pygame.draw.arc(screen, BLACK, [20, 220, 250, 200], 0, PI / 2, 2) pygame.draw.arc(screen, GREEN, [20, 220, 250, 200], PI / 2, PI, 2) pygame.draw.arc(screen, BLUE, [20, 220, 250, 200], PI, 3 * PI / 2, 2) pygame.draw.arc(screen, RED, [20, 220, 250, 200], 3 * PI / 2, 2 * PI, 2) # This draws a triangle using the polygon command pygame.draw.polygon(screen, BLACK, [[100, 100], [0, 200], [200, 200]], 5) # Select the font to use. Default font, 25 pt size. font = pygame.font.Font(None, 25) # Render the text. "True" means anti-aliased text. # Black is the color. This creates an image of the # letters, but does not put it on the screen text = font.render("My text", True, BLACK) # Put the image of the text on the screen at 250x250 screen.blit(text, [250, 250]) # Go ahead and update the screen with what we've drawn. # This MUST happen after all the other drawing commands. pygame.display.flip() # This limits the while loop to a max of 60 times per second. # Leave this out and we will use all CPU we can. clock.tick(60) # Be IDLE friendly pygame.quit() 5.18 Tekrar Soruları Çoktan seçmeli bir quiz için buraya tıklayın. Alttaki sorulara cevap verdikten sonra, sizin kendi tasarımınızın resmini oluşturan bir program yazın. Detaylar için Bir-Resim-Oluştur labına bakın. - Bilgisayar pygame.display.set_mode() gibi bütün fonksiyonları kullanmadan önce yapılması gereken iki şey nedir? - pygame.display.set_mode() fonksiyonu ne yapar? - pygame.time.Clock ne için kullanılır? - for event in pygame.event.get() döngünü ne yapmak içindir? - Kodun bu satırı için: pygame.draw.line(screen,green,[0,0],[100,100],5) - screen ne yapar? - [0,0] ne yapar? [100,100] ne işe yarar? - 5 ne için kullanılmıştır? - Bilgisayar koordinat sisteminin Kartezyen koordinat sisteminden olan farklarını açıklayın. - white = ( 255, 255, 255)'ın nasıl bir renk belirttiğini açıklayın. - Bir dikdördgen çizerken, doğru kalınlığı sıfır olarak belirtilmişse ne olur? - Alttaki kodta çizilen elipsi çizin, daha sonra orijin koordinatını, uzunluk ve genişliğini etiketlendirin: pygame.draw.ellipse(screen,black,[20,20,250,100],2) - Genel olarak, grafikleri kullanarak yazıları ekrana bastırmak için kullanılan üç aşamanın neler olduğunu tanımlayın. - Alttaki kodun çizdiği çokgenin koordinatları nelerdir? - pygame.display.flip() ne yapar? - pygame.quit() ne işe yarar? You are not logged in. Log in here and track your progress. English version by Paul Vincent Craven Russian version by Vladimir Slav Turkish version by Güray Yildirim Dutch version by Frank Waegeman Portuguese version by Tati Carvalho