在这个里面建立一个wxr.py
import pygame,sys
from pygame.sprite import Group,Sprite
from decimal import Decimal
class Settings():
def __init__(self):
#屏幕加背景
self.screen_width = 800
self.screen_height = 600
self.bg_color = (230, 230, 230)
self.image = '头像.png'
self.ship_image = self.image#'头像.png'
# 后面的就是开始设置子弹了
self.bullet_speed_factor = 1
self.bullet_width = 3
self.bullet_height = 15
self.bullet_color = 60, 60, 60
# 这里是计数器的参数
self.alien_points = 50
#设置飞机参数
class Ship():
def __init__(self,screen,bullets):
# 飞船的参数只能初始化,后面whil里面就要开始不断变化了
# 下面的那个scren是因为背景需要不断填充
# 函数这样来调用类---可以直接跨越,不用再专门传入进来
# buttle1 = Buttle1()
#group = pygame.sprite.Group()
# 这里也是一样的不用专门来想办法传入进来,因为他不是具体的函数
# 现在这个加入子弹的代码是否成功就取决于下面调用飞船的位置是否成功了
self.bullets = bullets
setting = Settings()
#初始化飞船并设置器初始位置
self.screen = screen
image = pygame.image.load(setting.ship_image)
self.image = pygame.transform.scale(image, (100, 100))
#捕捉照片的坐标
self.rect = self.image.get_rect()
#这个是捕捉屏幕的位置
self.screen_rect = self.screen.get_rect()
#将每艘新飞船放在屏幕底部中央
#就是让照片的X和Y和屏幕的X,Y一样
#就只设置一次是工具屏幕参数化的,后面就在这个基础上不断的进行加减
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
self.move_right = False
self.move_left = False
self.move_up = False
self.move_down = False
self.fire =False
#self.blitme()
#return self.rect,self.screen_rect
# j就把填充好的最终结果给最后那个blitme
def blitme(self):
if self.move_right and self.rect.right < self.screen_rect.right:
self.rect.centerx += 1
elif self.move_left and self.rect.left > 0:
self.rect.centerx -= 1
elif self.move_up and self.rect.top > 0 :
self.rect.bottom -= 1
elif self.move_down and self.rect.bottom < self.screen_rect.bottom:
self.rect.bottom += 1
elif self.fire and jihuo().stats != False:
self.init_position = self.rect.centerx, self.rect.bottom
# 加入了飞船和屏幕参数
# 这里最终得到的函数是否用弹出
# 要不然下一个函数无法调用这个函数里面经过处理的函数
# 这个函数是否要返回
# 类函数不用传递
new_bullet = Buttle1(self.init_position)
self.bullets.add(new_bullet)
#def draw_ship(self):
#elif self.fire:
# ship.fire = False
# elif event.key == pygame.K_SPACE:
# ship.fire = True
# 现在这里又是捕捉飞船参数,自己就怕这里出错,因为捕捉老是出错
# 创建一颗子弹,并将其加入到编组bullets中---最关键的就是这里了,只能操作一次从此就自动化了
# 指定位置绘制飞船
# blit方法先填充照片,后面填充已经和screen保持一致的位置
#照片擦描述还是不变,rect已经进过修改
self.screen.blit(self.image, self.rect)
#只要是经过处理的大小都必须这样弹出---要不然数据就没有办法出来
#return self.rect,self.screen_rect
class Buttle1(pygame.sprite.Sprite):
# 构造函数
def __init__(self, init_position):
pygame.sprite.Sprite.__init__(self) # 父类构造函数
'''精灵图片:加载图片(1)或者绘制(2)'''
# 方法(1)
# self.image = pygame.image.load('resources/images/enemy.png')
# 方法(2)
self.image = pygame.Surface([100, 100]) # 绘制大小
self.image.fill((255, 255, 255)) # 填充颜色
self.rect = self.image.get_rect()
#这里的这个toplft是关键字
self.rect.x = init_position[0]-50
self.rect.y = init_position[1]-75
self.speed = 5
# 每个精灵组执行update,组内所有精灵都会update
def update(self):
self.rect.top = self.rect.top - self.speed
if self.rect.top > 800:
self.kill()
#创建自动化的外星人
#他所接受的是经过修改的ai_settings
class Alien(Sprite):
#传入屏幕参数就是为了后面的blitem画画,在screen上面
"""表示单个外星人的类"""
def __init__(self, screen):
"""初始化外星人并设置其起始位置"""
#自己继承自己的种类和上面的那个一样,其实就是为了Sprite的继承
#pygame.sprite.Sprite.__init__(self) # 父类构造函数
super(Alien, self).__init__()
#这个里面是为了给外星人用的
self.screen = screen
#这个是为了干什么
#self.ai_settings = ai_settings
# 加载外星人图像,并设置其rect属性
self.image = pygame.transform.scale(pygame.image.load('头像.png'), (50, 50))
# 这里就有点难看懂了
self.rect = self.image.get_rect()
# 每个外星人最初都在屏幕左上角附近---这个就有点恼火了为什么这样
#自己捕捉自己的位置---只是他没有用那个centerx
x = self.rect.width
self.rect.x = x
y = self.rect.height
self.rect.y = y
# 存储外星人的准确位置
#self.x = float(self.rect.x)
#self.rect.topleft = init_position
def update(self):
"""在指定位置绘制外星人"""
#top是关键字
self.rect.top = self.rect.top + 1
if self.rect.top > 800:
self.kill()
#self.screen.blit(self.image, self.rect)
#外星人组参数修改
#创建外星人事件
#外星人的参数给够然后再加入小组
def create_fleet(settings, screen, aliens):
"""创建外星人群"""
# 创建一个外星人,并计算一行可容纳多少个外星人
# 外星人间距为外星人宽度---这个是为了调用里面的长度和宽度
alien = Alien(screen)
#这里是刚刚获取的外星人image
#调用了外星人的宽度,自己捕捉的
alien_width = alien.rect.width
#屏幕的宽度减去两倍的外星人宽度---剩余的可以用来装外星人的空间
available_space_x = settings.screen_width - 2 * alien_width
#装外星人的数量---为了确保不是塞满的,一个空间里面要留两个外星人的宽度,所以除以2
number_aliens_x = int(available_space_x / (2 * alien_width))
# 创建第一行外星人
for alien_number in range(number_aliens_x):
# 将参数传给外星人
alien = Alien(screen)
#开始制造外星人横轴坐标
#横纵坐标修改好了之后调用外星人
alien.x = alien_width + 2 * alien_width * alien_number
alien.rect.x = alien.x
#精灵创建---创建好了之后外面开始使用
aliens.add(alien)
class Button():
def __init__(self, screen):
"""初始化按钮的属性"""
self.screen = screen
self.screen_rect = screen.get_rect()
# 设置按钮的尺寸和其他属性
self.width, self.height = 200, 50
#颜色
self.button_color = (0, 255, 0)
#字体颜色
self.text_color = (255, 255, 255)
#字体设置
self.font = pygame.font.SysFont(None, 48)
# 创建按钮的rect对象,并使其居中
#按钮创建
self.rect = pygame.Rect(0, 0, self.width, self.height)
self.rect.center = self.screen_rect.center
# 按钮的标签只需创建一次
#这个东西非常重要,它创建的是让这个函数变成全局变量
self.prep_msg()
def prep_msg(self):
"""将msg渲染为图像,并使其在按钮上居中"""
self.msg_image = self.font.render("Play", 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):
# 绘制一个用颜色填充的按钮,再绘制文本
#fill是颜色填充
self.screen.fill(self.button_color, self.rect)
#blit是绘画
self.screen.blit(self.msg_image, self.msg_image_rect)
class Scoreboard():
"""显示得分信息的类"""
def __init__(self, settings, screen, score):
"""初始化显示得分涉及的属性"""
self.screen = screen
self.screen_rect = screen.get_rect()
self.ai_settings = settings
self.score = score
# 显示得分信息时使用的字体设置
self.text_color = (30, 30, 30)
self.font = pygame.font.SysFont(None, 48)
# 准备初始得分图像---其实就是全局变量的函数
self.prep_score()
def prep_score(self):
"""将得分转换为一幅渲染的图像"""
score_str = str(self.score)
self.score_image = self.font.render(score_str, True, self.text_color,
self.ai_settings.bg_color)
# 将得分放在屏幕右上角
self.score_rect = self.score_image.get_rect()
self.score_rect.right = self.screen_rect.right - 20
self.score_rect.top = 20
def show_score(self):
"""在屏幕上显示得分"""
self.screen.blit(self.score_image, self.score_rect)
class Scoreboard_dengji():
"""显示得分信息的类"""
def __init__(self, settings, screen, score_dengji):
"""初始化显示得分涉及的属性"""
self.screen = screen
self.screen_rect = screen.get_rect()
self.ai_settings = settings
self.score = score_dengji
# 显示得分信息时使用的字体设置
self.text_color = (30, 30, 30)
self.font = pygame.font.SysFont(None, 48)
# 准备初始得分图像---其实就是全局变量的函数
self.prep_score()
def prep_score(self):
"""将得分转换为一幅渲染的图像"""
score_str = str(self.score)
self.score_image = self.font.render(score_str, True, self.text_color,
self.ai_settings.bg_color)
# 将得分放在屏幕右上角
self.score_rect = self.score_image.get_rect()
self.score_rect.right = self.screen_rect.right - 500
self.score_rect.top = 20
def show_score(self):
"""在屏幕上显示得分"""
self.screen.blit(self.score_image, self.score_rect)
class jihuo():
def __init__(self):
self.stats = True
#stats = False
def event(ship,button,jihuo):
# 等待事件发生
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_x, mouse_y = pygame.mouse.get_pos()
if button.rect.collidepoint(mouse_x, mouse_y):
jihuo.stats = False
# return stats = False
elif event.type == pygame.KEYDOWN:
# 一定要确保这里捕捉的是飞船的试试位置
# 这个明明是绝对值但是怎么调节都还是没有办法限制界面
if event.key == pygame.K_RIGHT:
# ship.screen_rect.right:
ship.move_right = True
elif event.key == pygame.K_LEFT:
ship.move_left = True
elif event.key == pygame.K_DOWN:
# ship.screen_rect.bottom:
ship.move_down = True
# 经过测试图片的捕捉没有问题但是屏幕的捕捉有问题
# 现在的问题已经确定了就是照片参数捕捉老是无法捕捉到,捕捉的屏幕值会变化
# 动作太快意味着还没有捕捉到
elif event.key == pygame.K_UP:
ship.move_up = True
elif event.key == pygame.K_SPACE:
ship.fire = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
ship.move_right = False
elif event.key == pygame.K_LEFT:
ship.move_left = False
elif event.key == pygame.K_DOWN:
ship.move_down = False
elif event.key == pygame.K_UP:
ship.move_up = False
elif event.key == pygame.K_SPACE:
ship.fire = False
# elif event.key == pygame.K_SPACE:
# ship.fire = False
# return bullets
# 因为这个东西是对于函数的修改,当他完成一次动作修改后,后面只管进行,不用把这个函数弹出来
# bullets.update() # 子弹是无限自己更新
# bullets.draw(screen)
然后自己再随便的建立一个一个文件比如main.py
#库的调用
import pygame
from random import randint
from wxr import Settings,Ship
import wxr
from pygame.sprite import Group,Sprite
from pygame.sprite import Group
#从库里面调用模块并且名字简化
settings = Settings()
# 初始化程序
pygame.init()
screen = pygame.display.set_mode((settings.screen_width,settings.screen_width ))
pygame.display.set_caption("飞机大战")
# 更新显示
pygame.display.flip()
#图片载入--设置背景
image = settings.image
background = pygame.image.load(image).convert_alpha()
background = pygame.transform.scale(background, (800, 900))
bullets = Group()
aliens = Group()
ship = Ship(screen,bullets)
#创建自动化的外星人
#他所接受的是经过修改的ai_settings
class Alien(Sprite):
#传入屏幕参数就是为了后面的blitem画画,在screen上面
"""表示单个外星人的类"""
def __init__(self, settings, screen):
"""初始化外星人并设置其起始位置"""
#自己继承自己的种类和上面的那个一样,其实就是为了Sprite的继承
#pygame.sprite.Sprite.__init__(self) # 父类构造函数
super(Alien, self).__init__()
#这个里面是为了给外星人用的
self.screen = screen
#这个是为了干什么
self.ai_settings = settings
# 加载外星人图像,并设置其rect属性
self.image = pygame.transform.scale(pygame.image.load('头像.png'), (100, 100))
# 这里就有点难看懂了
self.rect = self.image.get_rect()
# 每个外星人最初都在屏幕左上角附近---这个就有点恼火了为什么这样
x = float(self.rect.width)
self.rect.x = x
y = float(self.rect.height)
self.rect.y = y
# 存储外星人的准确位置
#self.x = float(self.rect.x)
#self.rect.topleft = init_position
def update(self):
"""在指定位置绘制外星人"""
#top是关键字
self.rect.top = self.rect.top + 1
if self.rect.top > 800:
self.kill()
#self.screen.blit(self.image, self.rect)
#外星人组参数修改
#创建外星人事件
#外星人的参数给够然后再加入小组
def create_fleet(ettings, screen, aliens):
"""创建外星人群"""
# 创建一个外星人,并计算一行可容纳多少个外星人
# 外星人间距为外星人宽度---这个是为了调用里面的长度和宽度
alien = Alien(settings, screen)
#这里是刚刚获取的外星人image
alien_width = alien.rect.width
#屏幕的宽度减去两倍的外星人宽度---剩余的可以用来装外星人的空间
available_space_x = settings.screen_width - 2 * alien_width
#装外星人的数量---为了确保不是塞满的,一个空间里面要留两个外星人的宽度,所以除以2
number_aliens_x = int(available_space_x / (2 * alien_width))
# 创建第一行外星人
for alien_number in range(number_aliens_x):
# 将参数传给外星人
alien = Alien(settings, screen)
#开始制造外星人横轴坐标
alien.x = alien_width + 2 * alien_width * alien_number
alien.rect.x = alien.x
aliens.add(alien)
#aliens = wxr.Alien()
#外星人组自己动
#用到了设置里面的屏幕长和宽
#将处理好的外星人函数留着,下面会自己调用的
#这个群组千万不能在没有消除功能的情况下放到whil循环里面,否则这就不止一个外星人组了
wxr.create_fleet(settings, screen, aliens)
#函数不能这么用要不然就会失效
#button = wxr.Button()
#button = button(screen)
button = wxr.Button(screen)
jihuo = wxr.jihuo()
#stats = True
ship.blitme()
score = 0
jifen = 50
score_dengji = 0
while True:
# 图像
screen.blit(background, (0, 0))
wxr.Scoreboard(settings, screen, score).show_score()
wxr.Scoreboard_dengji(settings, screen, score_dengji).show_score()
if jihuo.stats == True:
button.draw_button()
#事件
#函数的这样调用英文调用的那个函数是负责修改另一个函数的参数
#而不是用来处理像stats这样的结果的处理,所以不用return
#函数处理好后可以不用返回
#这样的单独的事件处理没有问题,但是如果两个事件在一起那么就会出现问题老是捕捉的位置不对
wxr.event(ship,button,jihuo)
aliens.draw(screen)
if jihuo.stats == False:
pygame.mouse.set_visible(False)
if len(aliens) == 0:
wxr.create_fleet(settings, screen, aliens)
ship.blitme()
# 外星人自动化
# 上面留了一个alines的外星人组
# 经过wxr.create_fleet(settings, screen, aliens)处理过后这里就可以调用了
aliens.update()
# 子弹自动化
# rect = ship.image.get_rect()
bullets.update() # 子弹是无限自己更新
bullets.draw(screen)
# 就把这句话这么一加就可以起到消除的作用了
collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
if collisions:
score += jifen
if score > 1000:
score = 0
score_dengji += 1
jifen -= 10
#在撞到人的情况下
if pygame.sprite.spritecollideany(ship, aliens):
jihuo.stats = True
aliens.empty()
bullets.empty()
# 光标的可见与不可见
pygame.mouse.set_visible(True)
button.draw_button()
score = 0
# 屏幕可见---官方解释是为了更新画面
pygame.display.flip()