游戏初始化
游戏循环
pygame.Rect(x,y,width,height)
四个参数可以来确定一个矩形区域的大小和位置pygame.display.set_mode()
初始化窗口或屏幕import pygame
SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
screen = pygame.display.set_mode(SCREEN_RECT.size)
pygame.sprite
模块中pygame.sprite.Sprite和pygame.sprite.Groupdef __create_sprite(self):
"""创建精灵组"""
# 背景组
bg1 = Background()
bg2 = Background(True)
self.back_group = pygame.sprite.Group(bg1, bg2)
# 敌机组
self.enemy_group = pygame.sprite.Group()
# 英雄组
self.hero = Hero()
self.hero_group = pygame.sprite.Group(self.hero)
def __update_sprites(self):
"""更新精灵组"""
for group in [self.back_group, self.enemy_group, self.hero_group, self.hero.bullets]:
group.update()
group.draw(self.screen)
pygame.time.Clock()
tick
方法def __event_handler(self):
"""事件监听"""
for event in pygame.event.get():
# 判断是否退出游戏
if event.type == pygame.QUIT:
PlayGame.__game_over()
# 判断是否为创建敌机
elif event.type == CREAT_ENEMY_EVENT:
# 将敌机精灵添加到敌机精灵组
self.enemy_group.add(Enemy())
# 发射子弹
elif event.type == HERO_FIRE_EVENT:
self.hero.fire()
# 根据按键来调整飞机的位置
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_RIGHT]:
self.hero.speed = 5
elif keys_pressed[pygame.K_LEFT]:
self.hero.speed = -5
else:
self.hero.speed = 0
战机的子弹摧毁敌机
战机被敌机摧毁
利用pygame.sprite.groupcollide()
和pygame.sprite.spritecollide
前者检测子弹和敌机器冲突,并设置两者dokill属性True,从内存中释放它们
pygame.sprite.groupcollide()
Find all sprites that collide between two groups.
If either dokill argument is True, the colliding Sprites will be removed from their respective Group.
后者检测精灵是否和另一精灵组任意一精灵碰撞,如果发生碰撞,返回另一精灵组中产生碰撞的精灵;如果没有发生,不返回
pygame.sprite.spritecollideany()
Simple test if a sprite intersects anything in a group.
If the sprite collides with any single sprite in the group, a single sprite from the group is returned. On no collision None is returned.
def __check_collide(self):
"""碰撞检测"""
# 1.子弹摧毁敌机
pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)
# 2.敌机摧毁英雄
enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)
if len(enemies) > 0:
self.hero.kill()
PlayGame.__game_over()
import random
import pygame
# 屏幕大小的常量
SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
# 刷新的帧率
FRAME_PRE_SEC = 20
# 创建敌机的定时器常量
CREAT_ENEMY_EVENT = pygame.USEREVENT
# 英雄发射子弹
HERO_FIRE_EVENT = pygame.USEREVENT + 1
class GameSprite(pygame.sprite.Sprite):
"""飞机大战游戏精灵"""
def __init__(self, image_name, speed=5):
# 调用父类的初始化方法
super().__init__()
# 定义对象的属性
self.image = pygame.image.load(image_name)
self.rect = self.image.get_rect()
self.speed = speed
def update(self):
# 在屏幕的垂直方向上移动
self.rect.y += self.speed
class Background(GameSprite):
"""游戏背景精灵"""
def __init__(self, is_alt=False):
# 调用父类方法创建初始化对象
super().__init__("./plane/images/background.png")
# 判断是否为第一张图片,如果不是,则修改位置
if is_alt:
self.rect.y = -self.rect.height
def update(self):
# 1.调用父类的方法实现
super().update()
# 2.判断是否移出屏幕,如果移出屏幕,将图像设置到屏幕上方
if self.rect.y >= SCREEN_RECT.height:
self.rect.y = - self.rect.height
class Enemy(GameSprite):
def __init__(self):
# 1.调用父类方法,创建敌机精灵,同时指定敌机图片
super().__init__("./plane/images/enemy1.png")
# 2.指定敌机的初始随机速度
self.speed = random.randint(5, 8)
# 3.指定敌机的初始随机位置
self.rect.bottom = 0
max_x = SCREEN_RECT.width - self.rect.width
self.rect.x = random.randint(0, max_x)
def update(self):
super().update()
# 判断敌机是否没有被销毁而且飞出了屏幕
if self.rect.y >= SCREEN_RECT.height:
self.kill()
class Hero(GameSprite):
"""英雄精灵"""
def __init__(self):
# 1.调用父类方法,设置image、speed
super().__init__("./plane/images/me1.png", 0)
# 创建子弹组
self.bullets = pygame.sprite.Group()
# 设置初始位置
self.rect.centerx = SCREEN_RECT.centerx
self.rect.bottom = SCREEN_RECT.bottom
def update(self):
self.rect.x += self.speed
if self.rect.right > SCREEN_RECT.right:
self.rect.right = SCREEN_RECT.right
if self.rect.left < 0:
self.rect.left = 0
def fire(self):
for i in (1, 2, 3):
# 创建子弹精灵
bullet = Bullet()
# 设置精灵的位置
bullet.rect.bottom = self.rect.y - i * 20
bullet.rect.centerx = self.rect.centerx
# 将精灵添加到精灵组
self.bullets.add(bullet)
class Bullet(GameSprite):
"""子弹精灵"""
def __init__(self):
super().__init__("./plane/images/bullet1.png", -8)
def update(self):
super().update()
if self.rect.bottom < 0:
self.kill()
class PlayGame(object):
def __init__(self):
print("game loading")
# 创建游戏窗口
self.screen = pygame.display.set_mode(SCREEN_RECT.size)
# 创建游戏时钟
self.clock = pygame.time.Clock()
# 调用私有方法,精灵和精灵组创建
self.__create_sprite()
# 设置定时器事件,每一秒出现一架敌机
pygame.time.set_timer(CREAT_ENEMY_EVENT, 1000)
pygame.time.set_timer(HERO_FIRE_EVENT, 500)
def __create_sprite(self):
"""创建精灵组"""
# 背景组
bg1 = Background()
bg2 = Background(True)
self.back_group = pygame.sprite.Group(bg1, bg2)
# 敌机组
self.enemy_group = pygame.sprite.Group()
# 英雄组
self.hero = Hero()
self.hero_group = pygame.sprite.Group(self.hero)
def start_game(self):
print("game start")
while True:
# 设置时钟频率
self.clock.tick(FRAME_PRE_SEC)
# 事件监听
self.__event_handler()
# 碰撞检测
self.__check_collide()
# 更新精灵组
self.__update_sprites()
# 更新显示
pygame.display.update()
def __event_handler(self):
"""事件监听"""
for event in pygame.event.get():
# 判断是否退出游戏
if event.type == pygame.QUIT:
PlayGame.__game_over()
# 判断是否为创建敌机
elif event.type == CREAT_ENEMY_EVENT:
# 将敌机精灵添加到敌机精灵组
self.enemy_group.add(Enemy())
# 发射子弹
elif event.type == HERO_FIRE_EVENT:
self.hero.fire()
# 根据按键来调整飞机的位置
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_RIGHT]:
self.hero.speed = 5
elif keys_pressed[pygame.K_LEFT]:
self.hero.speed = -5
else:
self.hero.speed = 0
def __update_sprites(self):
"""更新精灵组"""
for group in [self.back_group, self.enemy_group, self.hero_group, self.hero.bullets]:
group.update()
group.draw(self.screen)
def __check_collide(self):
"""碰撞检测"""
# 1.子弹摧毁敌机
pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)
# 2.敌机摧毁英雄
enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)
if len(enemies) > 0:
self.hero.kill()
PlayGame.__game_over()
@staticmethod
def __game_over():
"""游戏结束"""
print("game over")
pygame.quit()
exit()
if __name__ == '__main__':
game = PlayGame()
game.start_game()