Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
446 views
in Technique[技术] by (71.8m points)

python 外星人入侵 射击bug 当射中单数时会出现bug 但双数则不会 每次都是在检测边缘的时候出现

代码如下
alien_invasion

from settings import Settings
from ship import Ship
from alien import Alien
import game_functions as gf
from pygame.sprite import Group
#将导入的模块指定别名为gf
import pygame

def run_game():
    #初始化屏幕并创建一个屏幕对象
    pygame.init()
    setting =Settings()
    screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))
    ship=Ship(setting,screen)
    #创建一个外星人组
    aliens=Group()
    gf.create_fleet(setting,screen,ship,aliens)

    bullets=Group()
    pygame.display.set_caption("Alien Invasion")
    #开始游戏的主循环
    while True:
        #监视键盘和鼠标事件
        gf.check_events(setting,screen,ship,bullets)
        ship.update()
        gf.update_bullets(aliens,bullets)
        gf.update_aliens(setting,aliens)
        #让最近绘制的屏幕可见
        gf.update_screen(setting,screen,ship,aliens,bullets)

run_game()

alien

import pygame
from pygame.sprite import Sprite

class Alien(Sprite):
    """表示单个外星人类"""

    def __init__(self,setting,screen):
        """初始化外星人并设置其初始位置"""
        super(Alien,self).__init__()
        self.screen=screen
        self.setting=setting

        #加载外星人图像,并设置rect属性
        self.image=pygame.image.load('D:\CODE\py\pygame\alien_invasion\images\alien.bmp')
        self.rect=self.image.get_rect()

        #每个外星人最初都在屏幕的左上角附件
        self.rect.x=self.rect.width
        self.rect.y=self.rect.height
        #将外星人的左边距设置成外星人的宽度
        #将外星人的上边距设置成外星人的高度

        #存储外星人的准确位置
        self.x=float(self.rect.x)
    
    def update(self):
        """向左右移动外星人"""
        self.x+=(self.setting.alien_speed_factor*self.setting.fleet_direction)
        self.rect.x=self.x
    def check_edges(self):
        """如果外星人位于屏幕边缘,就返回ture"""
        screen_rect=self.screen.get_rect()
        if self.rect.right>=screen_rect.right:
            return True
        elif self.rect.left<=0:
            return True

bullet

import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
    """发射子弹的类"""
    def __init__(self,setting,screen,ship):
        """在飞船所处位置创建一个子弹对象"""
        super(Bullet,self).__init__()
        self.screen=screen

        #在(0,0)处创建一个子弹的矩阵,再设置正确的位置
        self.rect=pygame.Rect(0,0,setting.bullet_width,setting.bullet_height)
        #先创建一个矩形
        self.rect.centerx=ship.rect.centerx
        self.rect.top=ship.rect.top
        #移动到飞船的正上方

        #存储用小数表示的子弹位置
        self.y=float(self.rect.y)
        #y是子弹的纵向坐标 可以控制子弹的速度

        self.color=setting.bullet_color
        self.speed_factor=setting.bullet_speed_factor
    
    def update(self):
        """向上移动子弹"""
        #更新表示子弹位置的小数值
        self.y-=self.speed_factor
        #更新子弹的rect位置
        self.rect.y=self.y
    
    def draw_bullet(self):
        """在屏幕上绘制子弹"""
        pygame.draw.rect(self.screen,self.color,self.rect)

game_functions

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

def check_events(setting,screen,ship,bullets):
    """响应按键和鼠标事件"""
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit()
        elif event.type==pygame.KEYDOWN:
            check_keydown_events(event,setting,screen,ship,bullets)
        elif event.type==pygame.KEYUP:
            check_keyup_events(event,ship)

def check_keydown_events(event,setting,screen,ship,bullets):
    """响应按键"""
    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_bullets(setting,screen,ship,bullets)

def check_keyup_events(event,ship):
    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
    
def update_screen(setting,screen,ship,aliens,bullets):
    """更新屏幕上的图像,并切换到新屏幕"""
    #每次循环时都要重绘屏幕
    screen.fill(setting.bg_color)
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    aliens.draw(screen)#在屏幕中绘制编组中的每一个外星人
    #让最近绘制的屏幕可见
    pygame.display.flip()

def update_bullets(aliens,bullets):
    bullets.update()
    #将飞出屏幕的子弹删除
    for bullet in bullets.copy():
        if bullet.rect.bottom<=0:#检测
            bullets.remove(bullet)#删除
    #检查是否有子弹击中外星人
    #如果是 则删除相应的子弹和外星人
    collisions=pygame.sprite.groupcollide(bullets,aliens,True,True)

def fire_bullets(setting,screen,ship,bullets):
    if len(bullets)<setting.bullet_allowed:
        new_bullet=Bullet(setting,screen,ship)
        bullets.add(new_bullet)

def get_number_alien_x(setting,alien_width):
    available_space_x=setting.screen_width-2*alien_width
    #左右两边删去留边距
    number_alien_x=int(available_space_x/(2*alien_width))
    #间距为一个外星人的宽度
    return number_alien_x

def get_number_rows(setting,ship_height,alien_height):
    """计算屏幕可容纳多少行外星人"""
    available_space_y=(setting.screen_height-(3*alien_height)-ship_height)
    number_rows=int(available_space_y/(2*alien_height))
    return number_rows

def create_alien(setting,screen,aliens,alien_number,row_number):
    alien=Alien(setting,screen)
    #创建一个外星人
    alien_width=alien.rect.width
    alien.x=alien_width+2*alien_width*alien_number
    #计算出它应该有的x坐标并赋予
    alien.rect.x=alien.x
    alien.rect.y=alien.rect.height+2*alien.rect.height*row_number
    aliens.add(alien)

def create_fleet(setting,screen,ship,aliens):
    alien=Alien(setting,screen)
    number_alien_x=get_number_alien_x(setting,alien.rect.width)
    number_rows=get_number_rows(setting,ship.rect.height,alien.rect.height)
    for row_number in range(number_rows):
        for alien_number in range(number_alien_x):
            create_alien(setting,screen,aliens,alien_number,row_number)
            #循环创建次数为计算得出的外星人数量

def update_aliens(setting,aliens):
    """检测是否有外星人到达屏幕边界,更新外星人群中所有外星人的位置"""
    check_fleet_edge(setting,aliens)
    aliens.update()

def check_fleet_edge(setting,aliens):
    """有外星人到达边界时采取相应的措施"""
    for alien in aliens.sprites():
        if alien.check_edges():
            change_fleet_direction(setting,aliens)
            break

def change_fleet_direction(setting,aliens):
    """将整群外星人下移,并改变他们的方向"""
    for alien in aliens.sprites():
        alien.rect.y+=setting.fleet_drop_speed
        setting.fleet_direction*=-1
        



settings

class Settings():

    """存储所有设置的类"""
    def __init__(self):
        """初始化游戏的设置"""
        #屏幕设置
        self.screen_width = 1300
        self.screen_height = 600
        self.bg_color=(230,230,230)#颜色的RGB
        self.ship_speed_factor=0.5#factor=因素
        #子弹设置
        self.bullet_speed_factor=1
        self.bullet_width=3
        self.bullet_height=15
        self.bullet_color=60,60,60
        self.bullet_allowed=5
        #外星人设置
        self.alien_speed_factor=0.2
        self.fleet_drop_speed=2
        #fleet_direction为1表示向右移,为-1表示向左移
        self.fleet_direction=1

ship

import pygame

class Ship():
    def __init__(self,setting,screen):
        """初始化飞船并设置其初始位置"""
        self.screen=screen
        self.setting=setting
        #加载飞船图像并获取其外接矩形
        self.image = pygame.image.load('D:\CODE\py\pygame\alien_invasion\images\ship.bmp')
       
        self.rect=self.image.get_rect()
        #获取图片的外接矩阵
        self.screen_rect=screen.get_rect()
        #获取屏幕的外接矩阵

        #将每部新飞船放到屏幕底部中央
        self.rect.centerx=self.screen_rect.centerx
        #CENTERX =中心 让飞船的中心等于屏幕的中心
        self.rect.bottom=self.screen_rect.bottom
        #BOTTOM =底部 让飞船的底部等于屏幕的底部

        #在飞船的属性center中存储小数值
        self.center=float(self.rect.centerx)
        self.bottom=float(self.rect.bottom)

        self.moving_right=False
        self.moving_left=False
        #控制飞船的左右
        self.moving_up=False
        self.moving_down=False

    def update(self):
        """根据移动标志调整飞船的位置"""
        if self.moving_right and self.rect.right<self.screen_rect.right:
            #只有飞船的右边界小于屏幕右边界的时候并且有向右的命令才能移动
            self.center+=self.setting.ship_speed_factor
        if self.moving_left and self.rect.left>0:
            #同理 飞船左边界大于零时并且有命令时
            self.center-=self.setting.ship_speed_factor
        if self.moving_up and self.rect.top>0:
            self.bottom-=self.setting.ship_speed_factor
        if self.moving_down and self.rect.bottom<self.screen_rect.bottom:
            self.bottom+=self.setting.ship_speed_factor

        self.rect.centerx=self.center
        self.rect.bottom=self.bottom
        #根据调整的飞船的中心值来改变原来飞船的中心值 
        #只取整移动

    def blitme(self):
        """在指定位置绘制飞船"""
        self.screen.blit(self.image,self.rect)

alien.bmpship.bmp
谢谢啦 第一次用思否 有什么不对的地方 望见谅


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

我也遇到了这个问题,你的解决了么


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...