【发布时间】:2021-11-12 00:26:31
【问题描述】:
我目前正试图让我的外星人在游戏过程中向玩家投掷“炸弹”。我目前的目标是让所有外星人投下炸弹,然后最终让随机外星人在一定级别后投下炸弹。
Currently is seems that all bombs are coming from the starting location of my first alien.
外星人入侵.py
import sys, pygame
from settings import Settings
from ship import Ship
from bombs import Bomb
from alien import Alien
class AlienInvasion:
"""Overall class to manage game assets and behavior."""
def __init__(self):
"""Initlize the game, and create game resources."""
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode((self.settings.screen_width,
self.settings.screen_height))
self.settings.screen_width = self.screen.get_rect().width
self.settings.screen_height = self.screen.get_rect().height
pygame.display.set_caption("Alien Invasion")
self.ship = Ship(self)
self.alien = Alien(self)
self.bullets = pygame.sprite.Group()
self.bombs = pygame.sprite.Group()
self.aliens = pygame.sprite.Group()
self._create_fleet()
#Set our background color
self.bg_color = (230, 230, 230)
def run_game(self):
"""Start main loop for our game."""
while True:
self._check_events()
self.ship.update()
self._drop_bombs()
self._update_bombs()
self._update_aliens()
self._update_screen()
def _check_events(self):
"""Respond to kepresses and mouse events."""
#for each event in game capture that event
for event in pygame.event.get():
#if player preses close, quit game
if event.type == pygame.QUIT:
sys.exit()
# if event is a key press
elif event.type == pygame.KEYDOWN:
self._check_keydown_events(event)
elif event.type == pygame.KEYUP:
self._check_keyup_events(event)
def _check_keydown_events(self, event):
"""respond to keydown events"""
if event.key == pygame.K_RIGHT:
self.ship.moving_right = True
elif event.key == pygame.K_LEFT:
self.ship.moving_left = True
elif event.key == pygame.K_ESCAPE:
sys.exit()
def _check_keyup_events(self, event):
if event.key == pygame.K_RIGHT:
self.ship.moving_right = False
elif event.key == pygame.K_LEFT:
self.ship.moving_left = False
def _drop_bombs(self):
"""drop bombs from alien ships"""
new_bomb = Bomb(self)
for alien in self.aliens:
self.bombs.add(new_bomb)
def _update_bombs(self):
"""update bombs positions and gets rid of old bombs"""
self.screen_rect = self.screen.get_rect()
self.bombs.update()
for bomb in self.bombs.copy():
if bomb.rect.bottom >= self.screen_rect.bottom:
self.bombs.remove(bomb)
def _update_aliens(self):
"""update the position of the aliens"""
self._check_fleet_edges()
self.aliens.update()
self._check_aliens_bottom()
def _create_fleet(self):
"""create our fleet of aliens"""
# creat an alien and fine the number that fits in a row
# spacing between each alien is equal to one alien
alien = Alien(self)
alien_width, alien_height = alien.rect.size
available_space_x = self.settings.screen_width - (2 * alien_width)
number_aliens_x = available_space_x // (2 * alien_width)
# determine the number of rows that fit on the screen
ship_height = self.ship.rect.height
available_space_y = (self.settings.screen_height -
(5 * alien_height) - ship_height)
number_rows = available_space_y // (2 * alien_height)
# create a full fleet of aliens
for row_number in range(number_rows):
for alien_number in range(number_aliens_x):
self._create_alien(alien_number, row_number)
def _create_alien(self, alien_number, row_number):
alien = Alien(self)
alien_width, alien_height = alien.rect.size
alien.x = alien_width + 2 * alien_width * alien_number
alien.rect.x = alien.x
alien.rect.y = 2 * alien_height + 2 * alien.rect.height * row_number
self.aliens.add(alien)
def _check_fleet_edges(self):
"""respond if any aliens reach the edge"""
for alien in self.aliens.sprites():
if alien.check_edges():
self._change_fleet_direction()
break
def _check_aliens_bottom(self):
"""check if any aliens have reached the bottom of the screen"""
screen_rect = self.screen.get_rect()
for alien in self.aliens.sprites():
if alien.rect.bottom >= screen_rect.bottom:
self._ship_hit()
break
def _change_fleet_direction(self):
"""drop entire fleet and change direction"""
for alien in self.aliens.sprites():
alien.rect.y += self.settings.fleet_drop_speed
self.settings.fleet_direction *= -1
def _update_screen(self):
"""Update images on screen and flip to the new screen."""
#fill our background with our bg_color
self.screen.fill(self.settings.bg_color)
#draw ship to screen
self.ship.blitme()
for bullet in self.bullets.sprites():
bullet.draw_bullet()
self.aliens.draw(self.screen)
for bomb in self.bombs.sprites():
bomb.draw_bomb()
#Make the most recently drawn screen visible.
#this clears our previous screen and updates it to a new one
#this gives our programe smooth movemnt
pygame.display.flip()
if __name__ == '__main__':
#Make a game instance, and run the game
ai = AlienInvasion()
ai.run_game()
外星人.py
import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
"""A class to represent a sinlge alien in the fleet"""
def __init__(self, ai_game):
"""initlize alien and set its starting position"""
super().__init__()
self.screen = ai_game.screen
self.settings = ai_game.settings
self.screen_rect = ai_game.screen.get_rect()
# load alien image at set its rect
self.image = pygame.image.load('images/alien.bmp')
self.rect = self.image.get_rect()
# start each new alien at the top left of the screen
self.rect.x = self.rect.width
self.rect.y = self.rect.height
# store aliens exact position (decimal)
self.x = float(self.rect.x)
def check_edges(self):
"""return true if alien is at edge of screen"""
screen_rect = self.screen.get_rect()
if self.rect.right >= screen_rect.right or self.rect.left <= 0:
return True
def update(self):
"""move the alien to the right or left"""
self.x += (self.settings.alien_speed *
self.settings.fleet_direction)
self.rect.x = self.x
炸弹.py
from pygame.sprite import Sprite
class Bomb(Sprite):
"""create a bullet that is dropped by aliens"""
def __init__(self, ai_game):
super().__init__()
self.screen = ai_game.screen
self.settings = ai_game.settings
self.color = self.settings.bullet_color
self.rect = pygame.Rect(0, 0, self.settings.bullet_width,
self.settings.bullet_height)
self.rect.midbottom = ai_game.alien.rect.midbottom
self.y = float(self.rect.y)
def update(self):
"""move bullet down screen"""
self.y += self.settings.bullet_speed
self.rect.y = self.y
def draw_bomb(self):
"""draw bullet to screen"""
pygame.draw.rect(self.screen, self.color, self.rect)
settings.py
class Settings:
"""A class to store our settings for Alien Invasion game."""
def __init__(self):
"""Initlize the games settings."""
# screen settings
self.screen_width = 1600
self.screen_height = 900
self.bg_color = (230, 230, 230)
# ship settings
self.ship_limit = 3
# bullet settings
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 quickly the game speeds up
self.speedup_scale = 1.1
# how muct alien poits value increses
self.score_scale = 1.5
self.initialize_dynamic_settings()
def initialize_dynamic_settings(self):
"""settings that change through the game"""
self.ship_speed = 1.5
self.bullet_speed = 1.5
self.alien_speed = 0.5
self.fleet_direction = 1
# scoring
self.alien_points = 50
def increse_speed(self):
"""increse speed settings"""
self.ship_speed *= self.speedup_scale
self.bullet_speed *= self.speedup_scale
self.alien_speed *= self.speedup_scale
self.alien_points = int(self.alien_points * self.score_scale)
ship.py
from pygame.sprite import Sprite
class Ship(Sprite):
"""A class for managing our ship."""
def __init__(self, ai_game):
"""Initlize the ship and set its starting position."""
super().__init__()
self.screen = ai_game.screen
self.settings = ai_game.settings
self.screen_rect = ai_game.screen.get_rect()
# load ship image and get its rect.(rect stands for rectangle)
self.image = pygame.image.load('images/ship.bmp')
self.rect = self.image.get_rect()
# Start each new ship at the bottom center of the screen.
self.rect.midbottom = self.screen_rect.midbottom
# store a decimal value for the ship's horizontal position
self.x = float(self.rect.x)
# movement flags
# we start our flag at false so the ship doesnt move by itself
self.moving_right = False
self.moving_left = False
def update(self):
"""Update ships position based on our movement flags"""
# update ship's x value, not its rectange
if self.moving_right and self.rect.right < self.screen_rect.right:
self.x += self.settings.ship_speed
if self.moving_left and self.rect.left > 0:
self.x -= self.settings.ship_speed
# update rect object for self.x
self.rect.x = self.x
def blitme(self):
"""Draw the ship at its current location."""
self.screen.blit(self.image, self.rect)
def center_ship(self):
"""center ship"""
self.rect.midbottom = self.screen_rect.midbottom
self.x = float(self.rect.x)
我将如何让每个外星人投下自己的炸弹?
希望这对你们来说遵循最小的可重现示例。
【问题讨论】:
-
如果所有对象都具有相同名称的相同功能 - 即。
draw而不是draw_bomb和blitme- 然后您可以将它们都保留在列表中并使用for-loop 对所有对象执行相同的功能。然后Alien可以将Bomb添加到此列表中,for-loop 将像其他对象一样绘制。
标签: python python-3.x pygame