If you want to start making games with pygame, you need to learn as first thing how to move an object on the screen. I tried to make as less lines of code for this so that you do not take too much time to get how it works. Here is a screen that shows you the result:
And here is the code, I think it is very clear what it does.
import pygame import sys # Initialize Pygame pygame.init() # Create a window with a clock for frame rate speed screen = pygame.display.set_mode((600, 400)) clock = pygame.time.Clock() # coordinates of the rectangle and surface of it rectx, recty = 100, 100 rectangle = pygame.Surface((10,10)) rectangle.fill((255,0,0)) # color red for it # direction controller go = 0 while True: # use the event.key id to move if go == 1073741903: rectx += 1 if go == 1073741904: rectx -= 1 # left if go == 1073741905: recty += 1 if go == 1073741906: recty -= 1 # top for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # If the user presses the left arrow key, move the rectangle to the left if event.type == pygame.KEYDOWN: go = event.key screen.blit(rectangle, (rectx, recty)) pygame.display.flip() clock.tick(60)
The event.key returns a number for each key pressed, so I used this number to change directions. These are the numbers for the arrow keys. The rectangle is made using a Surface, that is a part of the memory that contains images in a rectangular size. I could create a rectangle instead, you can do it, but I found that this way was simpler and also more usable, in case you want to make changes to the Surface. So, in just 23 lines of code we made something happen. In another post we will see how to make an actual game going further with our code.
import pygame import sys # Initialize Pygame pygame.init() # Create a window with a clock for frame rate speed screen = pygame.display.set_mode((600, 400)) clock = pygame.time.Clock() # coordinates of the rectangle and surface of it rectx, recty = 100, 100 rectangle = pygame.Surface((10,10)) rectangle.fill((255,0,0)) # color red for it # direction controller go = 0 while True: # use the event.key id to move match go: case 3: rectx += 1 case 4: rectx -= 1 case 5: recty += 1 case 6: recty -= 1 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # If the user presses the left arrow key, move the rectangle to the left if event.type == pygame.KEYDOWN: go = event.key % 10 screen.blit(rectangle, (rectx, recty)) pygame.display.flip() clock.tick(60)
We could also use match case instead of if, taking only the last digit of the event.key (but we could have other keys that return that last digit, I dunno if it’s a good idea, maybe it’s better to use the whole number).
If you don’t want to make a trace of the square, you just fill the screen every frame with the color of the background.
import pygame import sys # Initialize Pygame pygame.init() # Create a window with a clock for frame rate speed screen = pygame.display.set_mode((600, 400)) clock = pygame.time.Clock() # coordinates of the rectangle and surface of it rectx, recty = 100, 100 rectangle = pygame.Surface((10,10)) rectangle.fill((255,0,0)) # color red for it # direction controller go = 0 while True: screen.fill((0,0,0)) # use the event.key id to move match go: case 1073741903: rectx += 1 case 1073741904: rectx -= 1 case 1073741905: recty += 1 case 1073741906: recty -= 1 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # If the user presses the left arrow key, move the rectangle to the left if event.type == pygame.KEYDOWN: go = event.key screen.blit(rectangle, (rectx, recty)) pygame.display.flip() clock.tick(60)
If you want you could also use a class to make the rectangle.
import pygame import sys # Initialize Pygame pygame.init() # Create a window with a clock for frame rate speed screen = pygame.display.set_mode((600, 400)) clock = pygame.time.Clock() # coordinates of the rectangle and surface of it class Shape: def __init__(self, x, y): self.rectx, self.recty = x, y self.surface = pygame.Surface((10,10)) self.surface.fill((255,0,0)) # color red for it # direction controller rectangle = Shape(100,100) go = 0 while True: screen.fill((0,0,0)) # use the event.key id to move match go: case 1073741903: rectangle.rectx += 1 case 1073741904: rectangle.rectx -= 1 case 1073741905: rectangle.recty += 1 case 1073741906: rectangle.recty -= 1 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # If the user presses the left arrow key, move the rectangle to the left if event.type == pygame.KEYDOWN: go = event.key screen.blit(rectangle.surface, (rectangle.rectx, rectangle.recty)) pygame.display.flip() clock.tick(60)
You could ask, what is it for?
In case you wanted to create a more complex figure with 5 rectangles (that are sqares, indeed). You could do so:
import pygame import sys # Initialize Pygame pygame.init() # Create a window with a clock for frame rate speed screen = pygame.display.set_mode((600, 400)) clock = pygame.time.Clock() # coordinates of the rectangle and surface of it class Shape(pygame.sprite.Sprite): def __init__(self, x, y, color): super().__init__() self.rectx, self.recty = x, y self.surface = pygame.Surface((10,10)) self.surface.fill(color) # color red for it self.speed = 4 group.add(self) def update(self, go): match go: case 1073741903: self.rectx += self.speed case 1073741904: self.rectx -= self.speed case 1073741905: self.recty += self.speed case 1073741906: self.recty -= self.speed screen.blit(self.surface, (self.rectx, self.recty)) # direction controller group = pygame.sprite.Group() rec1 = Shape(100,100,(255,0,0)) rec2 = Shape(100,90,(255,255,0)) rec3 = Shape(90,100,(255,255,255)) rec4 = Shape(110,100,(0,255,0)) rec5 = Shape(100,110,(0,255,255)) go = 0 def check_keys(): global go for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # If the user presses the left arrow key, move the rectangle to the left if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: pygame.quit() sys.exit() go = event.key else: go = 0 return go while True: screen.fill((0,0,0)) # use the event.key id to move group.update(go) go = check_keys() pygame.display.flip() clock.tick(60)
Why I should do this and not just load an image like that instead? We will discover it in the next post, maybe. As you can see I user the super class Sprite of pygame.pygame. So I can use some methods in that class. I used the pygame.sprite.Group object called group (?) to update all the object just updating the object group. Otherwise I should have used 5 lines of code, and we do not want that, right?
I also added the attribute speed to the class Shape, so that it is easier to change speed of the square in case I want. In fact I changed it to 4, but I can imagine that the speed could change in the game for various reasons, so… it’s better to have it stored in a variable instead of having an absolute number.
But, why wait the next post when we can do something new now? Ok, we will use these 5 objects to do something like this:
So, that was an example of why we should use classes to make funcy stuffs. Here is the code modified to do what you saw in the video, with some math… if I knew that math could be used to make funny games I should have appreciate it more at school.
import pygame import sys import math # Initialize Pygame pygame.init() # Create a window with a clock for frame rate speed screen = pygame.display.set_mode((600, 400)) clock = pygame.time.Clock() # coordinates of the rectangle and surface of it class Shape(pygame.sprite.Sprite): def __init__(self, x, y, color, pos=""): super().__init__() self.rectx, self.recty = x, y self.surface = pygame.Surface((10,10)) self.surface.fill(color) # color red for it self.speed = 4 self.pos = pos group.add(self) def update(self, go): match go: case 1073741903: self.rectx += self.speed case 1073741904: self.rectx -= self.speed case 1073741905: self.recty += self.speed case 1073741906: self.recty -= self.speed self.pulsar() def pulsar(self): if self.pos == "right": self.rectx += math.cos(timer / 4) if self.pos == "left": self.rectx -= math.cos(timer / 4) if self.pos == "top": self.recty -= math.cos(timer / 4) if self.pos == "bottom": self.recty += math.cos(timer / 4) screen.blit(self.surface, (self.rectx, self.recty)) # direction controller group = pygame.sprite.Group() rec1 = Shape(100,100,(255,0,0), "center") rec2 = Shape(100,86,(255,255,0), "top") rec3 = Shape(86,100,(255,255,255), "left") rec4 = Shape(114,100,(0,255,0), "right") rec5 = Shape(100,114,(0,255,255), "bottom") go = 0 def check_keys(): global go for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # If the user presses the left arrow key, move the rectangle to the left if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: pygame.quit() sys.exit() go = event.key else: go = 0 return go timer = 0 while True: screen.fill((0,0,0)) # use the event.key id to move group.update(go) go = check_keys() pygame.display.flip() timer +=1 clock.tick(60)
I have used a timer that goes up for every frame, so 60 times for second. maybe it’s too much? We will see it in the next post. This time it’s true, we continue in another post. Bye.
A preview of the next post
As the code is becoming complex, I will put it into github at this address:
https://github.com/formazione/pygamezero
Subscribe to the newsletter for updates
Tkinter templates
My youtube channel
Twitter: @pythonprogrammi - python_pygame