Apple said it will pay an estimated $38 billion in tax to bring back to the US some of the $252 billion it has stashed overseas, following passage of the new tax law.
YouTube has taken new steps to limit who can profit from views—which may leave the next generation of creators in the lurch.
Labo is a set of cardboard, build-it-yourself accessories for Nintendo's super-popular Switch gaming console.
Entrepreneurs are selling VCs a vision of cheap, surgery-free cancer screening based on blood tests, even before symptoms appear.
When researchers put a popular criminal justice algorithm up against a bunch of Mechanical Turks, they came out about even.
Researchers claim they’ve reduced the uncertainty in a key metric of climate change by 60 percent. That could have implications for how humanity arrives at climate goals like it did in Paris.
A discussion about diversity in product design with Google's Lilian Rincon. Recorded live at CES 2018.
This is part three of a five-part series of tutorials about making games with Python 3 and Pygame. In part two, we covered the TextObject class used to render text on the screen, created the main window, and learned how to draw objects like bricks, the ball, and the paddle.
In this part, we will dive into the heart of Breakout and learn how to handle events, meet the main Breakout class, and see how to move the different game objects.Handling Events
In Breakout, there are three types of events: key press events, mouse events, and timer events. The main loop in the Game class takes care of the key press and mouse events and delivers them to subscribers (by calling a handler function).
While the Game class is very generic and has no Breakout specific knowledge, the subscription itself and how to handle each event are very specific.The Breakout Class
The Breakout class is where most of the domain knowledge about the Breakout game is managed. We will meet the Breakout class several times during this series. Here are the lines that register the various event handlers.
Note that all key events for both the left and right arrow keys will go to the same handler method of the paddle.# Register the handle_mouse_event() method of a button object self.mouse_handlers.append(b.handle_mouse_event) # Register the handle() method of the paddle to handle key events self.keydown_handlers[pygame.K_LEFT].append(paddle.handle) self.keydown_handlers[pygame.K_RIGHT].append(paddle.handle) self.keyup_handlers[pygame.K_LEFT].append(paddle.handle) self.keyup_handlers[pygame.K_RIGHT].append(paddle.handle)Handling Key Presses
The Game class will call the registered handlers for each key event and pass the key. Note that it doesn't the Paddle class. In Breakout, the only object that is interested in these events is the paddle. When a key is pressed or released, its handle() method is called.
The Paddle doesn't need to know if it was a key down or key up event because it manages the current state through a pair of boolean variables: moving_left and moving_right. If moving_left is True then it means the left arrow key is pressed and the next event will be key up, which will release it. The same goes for the right arrow key. The logic is as simple as toggling these variables in response to any event.def handle(self, key): if key == pygame.K_LEFT: self.moving_left = not self.moving_left else: self.moving_right = not self.moving_rightHandling Mouse Events
Breakout has a game menu you'll meet soon. The button on the menu handles various mouse events such as movement and clicks (mouse down and mouse up events). In response to these events, the button updates an internal state variable. Here is the mouse handling code:def handle_mouse_event(self, type, pos): if type == pygame.MOUSEMOTION: self.handle_mouse_move(pos) elif type == pygame.MOUSEBUTTONDOWN: self.handle_mouse_down(pos) elif type == pygame.MOUSEBUTTONUP: self.handle_mouse_up(pos) def handle_mouse_move(self, pos): if self.bounds.collidepoint(pos): if self.state != 'pressed': self.state = 'hover' else: self.state = 'normal' def handle_mouse_down(self, pos): if self.bounds.collidepoint(pos): self.state = 'pressed' def handle_mouse_up(self, pos): if self.state == 'pressed': self.on_click(self) self.state = 'hover'
Note that the handle_mouse_event() method that is registered to receive mouse events checks the type of the event and forwards it to the specific method that handles that event type.Handling Timer Events
Timer events are not processed through the main loop. However, since the main loop is called every frame, it's easy to check if a certain timed event is due. You will see an example of this later when discussing timed special effects.
Another situation is when we want to freeze the game—for example, when displaying a message that the player should be able to read without distraction. The show_message() method of the Breakout class uses this approach and calls time.sleep(). Here is the relevant code:import config as c class Breakout(Game): def show_message(self, text, color=colors.WHITE, font_name='Arial', font_size=20, centralized=False): message = TextObject(c.screen_width // 2, c.screen_height // 2, lambda: text, color, font_name, font_size) self.draw() message.draw(self.surface, centralized) pygame.display.update() time.sleep(c.message_duration)Gameplay
The gameplay part is where the rules of Breakout come to play (see what I did there?). Gameplay is about moving the different objects in response to the events and changing the game state based on their interactions.Moving the Paddle
You saw earlier that the Paddle class responds to arrow keys by updating its moving_left and moving_right fields. The actual movement happens in the update() method. There is some computation going on here if the paddle is close to the left or right edge of the screen. We don't want the paddle to move beyond the edges of the screen (including a predefined offset).
So if the movement would have taken it beyond the edge, the code adjusts the movement to stop exactly at the edge. Since the paddle is only moving horizontally, the vertical component of the movement is always zero.import pygame import config as c from game_object import GameObject class Paddle(GameObject): def __init__(self, x, y, w, h, color, offset): GameObject.__init__(self, x, y, w, h) self.color = color self.offset = offset self.moving_left = False self.moving_right = False ... def update(self): if self.moving_left: dx = -(min(self.offset, self.left)) elif self.moving_right: dx = min(self.offset, c.screen_width - self.right) else: return self.move(dx, 0)Moving the Ball
The ball just uses the functionality of the GameObject base class, which moves game objects based on their speed (with horizontal and vertical components). The speed of the ball is determined by many factors in the Breakout class that you'll see soon. Since moving is just adding the speed to the current position, the direction the ball is moving is fully determined by its speed along the horizontal and vertical axes.Setting the Initial Ball Speed
The ball in Breakout appears out of nowhere at the beginning of the game every time the player loses a life. It just materializes out of the ether and starts dropping either straight down or at a slight angle. When the ball is created in the create_ball() method, it receives a speed with a random horizontal component between -2 and 2 and a vertical component, which is determined in the config.py module (currently set to 3).def create_ball(self): speed = (random.randint(-2, 2), c.ball_speed) self.ball = Ball(c.screen_width // 2, c.screen_height // 2, c.ball_radius, c.ball_color, speed) self.objects.append(self.ball)Conclusion
In this part, we covered event handling such as key presses, mouse movement, and mouse clicks. We also dove into some of the gameplay elements of Breakout such moving the paddle, moving the ball, and controlling the ball's speed.
Remember also to see what we have available for sale and for study in the Envato Market if you're looking to study more Python-related material.
In part four, we will deal with the important topic of collision detection and see what happens when the ball hits various game objects like the paddle, bricks, and even the walls, ceiling, and the floor.
Then we'll turn our attention to the game menu. We'll create custom buttons that we'll use as a menu we can show and hide as necessary.
Just put on this goofy helmet, and the car could know what you'll do before you do it.
Set up an intersection the wrong way, and an oncoming car can be completely blind to an approaching biker—with fatal consequences.