Write a WeChat airplane hitting game in Python (9)

Source: Internet
Author: User

Compile a plane hitting game in Python (9)

In our previous blog posts, we added an increasing difficulty Mechanism for the game, which brought about a problem: when the difficulty level was reached, the enemy planes came overwhelming, our small planes cannot cope with this, so in this blog, we give our planes a mandatory killer-random supply of full-screen bombs and super bullets.

First, let's briefly describe these two technologies. A full-screen bomb is a full-screen bomb (if any) triggered when a user presses the Space key during the game ), all the enemies on the screen are destroyed immediately. A super bullet means that after a player receives a designated supply package, our plane can launch two bullets at a time, doubling the attack power. OK.

1. Define the supply Module

Define a module named supply. py to save the properties of the super weapon, including full-screen bomb replenishment class and super bullet replenishment class. For the full-screen bomb replenishment class, the complete code is provided here:

#=====================================Define a Super bomb supply package ====== class BombSupply (pygame. sprite. sprite): def _ init _ (self, bg_size): pygame. sprite. sprite. _ init _ (self) self. image = pygame. image. load (image/ufo2.png) self. rect = self. image. get_rect () self. width, self. height = bg_size [0], bg_size [1] self. rect. left, self. rect. bottom = randint (0, self. width-self. rect. width),-100 self. speed = 5 self. active = False self. mask = pygame. mask. from_surface (self. image) def move (self): if self. rect. top <self. height: self. rect. top + = self. speed else: self. active = False def reset (self): self. active = True self. rect. left, self. rect. bottom = randint (0, self. width-self. rect. width),-100

It can be seen that the BombSupply class structure is very similar to the class structure of the previous enemy aircraft. In fact, the supply package itself has the same property as the enemy plane: random location initialization, moving down at a certain speed, we need to perform mask collision detection (except that the collision will not cause damage to our enemies) and so on. Similarly, the Code for the super bullet Supply Class is as follows. The two are identical in structure and will not be repeated.

#=====================================Define a super bullet supply package ===== class BulletSupply (pygame. sprite. sprite): def _ init _ (self, bg_size): pygame. sprite. sprite. _ init _ (self) self. image = pygame. image. load (image/ufo1.png) self. rect = self. image. get_rect () self. width, self. height = bg_size [0], bg_size [1] self. rect. left, self. rect. bottom = randint (0, self. width-self. rect. width),-100 self. speed = 5 self. active = False self. mask = pygame. mask. from_surface (self. image) def move (self): if self. rect. top <self. height: self. rect. top + = self. speed else: self. active = False def reset (self): self. active = True self. rect. left, self. rect. bottom = randint (0, self. width-self. rect. width),-100

2. instantiate a Super bomb

It is worth noting that the game initially comes with three full-screen bombs. Therefore, we will not start the replenishment and distribution mechanism, so we should first make good use of these three Super bombs.

First, you need to display the full-screen bomb icon and remaining quantity in the lower left corner of the screen when the game is running. because the number of bombs is variable (our plane may eat a supply package ), therefore, initialize a global variable in the main function to save the current number of full screen bombs:

Bomb_num = 3 # Three bombs initially

Then load the small icon of the full screen bomb and obtain its location attribute. Note that the image added in the supply. py module is the replenishment package icon (with a small parachute), not the full screen bomb icon:

Bomb_image = pygame. image. load (image/bomb.png) # load the full screen bomb icon bomb_rect = bomb_image.get_rect () bomb_front = score_font

Note that since the characters (number of full screen bombs) need to be displayed next, we can directly apply the font object created previously to print scores (see the previous blog ). In the while loop of the main () function, we will plot images and the number of bombs to the screen in Real Time:

#===================================================== ========== Bomb_text = bomb_front.render (× % d % bomb_num, true, color_black) bomb_text_rect = bomb_text.get_rect () screen. bheight (bomb_image, (10, height-10-bomb_rect.height) screen. blit (bomb_text, (20 + bomb_rect.width, height-10-bomb_text_rect.height ))

Note that because the number of bomb icons and the number of bombs must be displayed side by side, you need to obtain the image and font size. As for how to place the number, I believe you can understand it with a slight scrutiny. Run the program, and the icon is displayed in the lower left corner of the screen.

3. trigger a full screen bomb

Since the full screen bomb has been displayed, it is not enough to put it in that shock. Every time a user presses the Space key, a full screen bomb is triggered, and all the enemies on the screen are immediately damaged. Of course, we first need to know when the user presses the Space key:

#================================================== ========= For event in pygame. event. get (): # respond to the user's accidental operation if event. type = QUIT: # If you press the close button on the screen to trigger the QUIT event, the program exits the elif event. type = KEYDOWN: if event. key = K_SPACE: # if the user is detected to press the Space key if bomb_num: # if the number of bombs is greater than zero, a Super bomb bomb_num-= 1 bomb_sound.play () for each in enemies will be detonated: if each. rect. bottom> 0: # All enemies on the screen destroy each. active = False

Because the Space key is accidentally pressed, "pygame. event. get () "event response mechanism. The code structure is simple, that is, when the user's keyboard is detected to be pressed and the corresponding key value is" K_SPACE, the number of bombs is reduced by one (if the number of bombs is greater than zero), the full screen bomb sound effects are played, and all enemies on the screen are damaged, here, we can also reflect the advantages in the "enemies" Sprite group structure when instantiating an enemy machine object, which is extremely convenient.

4. Enable the replenishment mechanism

The full-screen bomb was successfully cast, and then the replenishment mechanism was enabled. It is set to issue a replenishment every 10 seconds. We use the trigger time mechanism to complete this function. The replenishment is defined as a user time, which is triggered every 30 seconds, initialize the replenishment package during the response time. First, define the event in the main () function:

Supply_timer = USEREVENT # supply package delivery timer pygame. time. set_timer (supply_timer, 10*1000) # define to issue a supply package every 10 seconds

Note that the Pygame module defines a label for each event in the macro-defined manner to distinguish each time. When defining user events, we also assign an event label to them. To ensure that user-defined event labels do not conflict with System Event labels, pygame specifically provides the "USEREVENT" macro, labeled in (0, USEREVENT-1) events for system time, therefore, specifying the defined user event as "USEREVENT" does not conflict with system events. After the event is defined, call the set_timer () function in the time class to set the event interval triggered by the event. Note that the time here is in milliseconds. Therefore, you need to multiply by 1000 and convert it to seconds.

Of course, to print a supply package smoothly, you must first instantiate it (similar to the instance of an enemy plane ):

#============================================== ==== Bullet_supply = supply. bulletSupply (bg_size) bomb_supply = supply. bombSupply (bg_size)

Next, compile the Event Response Function of the replenishment timer "supply_timer" in the whlie () loop:

#================================================== ========= For event in pygame. event. get (): # respond to the user's accidental operation if event. type = QUIT: # If you press the close button on the screen to trigger the QUIT event, the program exits the elif event. type = supply_timer: # if choice ([True, False]): bomb_supply.reset () else: bullet_supply.reset ()

 

The main task of the event response function is to determine which replenishment package should be instantiated, whether it is a full-screen bomb or a super-bullet replenishment package. This option should be random, so you can use "choice () "implement the random selection mechanism, and then reset the corresponding replenishment package based on the random results (the reset will activate the active variable of the corresponding replenishment object ), then, we will guide the next replenishment mechanism.

5. Check whether the user obtains the replenishment package

After determining the current supply type through the event response function, we need to check whether our plane has successfully picked up the supply package. The core is to implement the collision detection mechanism, first, determine whether the full screen bomb supply package is obtained:

#=========================================================== ========= If bomb_supply.active: # If it is a super bomb supply package bomb_supply.move () screen. bppl( bomb_supply.image, bomb_supply.rect) if pygame. sprite. collide_mask (bomb_supply, me): # if the player obtains the Super bomb replenishment package get_bomb_sound.play () if bomb_num <3: bomb_num + = 1 bomb_supply.active = False

The program idea is very clear. If the full screen bomb supply package is activated, print the icon and start moving automatically. If a collision occurs with our plane during the moving process (true is returned for Collision Detection ), the player is deemed to have successfully obtained the full-screen bomb supply package, and then the number of remaining full-screen bombs is determined. If there are less than three, add one, then, set the active variable of the replenishment package object to false to disable the replenishment object.

Next, determine whether the user has obtained the super bullet supply package. Here, we need to note that after obtaining the full screen bomb, our plane will launch two rounds of bullets, therefore, you need to set a flag "is_double_bullet" to indicate the current bullet status. "is_double_bullet = false" indicates that the current bullet is being fired, "is_double_bullet = true" indicates that a super bullet is currently being fired. First, declare the variable in the main function and initialize it:

Is_double_bullet = False # whether to use a superbullet flag

Then begin the collision detection of the Super bullet supply package:

If bullet_supply.active: # if it is a super bullet supply package bullet_supply.move () screen. blit (bullet_supply.image, bullet_supply.rect) if pygame. sprite. collide_mask (bullet_supply, me): get_bullet_sound.play () is_double_bullet = True bullet_supply.active = False

Since two types of bullet attributes are added, it is necessary to make a judgment before the bullet is drawn. However, we have not yet defined the super bullet class, and we have previously defined the bullet. as mentioned in the py module, Bullet1 represents a normal bullet, and Bullet2 represents a super bullet. Here we add the class definition code of Bullet2 in the bullet module, which has the same structure as Bullet1:

#============================================== ==== Class Bullet2 (pygame. sprite. sprite): def _ init _ (self, position): pygame. sprite. sprite. _ init _ (self) self. image = pygame. image. load (image/bullet2.png) self. rect = self. image. get_rect () self. rect. left, self. rect. top = position self. speed = 14 self. active = True self. mask = pygame. mask. from_surface (self. image) def move (self): if self. rect. top <0: self. active = False else: self. rect. top-= self. speed def reset (self, position): self. rect. left, self. rect. top = position self. active = True

After Bullet2 is defined, a super bullet needs to be instantiated in the main program. Similar to the previous method of instantiating normal bullets (see the previous blog post), here is a little bit of tips on the sequence position of the bullet instance, first with the code:

#============================== Generate a super bullet ====================== === bullet2 = [] bullet2_index = 0 bullet2_num = 10 # define the number of bullet instantiation for I in range (bullet2_num // 2): bullet2.append (bullet. bullet2 (me. rect. centerx-33, me. rect. centery) bullet2.append (bullet. bullet2 (me. rect. centerx + 30, me. rect. centery )))

It can be seen that the superbullet here is instantiated in pairs (10 bullets, divided into 5 cycles), that is, one on the right of the left side of the enemy plane, in this way, as long as two adjacent bullet objects are printed at a time in the future printing process, the "One shot and two shots at a time" effect will be generated. Similarly, how can we achieve three shots and four shots at a time, everyone should be able to master it.

Next, you need to modify the original bullet display program and add a judgment branch. The Code is as follows:

If not (delay % 10): # play the bullet sound effect if not is_double_bullet: # launch a normal bullet else: # if it is a super bullet, bullets = bullet2 bullets [bullet2_index]. reset (me. rect. centerx-33, me. rect. centery) bullets [bullet2_index + 1]. reset (me. rect. centerx + 30, me. rect. centery) bullet2_index = (bullet2_index + 2) % bullet2_num

Sure enough, when printing a super bullet, two adjacent bullets in the bullet group are activated at one time, that is, one bullet is fired on both sides of the bullet group. Here all the intermediate variables bullets are used to simplify the collision detection between the next bullet and the enemy (no need to distinguish between normal and super bullets ). As for (me. rect. centerx-33, me. rect. centery), (me. rect. centerx-33, me. rect. centery) These two coordinates are also experience values, which exactly represent the positions of the two engines of our plane.

6. Set the super bullet time Timer

Running the program, all of the above expected functions are normal, but there is a problem, that is, once we get a super bullet supply package, our plane will launch super bullets endlessly, this is obviously unreasonable. After all, super weapons and super weapons can never be used to reflect their preciousness. Therefore, after we add a mechanism to obtain a super bullet supply package, the conversion of a super bullet can only last for a certain period of time, and automatically becomes a normal bullet after the specified time.

Similarly, we use the event trigger mechanism to complete this function. First, we define this event in the main () function:

Double_bullet_timer = USEREVENT + 1 # super bullet duration Timer

Enable this timer after the Super bullet supply package is obtained successfully:

If bullet_supply.active: # if it is a super bullet supply package pass if pygame. sprite. collide_mask (bullet_supply, me): pass pygame. time. set_timer (double_bullet_timer, 18*1000)

We can see that the duration of the Super bullet is set to 18 seconds. Then write the corresponding Event Response Function and close the super bullet status during the response process:

#================================================== ========= For event in pygame. event. get (): # respond to the user's accidental operation if event. type = QUIT: # If you press the close button on the screen to trigger the QUIT event, the program exits the elif event. type = double_bullet_timer: is_double_bullet = False pygame. time. set_timer (double_bullet_timer, 0)

Note that setting the time trigger time to zero indicates that the event is disabled and the event will be restarted after the next superbullet is obtained. Today's blog is here, with a lot of content. Let's take a look.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.