37,742
社区成员
发帖
与我相关
我的任务
分享
#创建一个关于外星人的模块
import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
'''表示单个外星人的类'''
def __init__(self,ai_settings,screen):
#继承精灵类
super().__init__()
self.ai_settings = ai_settings
self.screen = screen
#返回外星人图像并矩形化
self.image = pygame.image.load('image/humor.png')
self.rect = self.image.get_rect()
#每个外星人最初都在屏幕左上角附近
self.rect.x = self.rect.width
self.rect.y = self.rect.height
#储存外星人的准确位置
self.x = float(self.rect.x)
self.y = float(self.rect.y)
def blitme(self):
'''在指定位置绘制外星人'''
self.screen.blit(self.image,self.rect)
def update(self):
#外星人坐标为速度乘以方向值,当方向值为负时方向改变
self.x += (self.ai_settings.alien_speed_factor *
self.ai_settings.fleet_direction)
self.rect.x = self.x
'''当方向值为1时,x 坐标增加,向右移动。方向值为-1时,x 坐标减少,向左移动'''
def check_edges(self):
#检查外星人是否碰到了边缘
#矩形化屏幕
screen_rect = self.screen.get_rect()
#当外星人贴图右边缘大于或等于屏幕矩形右边缘,返回正确
if self.rect.right >= screen_rect.right:
return True
#当外星人贴图左边缘小于或等于屏幕矩形左边缘(小于等于0),返回正确
elif self.rect.left <= screen_rect.left:
return True
from pygame.sprite import Sprite
class Bullet(Sprite):
'''一个对飞船发射的子弹进行管理的类'''
def __init__(self,ai_settings,screen,ship):
#通过函数super()来继承sprite
super().__init__()
self.screen = screen
#在(0,0)处创建一个代表子弹的矩形,再设置正确的位置,参数为初识坐标,子弹的宽和高
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
#储存用小数表示的子弹位置
'''由于子弹是直线向下移动,所以我们只考虑在y轴上坐标的变化,
而x轴的坐标是固定的,这由发射子弹时飞船的x轴坐标决定,
因为我们在前面定义了self.rect.centerx = ship.rect.centerx'''
self.y = float(self.rect.y)
#储存子弹颜色
self.color = ai_settings.bullet_bg_color
#储存速度
self.speed_factor = ai_settings.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)
import pygame
class Ship:
def __init__(self,ai_settings,screen):
'''初始化飞船并设置其初始位置'''
self.screen = screen
self.ai_settings = ai_settings
#加载飞船图像,并获取其外接矩形
#load返回贴图所在文件
self.image = pygame.image.load('image/timg.PNG')
#矩形属性rect为贴图的矩形对象
#get_rect()是一个处理矩形图像的方法,返回值包含矩形的居中属性( center centerx centery )
#get_rect须加上(),否则后续程序在运行时会出现无法引用centerx和bottom的错误
self.rect = self.image.get_rect()
#先将表示屏幕的矩形储存在属性screen—rect中
self.screen_rect = screen.get_rect()
'''将每艘新飞船放在屏幕底部中央'''
#再将self.rect.centerx设置为表示屏幕的矩形属性centerx
#再将self.rect.bottom设置为表示屏幕的矩形属性bottom
#后面使用这个rect属性来放置飞船在屏幕底部中间
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
#在飞船属性center中储存小数点
self.center = float(self.rect.centerx)
#添加属性,设置一个飞船向右移动的标志
self.moving_right = False
#添加一个飞船向左移动的标志
self.moving_left = False
def blitme(self):
#方法blit 位块传输 将指定的像素内容传输到指定位置
self.screen.blit(self.image,self.rect)
def update(self):
#根据标志来向右移动飞船
#更新飞船的center值而不是rect(rect已被浮点化储存到center中)
'''添加条件,防止飞船移动到屏幕外'''
#以屏幕矩形的右边界为界,当按键事件(标志正确)以及飞船外接矩形坐标小于右边界时可向右移动
if self.moving_right and self.rect.right < self.screen_rect.right:
self.center += self.ai_settings.ship_speed_factor
#根据标志向左移动飞船
#以屏幕矩形的左边界为准,即x轴坐标的0,当按键事件(标志正确)以及飞船外接矩形坐标大于0时可向左移动
if self.moving_left and self.rect.left > 0:
self.center -= self.ai_settings.ship_speed_factor
'''此处使用两个if来应对左右方向按键,两个条件同时检测,当同时按下左右键时,飞船纹丝不动,
这有利于精准控制,如使用if—elif格式的话,if优先,故右键优先,同时按两个键时无法同时抵消,则向右移动'''
#根据center来更新rect
self.rect.centerx = self.center
def center_ship(self):
#让飞船底部居中
self.center = self.screen_rect.centerx#创建一个游戏设置的类
class Settings:
def __init__(self):
#储存游戏初始化数据
#初始化游戏的静态设置
self.screen_width = 1400
self.screen_height = 750
self.bg_color = (200,200,200)
#设置飞船数量
self.ship_limit = 3
#创建关于子弹的属性
self.bullet_width = 500
self.bullet_height = 15
self.bullet_bg_color = (60,0,0)
#设置限制子弹数量
self.bullets_allowed = 3
#设置外星人下降值
self.alien_drop_factor = 2
#设置速度提升倍数
self.speedup_scale = 1.1
#初始化速度值
self.initialize_dynamic_settings()
def initialize_dynamic_settings(self):
#初始化动态设置
# 设置外星人移动速度
self.alien_speed_factor = 0.5
# 设置外星人群移动值,向右为1,向左为-1
self.fleet_direction = 1
#设置子弹移动速度
self.bullet_speed_factor = 5
# 设置飞船移动速度
self.ship_speed_factor = 3
def increase_speed(self):
#提升速度值
self.ship_speed_factor *= self.speedup_scale
self.bullet_speed_factor *= self.speedup_scale
self.alien_speed_factor*= self.speedup_scale
#创建一个游戏设置的类
class Settings:
def __init__(self):
#储存游戏初始化数据
#初始化游戏的静态设置
self.screen_width = 1400
self.screen_height = 750
self.bg_color = (200,200,200)
#设置飞船数量
self.ship_limit = 3
#创建关于子弹的属性
self.bullet_width = 500
self.bullet_height = 15
self.bullet_bg_color = (60,0,0)
#设置限制子弹数量
self.bullets_allowed = 3
#设置外星人下降值
self.alien_drop_factor = 2
#设置速度提升倍数
self.speedup_scale = 1.1
#初始化速度值
self.initialize_dynamic_settings()
def initialize_dynamic_settings(self):
#初始化动态设置
# 设置外星人移动速度
self.alien_speed_factor = 0.5
# 设置外星人群移动值,向右为1,向左为-1
self.fleet_direction = 1
#设置子弹移动速度
self.bullet_speed_factor = 5
# 设置飞船移动速度
self.ship_speed_factor = 3
def increase_speed(self):
#提升速度值
self.ship_speed_factor *= self.speedup_scale
self.bullet_speed_factor *= self.speedup_scale
self.alien_speed_factor*= self.speedup_scale
#模块sys可用于退出游戏,因为模块game_functions中已经导入sys,主程序中不需要再导入
import pygame
from settings import Settings
from ship import Ship
#导入信息统计类
from game_stats import GameStats
#导入编组
from pygame.sprite import Group
#由于不在主程序创建外星人实例,此处不必导入
#导入game_functions,后面的事件管理部分从模块导入
import game_functions as gf
#导入按钮类
from button import Button
def run_game():
#初始化游戏并创建一个屏幕
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
#设置游戏屏幕为设置类中的数据
#设置屏幕对象
pygame.display.set_caption("alien_invision")
#创建按钮类 形参msg对应的实参为“play”
play_button = Button(ai_settings,screen,"Play")
#创建一个用于储存游戏信息统计的实例
stats = GameStats(ai_settings)
#创建一艘飞船
ship = Ship(ai_settings,screen)
#创建一个子弹编组
bullets = Group()
#创建一个外星人编组
aliens = Group()
# 使用gf模块中的函数绘制外星人群
gf.create_fleet(ai_settings,screen,ship,aliens)
#开始游戏主循环
while True:
#使用模块game_funcations中的方法
#check_events检测按键和鼠标点击事件
gf.check_events(ai_settings,ship,screen,bullets,stats,play_button,aliens)
#当标志正确时运行游戏:
if stats.game_active :
#方法update()用于确定事件标志以及移动距离和方向
ship.update()
#使用更新后的gf的函数用于更新和删除子弹
#检测外星人与子弹的碰撞,删除外星人与子弹 并创建外星人群
gf.update_bullets(bullets,aliens,ai_settings,screen,ship)
#由于外星人会被子弹击中,所以在绘制子弹之后绘制外星人
#增加实参 stats,bullets,screen
gf.update_aliens(ai_settings,ship,aliens,stats,bullets,screen)
#方法update_screen用于更新绘制屏幕各元素
gf.update_screen(ai_settings,ship,screen,aliens,bullets,stats,play_button)
#运行游戏
run_game()



[/quote]
一样要移除,要不就会穿过屏幕一直到消失[/quote]
穿过屏幕之后移除子弹的代码有的。
不过书上面是这样:
def update_bullets(aliens, bullets):
"""更新子弹的位置,并删除已消失的子弹""" --snip-
# 检查是否有子弹击中了外星人
# 如果是这样,就删除相应的子弹和外星人 collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
一行代码就可以实现子弹和外星人同归于尽的啊,为什么到我这里出问题了
[/quote]
一样要移除,要不就会穿过屏幕一直到消失
