📜 ⬆️ ⬇️

A personal zoo or a little about Pygame - Part 1

image
For those who do not know: Pygame is a very, very good framework for developing games in the Python language. And not only work with 2D and 3D is supported, but if you wish, you can install binders to many popular graphics and physics engines. By the way, Pygame does not have to be used specifically for games, you can also create programs with an unusual interface, for example, some kind of three-dimensional database frontend.
So I, in fact, wanted to talk about the basic principles of working with this framework, you never know, maybe it will be useful to someone :)

Let's go!


In order to gain access to Pygame classes and methods, it must be initialized. By the way, the global game timer starts exactly when the module is initialized, and the programmer, in turn, can receive time in seconds from the beginning of the initialization at any time. Create a simple window:
Copy Source | Copy HTML import pygame from pygame.locals import * def init_window (): pygame.init() window = pygame.display.set_mode(( 550 , 480 )) pygame.display.set_caption( 'My own little world' ) def main (): init_window () if __name__ == '__main__' : main ()
  1. Copy Source | Copy HTML import pygame from pygame.locals import * def init_window (): pygame.init() window = pygame.display.set_mode(( 550 , 480 )) pygame.display.set_caption( 'My own little world' ) def main (): init_window () if __name__ == '__main__' : main ()
  2. Copy Source | Copy HTML import pygame from pygame.locals import * def init_window (): pygame.init() window = pygame.display.set_mode(( 550 , 480 )) pygame.display.set_caption( 'My own little world' ) def main (): init_window () if __name__ == '__main__' : main ()
  3. Copy Source | Copy HTML import pygame from pygame.locals import * def init_window (): pygame.init() window = pygame.display.set_mode(( 550 , 480 )) pygame.display.set_caption( 'My own little world' ) def main (): init_window () if __name__ == '__main__' : main ()
  4. Copy Source | Copy HTML import pygame from pygame.locals import * def init_window (): pygame.init() window = pygame.display.set_mode(( 550 , 480 )) pygame.display.set_caption( 'My own little world' ) def main (): init_window () if __name__ == '__main__' : main ()
  5. Copy Source | Copy HTML import pygame from pygame.locals import * def init_window (): pygame.init() window = pygame.display.set_mode(( 550 , 480 )) pygame.display.set_caption( 'My own little world' ) def main (): init_window () if __name__ == '__main__' : main ()
  6. Copy Source | Copy HTML import pygame from pygame.locals import * def init_window (): pygame.init() window = pygame.display.set_mode(( 550 , 480 )) pygame.display.set_caption( 'My own little world' ) def main (): init_window () if __name__ == '__main__' : main ()
  7. Copy Source | Copy HTML import pygame from pygame.locals import * def init_window (): pygame.init() window = pygame.display.set_mode(( 550 , 480 )) pygame.display.set_caption( 'My own little world' ) def main (): init_window () if __name__ == '__main__' : main ()
  8. Copy Source | Copy HTML import pygame from pygame.locals import * def init_window (): pygame.init() window = pygame.display.set_mode(( 550 , 480 )) pygame.display.set_caption( 'My own little world' ) def main (): init_window () if __name__ == '__main__' : main ()
  9. Copy Source | Copy HTML import pygame from pygame.locals import * def init_window (): pygame.init() window = pygame.display.set_mode(( 550 , 480 )) pygame.display.set_caption( 'My own little world' ) def main (): init_window () if __name__ == '__main__' : main ()

I designed the code in a C-like manner, so it’s easier to read. Actually, there’s really nothing to perceive yet :) First we import the necessary modules (for sshnikov - we describe the namespace), then we initialize the framework, create a window with dimensions of 550 by 480 and give it the title “My own little world”.
I think those who tried to run this code, noticed that the window immediately after the appearance disappears. This happens because we have not yet described the global infinite loop of receiving messages, so the window simply has nothing to do. Fix this mistake:
Copy Source | Copy HTML
  1. import sys
  2. import pygame
  3. from pygame.locals import *
  4. def init_window ():
  5. pygame.init ()
  6. window = pygame.display.set_mode (( 550 , 480 ))
  7. pygame.display.set_caption ( 'My own little world' )
  8. def input (events):
  9. for event in events:
  10. if (event.type == QUIT) or (event.type == KEYDOWN and event.key == K_ESCAPE):
  11. sys .exit ( 0 )
  12. else :
  13. pass
  14. def action ():
  15. while 1 :
  16. input (pygame.event.get ())
  17. def main ():
  18. init_window ()
  19. action ()
  20. if __name__ == '__main__' : main ()

As we can see, an endless message receiving loop starts. If a QUIT message is sent (by clicking on the cross of the window) or the ESCAPE button is pressed, the application ends its work.
But the window is empty, black, uninteresting. What would we do to draw something on it? To begin with we will set it background . You can fill it with solid color or, oddly enough, just upload a picture of a suitable size and display it along the coordinates (0,0):
Copy Source | Copy HTML
  1. import os
  2. def load_image (name):
  3. fullname = os .path.join ( 'data' , name) I have pictures in the 'data' folder
  4. try :
  5. image = pygame.image.load (fullname)
  6. except pygame.error, message: # It's not enough :)
  7. print "Cannot load image:" , name
  8. raise SystemExit, message
  9. image = image.convert () # Adapt the image to display in the game. If it has an alpha channel - then convert_alpha ()
  10. return image, image.get_rect ()
  11. def draw_background ():
  12. screen = pygame.display.get_surface () # We get the surface on which we will draw
  13. background = pygame.Surface (screen.get_size ()) # and its size
  14. background = background.convert ()
  15. background.fill ((0, 0, 0)) # fill with color
  16. screen.blit (background, (0, 0)) # draw a background filled with one color
  17. back, back_rect = load_image ( "grass.jpg" ) # or load a picture with grass
  18. screen.blit (back, (0, 0)) # and draw it
  19. pygame.display.flip () # switch screen buffer
  20. return back
  21. def main ():
  22. init_window ()
  23. bk = draw_background ()
  24. action ()

The most important lines here are screen = pygame.display.get_surface () , screen.blit (back, (0, 0)) and pygame.display.flip () . When working with Pygame it is important to remember that every time drawing goes on some kind of surface . At the same time, there is such a thing as a backbuffer , that is, the drawing goes in the screen buffer, and the flip () method, so to speak, “inverts” the screen, displaying the changes that occurred in the buffer, on the screen.

Well, now add to our little world a bit of living creatures. To do this, create an animal, say, an elephant :) Just to get started, let's rewrite our image loading function a little. Now I will explain why.
Copy Source | Copy HTML
  1. def load_image (name, colorkey = None):
  2. fullname = os .path.join ( 'data' , name)
  3. try :
  4. image = pygame.image.load (fullname)
  5. except pygame.error, message:
  6. print "Cannot load image:" , name
  7. raise SystemExit, message
  8. image = image.convert ()
  9. if colorkey is not None:
  10. if colorkey is - 1 :
  11. colorkey = image.get_at ((0,0))
  12. image.set_colorkey (colorkey, RLEACCEL)
  13. return image, image.get_rect ()
  14. class Animal (pygame.sprite.Sprite):
  15. def __init__ (self, img, cX, cY):
  16. pygame.sprite.Sprite. __init__ (self)
  17. self .image, self .rect = load_image (img, - 1 )
  18. screen = pygame.display.get_surface ()
  19. self .area = screen.get_rect ()
  20. self .cX = cX
  21. self .cY = cY
  22. self .coord = (cX, cY)
  23. print "Animal spawned at" , self .coord
  24. class Elephant ( Animal ):
  25. def __init__ (self, cX, cY):
  26. Animal . __init__ (self, "Elephant.bmp" , cX, cY)

I foresee outraged cries of "why bmp ??". I will answer - for the experience :) Because now we have acquired one more skill - taking the color from the picture by coordinates ( colorkey = image.get_at ((0,0)) ), we can make this color on the whole picture completely transparent ( image.set_colorkey (colorkey, RLEACCEL) )! It is useful if you suddenly need to upload a picture without an alpha channel.
')
pygame.sprite.Sprite is the standard pygame sprite class. For those who do not know: a sprite is a flat image with a number of properties necessary for a game object. In particular, it can be made to move, teach any interactions, etc.

And now all we need is to run an elephant into our jungle!
Copy Source | Copy HTML
  1. def action (bk):
  2. creatures_list = [] # List with all animals. It will be useful if we add new ones.
  3. screen = pygame.display.get_surface ()
  4. elephant = Elephant ( 10 , 10 ) # Put an elephant in the coordinates x = 10, y = 10
  5. creatures_list.append (elephant)
  6. animals = pygame.sprite.RenderPlain (creatures_list) # Throwing all our animals into the RenderPlain class to display sprites on the screen
  7. while 1 :
  8. input (pygame.event.get ())
  9. screen.blit (bk, (0, 0))
  10. animals.update () # Standard verification method, suddenly something has changed. Useful for describing the movement
  11. animals.draw (screen)
  12. pygame.display.flip ()
  13. def main ():
  14. init_window ()
  15. bk = draw_background ()
  16. action (bk)

I agree that the above code needs to be optimized, in particular, do not kick the curve for drawing the background, but in general, everything should be clear.

And finally, a working screenshot of my little development, just getting acquainted with Pygame. The green contours around the images are the flaws of bmp processing, now I redraw everything myself under png. The grid is the simplest example of drawing with Pygame, I'll tell you about it next time.



Ready to answer any questions and listen to criticism.

Source: https://habr.com/ru/post/59748/


All Articles