This project is a project that our teacher asked us to do after contacting Python for one semester. Of course, it was just contacted. It must have been written in accordance with the book. During this period, there were many mistakes, many rewrites and many changes. It took about four days. I didn't understand anything, so it was slow. Let's put the source code on it,
This is the renderings
alien_invasion.py
import pygame from pygame.sprite import Group from settings import Settings from game_stats import GameStats from scoreboard import Scoreboard from button import Button from ship import Ship import game_functions as gf def run_game(): #Initialize the game and create a screen object pygame.init() ai_settings = Settings() screen = pygame.display.set_mode( (ai_settings.screen_width,ai_settings.screen_height)) pygame.display.set_caption("Alien Invasion") #Create play button play_button=Button(ai_settings,screen,"play") #Create an instance to store game statistics and create a scoreboard stats=GameStats(ai_settings) sb=Scoreboard(ai_settings,screen,stats) ship = Ship(ai_settings,screen) bullets=Group() aliens=Group() #Creating alien groups gf.create_fleet(ai_settings,screen,ship,aliens) #Start the main cycle of the game while True: #Monitor keyboard and mouse events gf.check_events(ai_settings,screen,stats,sb,play_button,ship, aliens,bullets) if stats.game_active: ship.update() #Make the most recently drawn screen visible gf.update_bullets(ai_settings,screen,stats,sb,ship,aliens, bullets) gf.update_aliens(ai_settings,screen,stats,sb,ship,aliens, bullets) gf.update_screen(ai_settings,screen,stats,sb,ship,aliens, bullets, play_button) run_game()
game_functions.py
In large projects, refactor existing code before adding new code. Refactoring aims to simplify the structure of existing code and make it easier to expand. Create a new module that will store a large number of functions to run the game alien invasion. By creating module game_ functions, which can avoid the too long of alien inasiopy and make its logic easier to understand.
import sys from time import sleep import pygame from bullet import Bullet from alien import Alien def check_keydown_events(event,ai_settings,screen,ship,bullets): """Response key""" if event.key == pygame.K_RIGHT : # Move the ship to the right ship.moving_right = True elif event.key == pygame.K_LEFT : ship.moving_left = True elif event.key==pygame.K_SPACE: fire_bullet(ai_settings,screen,ship,bullets) #Create a bullet and add it to the group bullets elif event.key==pygame.K_q: sys.exit() def check_keyup_events(event,ship): """Response release""" if event.key == pygame.K_RIGHT : # Move the ship to the right ship.moving_right = False elif event.key == pygame.K_LEFT : # Move the ship to the left ship.moving_left = False def check_events(ai_settings,screen,stats,sb,play_button,ship,aliens,bullets): """Corresponding key and mouse events""" for event in pygame.event.get() : if event.type == pygame.QUIT : sys.exit() elif event.type==pygame.KEYDOWN: check_keydown_events(event,ai_settings,screen,ship,bullets) elif event.type==pygame.KEYUP: check_keyup_events(event,ship) elif event.type==pygame.MOUSEBUTTONDOWN: mouse_x,mouse_y=pygame.mouse.get_pos() check_play_button(ai_settings,screen,stats,sb,play_button, ship,aliens,bullets,mouse_x,mouse_y) def check_play_button(ai_settings,screen,stats,sb,play_button,ship, aliens,bullets,mouse_x,mouse_y): """Click on the player play Button to start a new game""" button_clicked=play_button.rect.collidepoint(mouse_x,mouse_y) if button_clicked and not stats.game_active: #Reset game settings ai_settings.initialize_dynamic_settings() #hide cursor pygame.mouse.set_visible(False) #Reset game statistics stats.reset_stats() stats.game_active=True #Reset scoreboard image sb.prep_score() sb.prep_high_score() sb.prep_level() sb.prep_ships() #Empty alien list and bullet list aliens.empty() bullets.empty() #Create a new group of aliens and center the spacecraft create_fleet(ai_settings,screen,ship,aliens) ship.center_ship() def update_screen(ai_settings,screen,stats,sb,ship,aliens,bullets, play_button): """Update screen and switch to new screen""" #Redraw the screen every time you cycle screen.fill(ai_settings.bg_color) for bullet in bullets.sprites(): bullet.draw_bullet() ship.blitme() aliens.draw(screen) #Show score sb.show_score() #If the game is inactive, draw the play button if not stats.game_active: play_button.draw_button() pygame.display.flip() def update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets): """Update the location of bullets and delete the disappeared bullets""" #Update bullet position bullets.update() #Delete bullets that have disappeared for bullet in bullets.copy() : if bullet.rect.bottom <= 0 : bullets.remove(bullet) check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship, aliens,bullets) def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship, aliens,bullets): """In response to a collision between a bullet and an alien""" #Delete bullets and aliens in collision collisions = pygame.sprite.groupcollide(bullets, aliens, True, True) if collisions: for aliens in collisions.values(): stats.score += ai_settings.alien_points*len(aliens) sb.prep_score() check_high_score(stats,sb) if len(aliens) == 0 : # Delete existing bullets and create a new group of Aliens bullets.empty() ai_settings.increase_speed() #Improve the level stats.level += 1 sb.prep_level() create_fleet(ai_settings, screen, ship, aliens) def fire_bullet(ai_settings,screen,ship,bullets): if len(bullets) < ai_settings.bullets_allowed : new_bullet = Bullet(ai_settings, screen, ship) bullets.add(new_bullet) # Move the ship to the left def get_number_aliens_x(ai_settings,alien_width): available_space_x = ai_settings.screen_width - 2 * alien_width number_aliens_x = int(available_space_x / (2 * alien_width)) return number_aliens_x def get_number_rows(ai_settings,ship_height,alien_height): """How many lines of aliens can the screen hold""" available_space_y = (ai_settings.screen_height - (3*alien_height)-ship_height) number_rows=int(available_space_y/(2*alien_height)) return number_rows def create_alien(ai_settings,screen,aliens,alien_number,row_number): #Create an alien and join the current line alien = Alien(ai_settings, screen) alien_width = alien.rect.width alien.x = alien_width + 2 * alien_width * alien_number alien.rect.x = alien.x alien.rect.y=alien.rect.height+2*alien.rect.height*row_number aliens.add(alien) def create_fleet(ai_settings,screen,ship,aliens): """Creating aliens""" #Create an alien and calculate how many aliens a row can hold #Space between aliens is alien width alien=Alien(ai_settings,screen) number_aliens_x=get_number_aliens_x(ai_settings,alien.rect.width) number_rows=get_number_rows(ai_settings,ship.rect.height, alien.rect.height) #Create the first line of Aliens for row_number in range(number_rows): for alien_number in range(number_aliens_x): create_alien(ai_settings,screen,aliens,alien_number, row_number) def check_fleet_edges(ai_settings,aliens): """Take action when an alien reaches the edge""" for alien in aliens.sprites(): if alien.check_edges(): change_fleet_direction(ai_settings,aliens) break def change_fleet_direction(ai_settings,aliens): """Move the whole group down and change their direction""" for alien in aliens.sprites(): alien.rect.y+=ai_settings.fleet_drop_speed ai_settings.fleet_direction *= -1 def ship_hit(ai_settings,screen,stats,sb,ship,aliens,bullets): """Responding to a spaceship hit by an alien""" if stats.ships_left>0: #Ship_ left -= 1 stats.ships_left -= 1 #Update scoreboard sb.prep_ships() #Empty alien list and bullet list aliens.empty() bullets.empty() #Create a new group of aliens and put the spacecraft in the center of the bottom of the screen create_fleet(ai_settings,screen,ship,aliens) ship.center_ship() #suspend sleep(0.5) else: stats.game_active=False pygame.mouse.set_visible(True) def update_aliens(ai_settings,screen,stats,sb,ship,aliens,bullets): """Update the location of all aliens in the alien population""" check_fleet_edges(ai_settings,aliens) aliens.update() #Detect collisions between aliens and spacecraft if pygame.sprite.spritecollideany(ship,aliens): ship_hit(ai_settings,screen,stats,sb,ship,aliens,bullets) check_aliens_bottom(ai_settings,screen,stats,sb,ship,aliens,bullets) def check_aliens_bottom(ai_settings,screen,stats,sb,ship,aliens, bullets): """Check if any aliens have reached the bottom of the screen""" screen_rect=screen.get_rect() for alien in aliens.sprites(): if alien.rect.bottom >= screen_rect.bottom: #It's handled like a spaceship hit ship_hit(ai_settings,screen,stats,sb,ship,aliens,bullets) break def check_high_score(stats,sb): """Check if the new highest score is born""" if stats.score > stats.high_score: stats.high_score = stats.score sb.prep_high_score()
alien.py
Most of the aliens
import pygame from pygame.sprite import Sprite class Alien(Sprite): """Represents a single alien human""" def __init__(self,ai_settings,screen): """Initialize the alien and set its starting position""" super(Alien, self).__init__() self.screen=screen self.ai_settings=ai_settings #Load the alien image and set its rect property self.image=pygame.image.load('images/alien.bmp') self.rect=self.image.get_rect() #Each alien was initially near the top left corner of the screen self.rect.x=self.rect.width self.rect.y=self.rect.height #Store the exact location of Aliens self.x=float(self.rect.x) def blitme(self): """Draw aliens in designated locations""" self.screen.blit(self.image,self.rect) def check_edges(self): """If the alien is on the edge of the screen, go back True""" screen_rect=self.screen.get_rect() if self.rect.right>=screen_rect.right: return True elif self.rect.left<=0: return True def update(self): """Move aliens right""" self.x += (self.ai_settings.alien_speed_factor * self.ai_settings.fleet_direction) self.rect.x=self.x
bullet.py
In charge of bullets
import pygame from pygame.sprite import Sprite class Bullet(Sprite): """A class of bullet management for a team of spaceships""" def __init__ (self,ai_settings,screen,ship): """Create a bullet object where the ship is located""" super(Bullet,self).__init__() self.screen=screen #Create a rectangle representing the bullet at (0.0) and set it in the correct position self.rect=pygame.Rect(0,0,ai_settings.bullet_width, ai_settings.bullet_height) self.rect.centerx=ship.rect.centerx self.rect.top=ship.rect.top #Store bullet position in decimal self.y=float(self.rect.y) self.color=ai_settings.bullet_color self.speed_factor=ai_settings.bullet_speed_factor def update(self): """Move the bullet up""" #Update the small value indicating the bullet position self.y-=self.speed_factor #Update rectde position of bullet self.rect.y=self.y def draw_bullet(self): """Draw bullets on the screen""" pygame.draw.rect(self.screen,self.color,self.rect)
button.py
Responsible button
import pygame.font class Button(): def __init__(self,ai_settings,screen,msg): """Initialize button properties""" self.screen=screen self.screen_rect=screen.get_rect() #Set button size and other properties self.width,self.height=200,50 self.button_color=(1,220,212) self.text_color=(255,255,255) self.font=pygame.font.SysFont(None,48) #Create and center the button's rect object self.rect=pygame.Rect(0,0,self.width,self.height) self.rect.center=self.screen_rect.center #Button labels only need to be created once self.prep_msg(msg) def prep_msg(self,msg): """take msg Render to image and center button""" self.msg_image=self.font.render(msg,True,self.text_color, self.button_color) self.msg_image_rect=self.msg_image.get_rect() self.msg_image_rect.center=self.rect.center def draw_button(self): #Draw a color filled button to draw text self.screen.fill(self.button_color,self.rect) self.screen.blit(self.msg_image,self.msg_image_rect)
game_stats.py
Statistics game information
class GameStats(): """Track game statistics""" def __init__(self,ai_settings): """Initialize statistics""" self.ai_settings=ai_settings self.reset_stats() #Make the game inactive at the beginning self.game_active=False self.high_score=0 def reset_stats(self): """Initializes statistics that may change during play""" self.ships_left=self.ai_settings.ship_limit self.score=0 self.level=0
scoreboard.py
Scores
import pygame.font from pygame.sprite import Group from ship import Ship class Scoreboard(): """Categories of realistic score information""" def __init__(self,ai_settings,screen,stats): """Attribute involved in initializing display score""" self.screen=screen self.screen_rect=screen.get_rect() self.ai_settings=ai_settings self.stats=stats #Font settings used to display score information self.text_color=(30,30,30) self.font=pygame.font.SysFont(None,48) #Prepare initial score image self.prep_score() self.prep_high_score() self.prep_level() self.prep_ships() def prep_score(self): """Convert score to a rendered image""" rounded_score=int(round(self.stats.score,-1)) score_str="{:,}".format(rounded_score) score_str=str(self.stats.score) self.score_image=self.font.render(score_str,True,self.text_color, self.ai_settings.bg_color) #Put the score in the top right corner of the screen self.score_rect=self.score_image.get_rect() self.score_rect.right=self.screen_rect.right-20 self.score_rect.top=20 def show_score(self): """Display score and maximum score on screen""" self.screen.blit(self.score_image,self.score_rect) self.screen.blit(self.high_score_image,self.high_score_rect) self.screen.blit(self.level_image,self.level_rect) #Draw spacecraft self.ships.draw(self.screen) def prep_high_score(self): """Convert highest score to rendered image""" high_score=int(round(self.stats.high_score,-1)) high_score_str="{:,}".format(high_score) self.high_score_image=self.font.render(high_score_str,True, self.text_color,self.ai_settings.bg_color) #Center the highest score on the top of the screen self.high_score_rect=self.high_score_image.get_rect() self.high_score_rect.centerx=self.screen_rect.centerx self.high_score_rect.top=self.score_rect.top def prep_level(self): """Convert levels to rendered images""" self.level_image=self.font.render(str(self.stats.level),True, self.text_color,self.ai_settings.bg_color) #Put the grade below the score self.level_rect =self.level_image.get_rect() self.level_rect.right=self.score_rect.right self.level_rect.top=self.score_rect.bottom+10 def prep_ships(self): """Show how many ships are left""" self.ships=Group() for ship_number in range(self.stats.ships_left): ship=Ship(self.ai_settings,self.screen) ship.rect.x=10+ship_number*ship.rect.width ship.rect.y=10 self.ships.add(ship)
settings.py
Every time you add a new feature to a game, you'll usually introduce some new settings as well. Next, write a module named settings, which contains a class named settings, which is used to store all settings in one place, so as not to replace
Add settings everywhere in the code. In this way, we can pass one setting object instead of many different settings. In addition, this makes function calls easier, and it's easier to change the look of the game as the project grows: to change the game, just change it
settings.py Values in without looking for different settings scattered in the file.
class Settings(): """Store the set class of alien invasion""" def __init__(self): """Initialize game settings""" #screen setting self.screen_width = 1200 self.screen_height = 800 self.bg_color = (164, 177, 161) #Spaceship setup self.ship_limit = 3 #Bullet setting self.bullet_width=3 self.bullet_height=15 self.bullet_color=60,60,60 self.bullets_allowed = 3 #Alien settings self.fleet_drop_speed=10 #How to speed up the game self.speedup_scale=1.1 #Alien points increase speed self.score_scale=1.5 self.initialize_dynamic_settings() def initialize_dynamic_settings(self): self.ship_speed_factor = 1.5 self.bullet_speed_factor = 7 self.alien_speed_factor = 0.6 #fleet_ 1 for direction to right, - 1 for left self.fleet_direction=1 #scoring self.alien_points=50 def increase_speed(self): """Increase speed settings""" self.ship_speed_factor*=self.speedup_scale self.bullet_speed_factor*=self.speedup_scale self.alien_speed_factor*=self.speedup_scale self.alien_points=int(self.alien_points*self.score_scale) self.alien_points=int(self.alien_points*self.score_scale)
ship.py
Manage most of the ship's behavior
import pygame from pygame.sprite import Sprite class Ship(Sprite) : def __init__(self, ai_settings, screen): """"Initialize the spacecraft and set its initial position""" super(Ship,self).__init__() self.screen = screen self.ai_settings = ai_settings #Loading spacecraft image and obtaining its external rectangle self.image=pygame.image.load('images/ship.bmp') self.rect=self.image.get_rect() self.screen_rect=screen.get_rect() #Put each new ship in the center of the bottom of the screen self.rect.centerx=self.screen_rect.centerx self.rect.bottom=self.screen_rect.bottom self.center=float(self.rect.centerx) #Mobile sign self.moving_right = False self.moving_left = False def update(self): """Adjust the position of the spacecraft according to the moving signs""" #Update the center value of the ship instead of rect if self.moving_right and self.rect.right < self.screen_rect.right: self.center += self.ai_settings.ship_speed_factor if self.moving_left and self.rect.left > 0: self.center -= self.ai_settings.ship_speed_factor #according to self.center Update rect object self.rect.centerx = self.center def blitme (self): """Draw the spacecraft at the designated location""" self.screen.blit(self.image,self.rect) def center_ship(self): """Center the ship on the screen""" self.center=self.screen_rect.centerx
Among them, the picture can be screenshot of the rendering of the home page, and then converted into a bitmap, if you need the source code @ qq82401402. com