Table of Contents of Series Articles
StarCraft: Little Overlord and Little Bee (11)--Kill, kill, kill
StarCraft: Little Overlord and Little Bee (10)--Rat Road
StarCraft: Overlord and Bee (9) - Junkrat's Scourge
StarCraft: Little Overlord and Little Bee (8)--Blue Rat and Big-faced Cat
StarCraft: Little Overlord: Little Bee (7)--The disappearing bullet
StarCraft: Little Overlord and Little Bee (6)--Let the Bullets Fly
StarCraft's Little Overlord's Little Bee (5)--Slow down the speed of the Little Bee
StarCraft: Little Overlord and Little Bee (4)--Event Monitoring-Let the Little Bee Move
Table of contents
Table of Contents of Series Articles
1. The key event cannot be monitored
2. Several situations in which the game ends
3. Detect the collision between the little mouse and the little cat
Preface
Yesterday we have completed one of the main parts of the game, which is the collision detection of bullets. We still have some things to solve, such as judging game failure, game scoring, etc. Today we will first implement the function of judging game failure.
1. The key event cannot be monitored
This is a part that has little to do with today's content, but the problems that have existed before have not been solved. Previously we wrote a piece of code that can close the program by pressing the Q key on the keyboard:
elif event.key == pygame.K_q:
sys.exit()
After writing this code, I found that nothing happened when I pressed the Q key. Since it didn’t affect my ability to close the game by clicking the mouse, I ignored it. Before I wrote new code today, I tried to solve it. First, I judged whether the key was pressed. Add an output statement after Q, but when I click Q, there is no output on the console. So I doubted whether a key event was triggered when pressing Q. I judged and monitored the keyboard keys under elif event.type==pygame.KEYDOWN: and added output. It turned out that there was no output when pressing letters, that is, I did not monitor it, but Pressing other keys such as space, arrow keys, and numbers will work, but logically this shouldn't happen. After searching for information in many ways, we finally know the reason: when we run the program, the keyboard input defaults to the Chinese input method. At this time, pressing the letter keys cannot be monitored. We solved this problem by switching to the English input method.
2. Several situations in which the game ends
Closer to home, what we are going to write today is to determine the end of the game. Anyone who plays the game knows that there are several situations when the game ends: one is that the little mouse collides with the little cat, and the game can be judged to be over; Below, it's like tower defense. If you let the mobs run away, Athena will die and the game will be over. Third, when the time is up, the game will be over. If there is a life value or several lives, the first two cases above must be judged to determine whether there is no life, and if there is no life, the game is over.
Based on the above thinking, we write code according to various situations.
3. Detect the collision between the little mouse and the little cat
After updating the position of each little mouse, we determine whether it collides with the little cat.
def update_aliens(new_setting,,ship,aliens):
check_fleet_edges(new_setting,aliens)
aliens.update()
if pygame.sprite.spritecollideany(ship,aliens):
print('完了')
Seeing the above code, we thought of writing the function pygame.sprite.groupcollide that is called when the bullet collides with the mouse. Here we also use a function to make the implementation process very simple.
pygame.sprite.spritecollideany(ship, aliens) is a function in the Pygame library that detects whether a sprite collides with any of a set of sprites. Among them, ship is an elf object, and aliens is an elf group object. If the ship collides with any elf in the aliens, this function will return True, otherwise it will return False.
After the impact is judged here, the follow-up process is not written in the book. I guess it will be written in a unified manner later. I just wrote an output to prove that the judgment function was realized. We increased the speed of the mouse to test it.
You can see a lot of "finished" on the console, because there are a lot of little mice, and any left or right impact will determine success.
4. Cats have nine lives
This game finally endowed the player with several lives, but I think the idea in the book is still very good. Normally, what we think of is to recreate a new little cat, just like exploding bullets and mice. The idea in the book Instead of creating a new tabby cat, only create a variable to record the number of times the tabby cat dies. The tabby cat will still be the same tabby cat. To this end, create a class GameStats to save the statistical information needed in the game.
class GameStats():
def __init__(self,new_setting):
self.new_setting = new_setting
self.reset_stats()
def reset_stats(self):
self.ships_left = self.new_setting.ship_limit
Here self.new_setting.ship_limit, we will set it in the settings module immediately
class Settings():
def __init__(self):
self.screen_width = 800
self.screen_height = 600
self.bg_color = (255,255,255)
self.ship_speed_factor = 0.1
self.ship_limit = 9
self.bullet_speed_factor = 0.5
self.bullet_width = 2
self.bullet_hight = 5
self.bullet_color = 60,60,60
self.bullets_allowed = 20
self.alien_speed_factor = 2
self.fleet_drop_speed = 50
self.fleet_direction = 1
At this point we should think of where we need to use this function. The first thing that comes to mind is after the collision between the mouse and the cat we wrote above, but before update_aliens is called, we need to instantiate it and pass in the actual parameters.
import pygame
import settings
from ship import Ship
import game_functions as gf
from pygame.sprite import Group
from alien import Alien
from game_stats import GameStats
def run_game():
pygame.init()
new_setting=settings.Settings()
screen = pygame.display.set_mode((new_setting.screen_width,new_setting.screen_height))
ship = Ship(screen,new_setting)
alien = Alien(new_setting,screen)
pygame.display.set_caption("狂敲代码的橘子")
bullets = Group()
aliens = Group()
gf.create_fleet(new_setting,screen,aliens)
stats = GameStats(new_setting)
while True:
gf.check_events(new_setting,screen,ship,bullets)
ship.update()
gf.update_bullets(new_setting,screen,bullets,aliens)
gf.update_aliens(new_setting,stats,ship,aliens)
gf.update_screen(new_setting,screen,ship,bullets,aliens)
run_game()
We instantiate it in the main function and then pass it in when calling the update_aliens function. In update_aliens, we need to: first, reduce the life of the little cat by one, second, delete the original mice and create a group of new mice, and third, place the little cat in the initial position, which is the center of the window.
def ship_hit(new_setting,stats,screen,ship,aliens,bullets):
stats.ships_left -= 1
aliens.empty()
bullets.empty()
create_fleet(new_setting, screen, aliens)
ship.center_ship()
time.sleep(0.5)
def update_aliens(new_setting,stats,screen,ship,aliens,bullets):
check_fleet_edges(new_setting,aliens)
aliens.update()
if pygame.sprite.spritecollideany(ship,aliens):
ship_hit(new_setting, stats, screen, ship, aliens, bullets)
This code is not difficult to understand. We found that we have not defined the ship.center_ship() function in the ship class. Its function is to put the little cat in the center. In fact, it is dispensable. I think it is also good to resurrect in place. But according to the book, we still add it to the ship class
def center_ship(self):
self.center = self.screen_rect.centerx
Let's run it and try the effect
5. Athena was attacked
We have analyzed before that, in addition to the collision between the mouse and the kitten, the kitten will lose blood, and the mouse touches the bottom of the screen, which is equivalent to the loss of the tower defense game, and the monster ran away from home. It is very simple to realize this function. We only need to add another judgment after judging the collision between the mouse and the cat. If there is a collision, the follow-up operation is the same as that of the mouse touching the cat. We just call the ship_hit function.
def check_aliens_bottom(new_setting,stats,screen,ship,aliens,bullets):
screen_rect = screen.get_rect()
for alien in aliens.sprites():
if alien.rect.bottom >= screen_rect.bottom:
ship_hit(new_setting,stats,screen,ship,aliens,bullets)
break
def update_aliens(new_setting,stats,screen,ship,aliens,bullets):
check_fleet_edges(new_setting,aliens)
aliens.update()
if pygame.sprite.spritecollideany(ship,aliens):
ship_hit(new_setting, stats, screen, ship, aliens, bullets)
check_aliens_bottom(new_setting, stats, screen, ship, aliens, bullets)
Instead of making the judgment directly in update_aliens like when writing a collision between a little mouse and a little cat, we write the code in the check_aliens_bottom function. In order to test the code effect, we commented out the code that determines the collision between the mouse and the cat to avoid interference.
As you can see, there is no problem after the mouse passes through the cat, and then the mouse regenerates.
6. The game is over
The various situations at the end of the game have been written, but the mice and kittens are still being reborn. The cat's life attribute we set has not been used yet. We added a judgment statement. Every time the kitten returns to its place, its life will be reduced by one. .
def ship_hit(new_setting,stats,screen,ship,aliens,bullets):
stats.ships_left -= 1
aliens.empty()
bullets.empty()
create_fleet(new_setting, screen, aliens)
ship.center_ship()
if stats.ships_left > 0:
stats.ships_left -= 1
time.sleep(0.5)
else:
stats.game_active = False
The book uses the stats.game_active attribute to indicate whether the game is over. I personally think there is no need to go to such trouble. I just use stats.ships_left=0 to indicate that the game is over.
Summarize
There is a beginning and an end, and today we have completed the failure determination of the game.