2016-12-10 8 views
-2

私は今、最後の2日間は固まっています。ネストされたループのファイルgame_functionでは、私はエイリアンを作成しています。ランダムな乱数を作成するためにrandintを追加したとき、問題に遭遇しました。エイリアンクラスのエイリアン/スプライトのメソッドとしてスプライトエッジを検出したときには常に(ゲームを再実行するだけではない)時々、方向を変えずにx軸を右にたどり、常にエイリアンがチェックエッジの各パスをドロップダウンします。私はそれが何であるか分からない。私がランダムな乱数を連続して生成するためにranditを使用していないときは、すべてがうまくいっていました。機能create_fleetでスプライトは、それがそのままの形で動作しません

settings.py

class Settings(): 
"""A class to store all settings for Alien Invasion""" 
def __init__(self): 
    """Initialize the game settings""" 
    #Screen settings 
    self.screen_width = 1200 
    self.screen_height = 800 
    self.bg_color = (230,230,230) 
    #ship settings 
    self.ship_speed_factor = 1.5 
    #Bullet settings 
    self.bullet_speed_factor = 1 
    self.bullet_width = 3 
    self.bullet_height = 15 
    self.bullet_color = (60, 60, 60) 
    self.bullets_allowed = 3 
    # Alien settings 
    self.alien_speed_factor = 1 
    self.fleet_drop_speed = 10 
    # fleet_direction of 1 represents right; -1 represents left. 
    self.fleet_direction = 1 

ship.py

import pygame 

class Ship(): 

def __init__(self,ai_settings, screen): 
    """Initialize the ship and sets the starting position.""" 
    self.screen = screen 
    self.ai_settings = ai_settings 
    #load the ship image and get its rect 
    self.image = pygame.image.load('images/ship.png') 
    self.rect = self.image.get_rect() 
    self.screen_rect = screen.get_rect() 

    # Start each new ship at the bottom center of the screen 
    self.rect.centerx = self.screen_rect.centerx 
    self.rect.bottom = self.screen_rect.bottom 
    self.center = float(self.rect.centerx) 

    #Movement Flag 
    self.moving_right = False 
    self.moving_left = False 


def update(self): 
    """Update the ship's position based on the movement Flag.""" 
    #Update the ship's center value, not the 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 


    #update rect object from self.center 
    self.rect.centerx = self.center 


def blitme(self): 
    """Draw the ship at its current location""" 
    self.screen.blit(self.image, self.rect) 

(ai_settings、スクリーン、船、エイリアン)は、ネストされたループであり、場合代わりに3-間の乱数を生成します9そして新しいインスタンスを行に配置する定数計算を使用していますが、常に9人のエイリアンに行を渡しています。エイリアンは毎回の指示に変更され、次のcheck_edgeイベントが条件をパスするまで1回だけドロップされました。 1つの壁から別の壁まで。今、ランデントが存在するとき、常にではなく、check_edgeメソッドが真であることを確認すると、change_fleet_direction()関数が呼び出され、そこに問題があり、時には方向を変えないことがあります。 directionは単純に+1または-1だけ使用され、Alienクラスの更新を呼び出す場合は、x軸を減らすか、またはエッジイベントまで増加させる必要があります。

game_functions.py

import sys 
import pygame 
from bullet import Bullet 
from alien import Alien 
from random import randint 


def create_fleet(ai_settings, screen, ship, aliens): 
    """Create a full fleet of aliens.""" 
    #Create an Alien and find the number of aliens in a row 
    name= 'First unused' 
    alien = Alien(ai_settings, screen,name) 
    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 fleet of aliens. 
    for row_number in range(number_rows): 
     random_num = randint(3, number_aliens_x) 
     for alien_number in range(0, random_num): 
      create_alien(ai_settings, screen, aliens, alien_number, 
         row_number) 


def get_number_aliens_x(ai_settings, alien_width):  
    """Determine the number of aliens that fit in a row.""" 
    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): 
    """Determine the number of rows of aliens that fit on the screen.""" 
    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 alien and place it in the row""" 

    name = "Alien number " + str(alien_number) + " in row " + str(row_number)   
    alien = Alien(ai_settings, screen, name) 
    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 check_keydown_events(event, ai_settings, screen, ship, bullets): 
    """Respond to key presses"""      
    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_SPACE: 
     fire_bullet(ai_settings, screen, ship, bullets) 
    elif event.key == pygame.K_q: 
     sys.exit() 


def fire_bullet(ai_settings, screen, ship, bullets): 
    # Create a new bullet and add it to the bullets group. 
     if len(bullets) < ai_settings.bullets_allowed: 
      new_bullet = Bullet(ai_settings, screen, ship) 
      bullets.add(new_bullet) 


def check_keyup_events(event,ship): 
    """Respond to key releases""" 
    if event.key == pygame.K_RIGHT: 
     ship.moving_right = False 
    elif event.key == pygame.K_LEFT: 
     ship.moving_left = False 


def check_events(ai_settings, screen, ship, bullets): 
    """Respond to keypress 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) 


def update_screen(ai_settings, screen, ship, aliens, bullets): 
    """Update images on the screen and flip to the new screen.""" 
    # Redraw the screen during each pass through the loop. 
    screen.fill(ai_settings.bg_color) 
    # Redraw all bullets behind ship and aliens. 
    for bullet in bullets.sprites(): 
     bullet.draw_bullet() 
    ship.blitme() 
    aliens.draw(screen) 
    # Make the most recently drawn screen visible. 
    pygame.display.flip() 


def update_bullets(bullets): 
    """Update position of bullets and get rid of old bullets.""" 
    # Update bullet positions. 
    bullets.update() 
    # Get rid of bullets that have disappeared. 
    for bullet in bullets.copy(): 
     if bullet.rect.bottom <= 0: 
      bullets.remove(bullet)  


def check_fleet_edges(ai_settings, aliens): 
     """Respond appropriately if any aliens have reached an edge.""" 
     for alien in aliens.sprites(): 
      if alien.check_edges(): 
       print(alien.name) 
       change_fleet_direction(ai_settings, aliens) 
       break 


def change_fleet_direction(ai_settings, aliens): 
    """Drop the entire fleet and change the fleet's direction.""" 
    print("old direction " + str(ai_settings.fleet_direction)) 
    for alien in aliens.sprites(): 
     alien.rect.y += ai_settings.fleet_drop_speed 
     if ai_settings.fleet_direction == 1: 
      ai_settings.fleet_direction = -1 
     else: 
      ai_settings.fleet_direction = 1 

    print("new direction" + str(ai_settings.fleet_direction)) 


def update_aliens(ai_settings, aliens): 
    """ 
    Check if the fleet is at an edge, 
    and then update the positions of all aliens in the fleet. 
    """ 
    check_fleet_edges(ai_settings, aliens) 
    aliens.update() 

メインファイルalien_invasion.py

import pygame 
from pygame.sprite import Group 
from settings import Settings 
from ship import Ship 
import game_functions as gf 


def run_game(): 
# Initialize 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") 
    ship = Ship(ai_settings,screen) 
    #Make a group to store bullets in 
    bullets = Group() 
    aliens = Group() 

    #Create the fleet of aliens 
    gf.create_fleet(ai_settings, screen, ship, aliens) 
    # Start the main loop for the game. 
    while True: 

     gf.check_events(ai_settings, screen, ship, bullets) 
     ship.update() 
     bullets.update() 
     gf.update_bullets(bullets) 
     gf.update_aliens(ai_settings, aliens)     
     gf.update_screen(ai_settings, screen, ship, aliens, bullets) 

run_game() 

bullet.py

import pygame 
from pygame.sprite import Sprite 


class Bullet(Sprite): 
"""A class to manage bullets fired from the ship""" 

    def __init__(self, ai_settings, screen, ship): 
     """create a bullet object at the ship's current position""" 
     super().__init__() 
     self.screen = screen 

     #Create a bullet rect at (0, 0) and then set 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 the bullet position as a decimal value. 
     self.y = float(self.rect.y) 

     self.color = ai_settings.bullet_color 
     self.speed_factor = ai_settings.bullet_speed_factor 

    def update(self): 
     """Move bullet up the scereen""" 
     #Update the decimal position of the bullet 
     self.y -= self.speed_factor 
     #Update the rect position 
     self.rect.y = self.y 

    def draw_bullet(self): 
     """Draw the bullet to the screen""" 
     pygame.draw.rect(self.screen, self.color, self.rect) 

alien.py

import pygame 
from pygame.sprite import Sprite 

class Alien(Sprite): 
"""A class to represent a single alien in the fleet""" 
def __init__(self, ai_settings, screen, name): 
    """Initialize the alien and set its starting position""" 
    super().__init__() 
    self.screen = screen 
    self.ai_settings = ai_settings 

    #Load the alien image and set its rect attribute. 
    self.image = pygame.image.load('images/alien.bmp') 
    self.rect = self.image.get_rect() 

    #Start each alien near the top left of the screen 
    self.rect.x = self.rect.width 
    self.rect.y = self.rect.height 

    #Store the alien's exact position 
    self.x = float(self.rect.x) 
    self.name = name 

#  def blitme(self): 
#   """Draw the alien at its current location.""" 
#   self.screen.blit(self.image, self.rect) 
#    

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: 
     print("Right >= right screen" +' direction is' + str(self.ai_settings.fleet_direction)) 
     return True 
    elif self.rect.left <= 0: 
     print("Left <= left") 
     return True 


def update(self): 
    """Move the alien right or left.""" 
    self.x += (self.ai_settings.alien_speed_factor * 
     self.ai_settings.fleet_direction) 
    self.rect.x = self.x 

私はpygameとスプライトを初めて使いましたが、なぜranditにそのような影響があるのか​​分かりません。私は、重要な変更がコンソールからデバッグするためにprintステートメントを作成しようとしているときにコードに配置しました(しかし、それが論理的な問題であれば私は気にしません)。それに光を当てることができる誰でも、私はそんなに感謝します。すでに学習とプログラミングの2日間を失った。 Eclipse Neonのpython 3.4をwin 10に走らせてくれてありがとう。

答えて

1

func change_fleet_direction()内でインデントが間違っています。ブロック:forループに入れることはできません。

関連する問題