程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Segmentation fault error in running alien intrusion program in Python introductory practice

編輯:Python

I'm learning 《python Programming : From introduction to practice 》 This book , Complete the first project “ Alien invasion ” The problems encountered are shown in the figure below , Strangely, this error doesn't run every time alien_invasion All the time ( The previous several runs can correctly complete the corresponding logic functions ), After this error, I rerun , Sometimes it works , Sometimes continue to report this error . I don't know why , People are numb .


alien.py The code is as follows

import pygamefrom pygame.sprite import Spriteclass Alien(Sprite): # Class representing a single alien  def __init__(self, ai_settings, screen): # Initialize the alien and set its starting position  super().__init__() self.screen = screen self.ai_settings = ai_settings # Loading alien images , And set its rect attribute  self.image = pygame.image.load('images/alien.bmp') self.image = pygame.transform.scale(self.image, (45, 48)) self.rect = self.image.get_rect() # Each alien was initially near the top left corner of the screen  # The left margin of each alien is set to the width of the alien , And set the upper margin to the height of aliens  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 check_edges(self): # If the alien is on the edge of the screen , Just go back to 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 left or right  self.x += (self.ai_settings.alien_speed_factor * self.ai_settings.fleet_direction) self.rect.x =self.x def blitme(self): # Draw aliens in designated locations  self.screen.blit(self.image, self.rect)

alien_invasion.py The code is as follows

import pygamefrom pygame.sprite import Groupfrom button import Buttonfrom game_stats import GameStatsfrom ship import Shipfrom settings import Settingsimport game_functions as gfdef run_game(): # initialization pygame、 Settings and screen objects pygame.init() ai_settings = Settings() # Create a display window , And specify the size of the game window px, Notice the use of two parentheses screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height)) pygame.display.set_caption("Alien Invasion") ship = Ship(ai_settings, screen) # Create a spaceship bullets = Group() # Create a group to store bullets aliens = Group() # Create an alien group stats = GameStats(ai_settings) # Create an instance to store game statistics gf.create_fleet(ai_settings, screen, ship, aliens) # Creating alien groups play_button = Button(ai_settings, screen, 'Play') # establish Play Button # Start the main cycle of the game while True: gf.check_events(ai_settings, screen, stats, play_button, ship, aliens, bullets) # Monitor keyboard and mouse events if stats.game_active: ship.update() # Update the position of the ship gf.update_bullets(ai_settings, screen, ship, aliens, bullets) # Update the location of all bullets that have not disappeared gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets) gf.update_screen(ai_settings, screen, stats, ship, aliens, bullets, play_button) # Use the updated position to redraw the new screen run_game() # This will initialize the game and start the main loop 

bullet.py Code block

import pygamefrom pygame.sprite import Spriteclass Bullet(Sprite): """ A class that manages the bullets fired by a spaceship """ def __init__(self, ai_settings, screen, ship): # Create a bullet object where the ship is located  super().__init__() self.screen = screen # stay (0,0) Create a rectangle representing the bullet at , Set 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 # Will represent the... Of a bullet rect Of top Property is set to the ship's rect Of top attribute , Make the bullet look like it was shot from a spaceship  # 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 # After launch , The bullet moves up the screen , It means y The coordinates will decrease  # Update for bullets rect The location of  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 Code block

import pygame.font # Render text to the screen 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 = (67, 205, 128) self.text_color = (255, 255, 255) self.font = pygame.font.SysFont(None, 48) # Actual parameters None Give Way Pygame Use default font ,48 Specify the font size of the text . # Create button's rect object , And center it  self.rect = pygame.Rect(0, 0, self.width, self.height) self.rect.center = self.screen_rect.center # The label of the button needs to be created only once  self.prep_msg(msg) def prep_msg(self, msg): # take msg Render as image , And center it on the 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 , Redraw text  self.screen.fill(self.button_color, self.rect) self.screen.blit(self.msg_image, self.msg_image_rect)

game_functions.py Code block :

import sys # When players exit , Using modules sys Quit the game from time import sleepimport pygamefrom alien import Alienfrom bullet import Bulletdef check_keydown_events(event, ai_settings, screen, ship, bullets): # Response button  if event.key == pygame.K_RIGHT: ship.moving_right = True elif event.key == pygame.K_LEFT: ship.moving_left = True elif event.key == pygame.K_UP: ship.moving_up = True elif event.key == pygame.K_DOWN: ship.moving_down = True elif event.key == pygame.K_SPACE: fire_bullet(ai_settings, screen, ship, bullets)def check_keyup_events(event, ship): # Response loosening  if event.key == pygame.K_RIGHT: ship.moving_right = False elif event.key == pygame.K_LEFT: ship.moving_left = False elif event.key == pygame.K_UP: ship.moving_up = False elif event.key == pygame.K_DOWN: ship.moving_down = False elif event.key == pygame.K_q: sys.exit()def check_events(ai_settings, screen, stats, play_button, ship, aliens, bullets): # Respond to key and mouse events  for event in pygame.event.get(): if event.type == pygame.QUIT: # When the player clicks the close button of the game window, it is detected that  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, play_button, ship, aliens, bullets, mouse_x, mouse_y)def check_play_button(ai_settings, screen, stats, play_button, ship, aliens, bullets, mouse_x, mouse_y): # Player Click 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: # hide cursor  pygame.mouse.set_visible(False) # Reset game statistics  stats.reset_stats() stats.game_active = True # Empty alien list and bullet list  aliens.empty() bullets.empty() # Create a new group of Aliens , And center the ship  create_fleet(ai_settings, screen, ship, aliens) ship.center_ship()def update_screen(ai_settings, screen, stats, ship, aliens, bullets, play_button): # Update image on screen , And switch to the new screen  # Redraw the screen every time you cycle  screen.fill(ai_settings.bg_color) # Redraw all the bullets behind the spaceship and the alien  for bullet in bullets.sprites(): bullet.draw_bullet() ship.blitme() aliens.draw(screen) # If the game is inactive , Just draw Play Button  if not stats.game_active: play_button.draw_button() # Constantly update the screen , Make the most recently drawn screen visible  # As we move game elements ,pygame.display.flip() The screen will be constantly updated , To display the new position of the element , And hide the element in its original position , So as to create the effect of smooth movement . pygame.display.flip()def update_bullets(ai_settings, screen, ship, aliens, 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, ship, aliens, bullets)def check_bullet_alien_collisions(ai_settings, screen, ship, aliens, bullets): # In response to the collision between the bullet and the alien  # Delete bullets and aliens in collision  collisions = pygame.sprite.groupcollide(bullets, aliens, True, True) if len(aliens) == 0: # Delete existing bullets and create a new group of Aliens  bullets.empty() create_fleet(ai_settings, screen, ship, aliens)def fire_bullet(ai_settings, screen, ship, bullets): # If the limit is not reached , Just fire a bullet  # Create a bullet , And add it to the group bullets in  if len(bullets) < ai_settings.bullets_allowed: new_bullet = Bullet(ai_settings, screen, ship) bullets.add(new_bullet)def get_number_aliens_x(ai_settings, alien_width): # Calculate how many aliens per row  avaliable_space_x = ai_settings.screen_width - 2 * alien_width number_aliens_x = int(avaliable_space_x / (2 * alien_width)) return number_aliens_xdef 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_rowsdef create_alien(ai_settings, screen, aliens, alien_number, row_number): # Create an alien and put it on the current line  alien = Alien(ai_settings, screen) alien_width = alien.rect.width # From alien rect Property to get the alien 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 alien groups  # 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 alien_number in range(number_aliens_x): # create_alien(ai_settings, screen, aliens, alien_number) # Creating alien groups  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) breakdef change_fleet_direction(ai_settings, aliens): # Move the whole group of aliens down , And change their direction  for alien in aliens.sprites(): alien.rect.y += ai_settings.fleet_drop_speed ai_settings.fleet_direction *= -1def ship_hit(ai_settings, stats, screen, ship, aliens, bullets): # Responding to a spaceship hit by an alien  if stats.ships_left > 0: # take ship_left reduce 1 stats.ships_left -= 1 # Empty alien list and bullet list  aliens.empty() bullets.empty() # Create a new group of aliens , And put the ship in the center of the bottom  create_fleet(ai_settings, screen, ship, aliens) ship.center_ship() # Pause  sleep(0.5) else: stats.game_active = False pygame.mouse.set_visible(True)def check_aliens_bottom(ai_settings, stats, screen, 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: # Deal with it as if it were hit by a spaceship  ship_hit(ai_settings, stats, screen, ship, aliens, bullets) breakdef update_aliens(ai_settings, stats, screen, ship, aliens, bullets): # Check if any aliens have reached the bottom of the screen  check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets) # Check for aliens on the edge of the screen , And 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, stats, screen, ship, aliens, bullets)

game_stats.py Code block

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 def reset_stats(self): # Initialize statistics that may change during the game run  self.ships_left = self.ai_settings.ship_limit

settings Code block

class Settings(): # A class that stores all the settings for the project  def __init__(self): # Initialize game settings  # screen setting  self.screen_width = 1000 self.screen_height = 700 self.bg_color = (230, 230, 230) # Spacecraft setup  self.ship_left_right_speed_factor = 1.5 # Left and right movement speed self.ship_up_down_speed_factor = 1.5 self.ship_limit = 3 # Bullet settings  self.bullet_speed_factor = 3 self.bullet_width = 3 self.bullet_height = 15 self.bullet_color = 178, 34, 34 self.bullets_allowed = 3 # Alien settings  self.alien_speed_factor = 0.3 # Alien movement speed setting self.fleet_drop_speed = 10 # The speed at which the aliens move down # fleet_direction by 1 Move to the right , by -1 Move left  self.fleet_direction = 1

ship.py Code block

import pygameclass Ship(): def __init__(self, ai_settings, screen): # Initialize the spacecraft and set its initial position  self.screen = screen self.ai_settings = ai_settings # Load the image of the spacecraft and get its external rectangle  self.image = pygame.image.load('images/ship.bmp') self.image = pygame.transform.scale(self.image, (40, 70)) # take Surface Attribute self.image Turn into 30×30 Size  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 # Properties in the spaceship center Small value stored in  self.centerx = float(self.rect.centerx) self.centery = float(self.rect.centery) # Mobile logo  self.moving_right = False self.moving_left = False self.moving_up = False self.moving_down = False def update(self): # Adjust the position of the spacecraft according to the moving signs  # Update the ship's center value , instead of rect # Make the spacecraft stop moving when it reaches the edge of the screen  if self.moving_right and (self.rect.right < self.screen_rect.right): # Mark is True Move the ship to the right  self.centerx += self.ai_settings.ship_left_right_speed_factor if self.moving_left and (self.rect.left > 0): self.centerx -= self.ai_settings.ship_left_right_speed_factor if self.moving_down and (self.rect.bottom < self.screen_rect.bottom): self.centery += self.ai_settings.ship_up_down_speed_factor if self.moving_up and (self.rect.top > 0): self.centery -= self.ai_settings.ship_up_down_speed_factor # according to self.centerx/y to update rect object  self.rect.centerx = self.centerx self.rect.centery = self.centery 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 self.rect.midbottom = self.screen_rect.midbottom self.centerx = float(self.rect.centerx) self.centery = float(self.rect.centery)

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved