#coding=utf-8
import pygame
from pygame import *
from pygame.locals import *
from random import randint
import sys
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 640
# 材质类
class Texture():
def __init__(self):
texture = pygame.image.load('resources/image/texture.png')
self.enemy3_down6 = texture.subsurface( 0, 747, 166, 261 )
self.enemy3_hit = texture.subsurface( 166, 750, 169, 258 )
self.enemy3_n1 = texture.subsurface( 335, 750, 169, 258 )
self.enemy3_n2 = texture.subsurface( 504, 750, 169, 258 )
self.enemy3_down1 = texture.subsurface( 0, 486, 165, 261 )
self.enemy3_down2 = texture.subsurface( 0, 225, 165, 261 )
self.enemy3_down5 = texture.subsurface( 673, 748, 166, 260 )
self.enemy3_down3 = texture.subsurface( 839, 748, 165, 260 )
self.enemy3_down4 = texture.subsurface( 165, 486, 165, 261 )
self.hero1 = texture.subsurface( 0, 99, 102, 126)
self.hero2 = texture.subsurface( 165, 360, 102, 126)
self.hero_blowup_n1 = texture.subsurface( 165, 234, 102, 126 )
self.hero_blowup_n2 = texture.subsurface( 330, 624, 102, 126 )
self.hero_blowup_n3 = texture.subsurface( 330, 498, 102, 126 )
self.hero_blowup_n4 = texture.subsurface( 432, 624, 102, 126 )
self.enemy2 = texture.subsurface( 0, 0, 69, 99 )
self.enemy2_hit = texture.subsurface( 432, 525, 69, 99 )
self.ufo2 = texture.subsurface( 102, 118, 60, 107 )
self.enemy2_down1 = texture.subsurface( 534, 655, 69, 95 )
self.enemy2_down2 = texture.subsurface( 603, 655, 69, 95 )
self.enemy2_down3 = texture.subsurface( 672, 653, 69, 95 )
self.enemy2_down4 = texture.subsurface( 741, 653, 69, 95 )
self.ufo1 = texture.subsurface( 267, 398, 58, 88 )
self.bomb = texture.subsurface( 810, 691, 63, 57 )
self.enemy1_down1 = texture.subsurface( 267, 347, 57, 51 )
self.enemy1_down2 = texture.subsurface( 873, 697, 57, 51 )
self.enemy1_down3 = texture.subsurface( 267, 296, 57, 51 )
self.enemy1_down4 = texture.subsurface( 930, 697, 57, 51 )
self.game_pause_nor = texture.subsurface( 267, 251, 60, 45 )
self.game_pause_pressed = texture.subsurface( 810, 646, 60, 45 )
self.enemy1 = texture.subsurface( 534, 612, 57, 43 )
self.bullet1 = texture.subsurface( 1004, 987, 9, 21 )
self.bullet2 = texture.subsurface( 69, 78, 9, 21 )
class Bullet(pygame.sprite.Sprite):
def __init__(self, image, initPos):
super().__init__()
# 加载资源
self.image = image
self.rect = self.image.get_rect()
# 设置初始位置
self.rect.x = initPos[0]
self.rect.y = initPos[1]
self.speed = 10
def update(self):
self.rect.y -= self.speed
if self.rect.bottom < 0:
self.kill()
class Enemy1(pygame.sprite.Sprite):
def __init__(self, texture):
super().__init__()
# 加载资源
self.texture = texture
self.image = texture.enemy1
self.rect = self.image.get_rect()
# 随机生成的位置
self.rect.x = randint(0, SCREEN_WIDTH - self.rect.width)
self.rect.y = randint(0, 30)
# 飞行速度
self.speed = 4
self.downIndex = 0
def finishDownAnimation(self):
self.downIndex += 1
if self.downIndex == 4:
self.image = self.texture.enemy1_down1
elif self.downIndex == 8:
self.image = self.texture.enemy1_down2
elif self.downIndex == 12:
self.image = self.texture.enemy1_down3
elif self.downIndex == 16:
self.image = self.texture.enemy1_down4
elif self.downIndex == 20:
self.kill()
return True
return False
def update(self):
self.rect.y += self.speed
# if self.life < 0:
if self.rect.top > SCREEN_HEIGHT:
self.kill()
class Enemy1Group():
def __init__(self, texture):
# 生成间隔
self.texture = texture
self.frameIndex = 0
self.createSpan = 30
self.group = pygame.sprite.Group()
def createEnemy(self):
self.frameIndex += 1
if self.frameIndex > self.createSpan:
self.group.add(Enemy1(self.texture))
self.frameIndex = 0
# 中型敌机
class Enemy2(pygame.sprite.Sprite):
def __init__(self, texture, screen):
super().__init__()
# 加载资源
self.texture = texture
self.image = texture.enemy2
self.screen = screen
self.rect = self.image.get_rect()
# 随机生成的位置
self.rect.x = randint(0, SCREEN_WIDTH - self.rect.width)
self.rect.y = randint(0, 30)
# 飞行速度
self.speed = 2
# 生命值
self.life = 100
# 防御值
self.downIndex = 0
# 血槽图层
self.bloodBox = pygame.Surface((self.rect.width, 2))
# 完成被击中动画
def finishDownAnimation(self):
self.downIndex += 1
if self.downIndex == 4:
self.image = self.texture.enemy2_down1
elif self.downIndex == 8:
self.image = self.texture.enemy2_down2
elif self.downIndex == 12:
self.image = self.texture.enemy2_down3
elif self.downIndex == 16:
self.image = self.texture.enemy2_down4
elif self.downIndex == 20:
return True
return False
# 被击中, 返回是否死亡
def behit(self, type):
if self.life > 0:
if type == 1:
self.life -= 30
elif type == 2:
self.life -= 50
elif type == 3:
self.life -= 100
# 绘制血量
def drawBlood(self):
self.bloodBox.fill((255, 255, 255, 255))
pygame.draw.rect(self.bloodBox, [237, 28, 36, 90], [0, 0, int(self.rect.width*(self.life/100)), 2])
self.screen.blit(self.bloodBox, (self.rect.x, self.rect.y))
def update(self):
self.drawBlood()
if self.life <= 0:
if self.finishDownAnimation():
self.kill()
self.rect.y += self.speed
# if self.life < 0:
if self.rect.top > SCREEN_HEIGHT:
self.kill()
class Enemy2Group():
def __init__(self, texture):
# 生成间隔
self.texture = texture
self.frameIndex = 0
self.createSpan = 200
self.group = pygame.sprite.Group()
def collide(self, bulletGroup):
for ememy in self.group:
if pygame.sprite.spritecollide(ememy, bulletGroup, True):
if ememy.behit(1):
self.kill()
def createEnemy(self, screen):
self.frameIndex += 1
if self.frameIndex > self.createSpan:
self.createSpan = randint(200, 500)
self.group.add(Enemy2(self.texture, screen))
self.frameIndex = 0
class enemy3Bullet(pygame.sprite.Sprite):
def __init__(self, image, initPos):
super().__init__()
# 加载资源
self.image = image
self.rect = self.image.get_rect()
# 设置初始位置
self.rect.x = initPos[0]
self.rect.y = initPos[1]
self.speed = 1
def update(self):
x = randint(-1, 1)
self.rect.y += self.speed
if self.rect.bottom < 0:
self.kill()
class Enemy3(pygame.sprite.Sprite):
def __init__(self, texture, screen):
super().__init__()
# 加载资源
self.texture = texture
self.image = texture.enemy3_n2
self.screen = screen
self.rect = self.image.get_rect()
# 随机生成的位置
self.rect.x = randint(0, SCREEN_WIDTH - self.rect.width)
self.rect.y = 10
# 飞行速度
self.speed = 0
# 生命值
self.life = 1000
self.downIndex = 0
# 血槽图层
self.bloodBox = pygame.Surface((self.rect.width, 2))
# 敌人子弹精灵组
self.bulletGroup = pygame.sprite.Group()
def finishDownAnimation(self):
self.downIndex += 1
if self.downIndex == 4:
self.image = self.texture.enemy3_down1
elif self.downIndex == 8:
self.image = self.texture.enemy3_down2
elif self.downIndex == 12:
self.image = self.texture.enemy3_down3
elif self.downIndex == 16:
self.image = self.texture.enemy3_down4
elif self.downIndex == 20:
self.image = self.texture.enemy3_down5
elif self.downIndex == 25:
self.image = self.texture.enemy3_down6
elif self.downIndex == 30:
return True
return False
# 被击中, 返回是否死亡
def behit(self, type):
if self.life > 0:
if type == 1:
self.life -= 30
elif type == 2:
self.life -= 50
elif type == 3:
self.life -= 100
# 绘制血量
def drawBlood(self):
self.bloodBox.fill((255, 255, 255, 255))
pygame.draw.rect(self.bloodBox, [237, 28, 36, 90], [0, 0, int(self.rect.width*(self.life/1000)), 2])
self.screen.blit(self.bloodBox, (self.rect.x, self.rect.y))
def update(self):
self.drawBlood()
if self.life <= 0:
if self.finishDownAnimation():
self.kill()
self.rect.y += self.speed
# if self.life < 0:
if self.rect.top > SCREEN_HEIGHT:
self.kill()
class Enemy3Group():
def __init__(self, texture):
# 生成间隔
self.texture = texture
self.frameIndex = 0
self.createSpan = 300
self.group = pygame.sprite.Group()
def collide(self, bulletGroup):
for ememy in self.group:
if pygame.sprite.spritecollide(ememy, bulletGroup, True):
if ememy.behit(1):
self.kill()
def createEnemy(self, screen):
self.frameIndex += 1
if self.frameIndex > self.createSpan:
self.createSpan = randint(500, 1000)
self.group.add(Enemy3(self.texture, screen))
self.frameIndex = 0
# 物资类
class Supply(pygame.sprite.Sprite):
def __init__(self, texture):
super().__init__()
# self.type = randint(0, 3)
# if self.type == 1:
self.image = texture.bomb
self.rect = self.image.get_rect()
# 随机生成位置
self.rect.x = randint(0, SCREEN_WIDTH - self.rect.width)
self.rect.y = 0
self.speed = 1
self.moveIndex = 1
self.direction = 1
def update(self):
self.moveIndex -= 1
self.rect.x += self.speed*self.direction
self.rect.y += self.speed
if self.moveIndex <= 0:
self.moveIndex = randint(0, 120)
self.direction = randint(-1, 1)
if self.rect.top > SCREEN_HEIGHT:
self.kill()
class SupplyGroup():
def __init__(self, texture):
self.texture = texture
self.frameIndex = 0
self.createSpan = 50
self.group = pygame.sprite.Group()
def createSupply(self, screen):
self.frameIndex += 1
if self.frameIndex > self.createSpan:
self.createSpan = randint(100, 500)
self.group.add(Supply(self.texture))
self.frameIndex = 0
class Player(pygame.sprite.Sprite):
def __init__(self, texture, screen):
super().__init__()
# 加载资源
self.screen = screen
self.texture = texture
self.image = texture.hero1
self.rect = self.image.get_rect()
# 设置初始位置
self.initpos = [200, 500]
self.rect.x, self.rect.y = self.initpos
# 设置飞机速度
self.shootSpan = 10
self.speed = 6
# 设置帧数
self.frameIndex = 0
self.MAX_FRAME_INDEX = 120
self.life = 100
# 由玩家控制的子弹精灵组
self.bulletGroup = pygame.sprite.Group()
self.bulletType = 1
# 血槽图层
self.bloodBox = pygame.Surface((self.rect.width, 4))
self.downIndex = 0
# 飞机飞行动画
def flightAnimation(self):
# 每 30 帧更换一次图片
if self.frameIndex % 30 == 0:
if self.image == self.texture.hero1:
self.image = self.texture.hero2
else:
self.image = self.texture.hero1
# 绘制血量
def drawBlood(self):
self.bloodBox.fill((255, 255, 255, 255))
pygame.draw.rect(self.bloodBox, [0, 128, 64, 90], [0, 0, int(self.rect.width*(self.life/100)), 4])
self.screen.blit(self.bloodBox, (self.rect.left, self.rect.bottom))
# 飞机移动方法
def moveUp(self):
self.rect.y -= self.speed
if self.rect.top < 0:
self.rect.top = 0
def moveDown(self):
self.rect.y += self.speed
if self.rect.bottom > SCREEN_HEIGHT:
self.rect.bottom = SCREEN_HEIGHT
def moveLeft(self):
self.rect.x -= self.speed
if self.rect.left < 0:
self.rect.left = 0
def moveRight(self):
self.rect.x += self.speed
if self.rect.right > SCREEN_WIDTH:
self.rect.right = SCREEN_WIDTH
# 射击函数
def shoot(self):
if self.frameIndex % self.shootSpan == 0:
if self.bulletType == 1:
self.bulletGroup.add(Bullet(self.texture.bullet1, self.rect.midtop))
elif self.bulletType == 2:
self.bulletGroup.add(Bullet(self.texture.bullet2, self.rect.midtop))
def finishDownAnimation(self):
self.downIndex += 1
if self.downIndex == 5:
self.image = self.texture.hero_blowup_n1
elif self.downIndex == 10:
self.image = self.texture.hero_blowup_n2
elif self.downIndex == 15:
self.image = self.texture.hero_blowup_n3
elif self.downIndex == 20:
self.image = self.texture.hero_blowup_n4
elif self.downIndex == 25:
return True
return False
def behit(self):
if self.life >= 0:
self.life -= 10
# 碰撞检测
def collide(self, ememyGroup):
if pygame.sprite.spritecollide(self, ememyGroup, True):
self.behit()
# 获取物资检测
def supplyCollide(self, supplyGroup):
if pygame.sprite.spritecollide(self, supplyGroup, True):
supplyType = randint(1, 3)
if supplyType == 1:
self.bulletType = 1
elif supplyType == 2:
self.bulletType = 2
elif supplyType == 3:
self.life += 100 - self.life
def update(self):
self.drawBlood()
if self.life <= 0:
if self.finishDownAnimation():
self.kill()
self.frameIndex += 1
if(self.frameIndex > self.MAX_FRAME_INDEX):
frameIndex = 0
self.flightAnimation()
self.shoot()
if __name__ == "__main__":
# 初始化窗口
pygame.init()
screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
pygame.display.set_caption('飞机大战')
colck = pygame.time.Clock()
# 加载背景图片和导入所有材质
background = pygame.image.load('resources/image/background.png')
gameover = pygame.image.load('resources/image/gameover.png')
texture = Texture()
# 创建敌人
enemy1Group = Enemy1Group(texture)
enemy2Group = Enemy2Group(texture)
enemy3Group = Enemy3Group(texture)
# 创建击毁敌人组
enemy1DownGroup = pygame.sprite.Group()
enemy2DownGroup = pygame.sprite.Group()
enemy3DownGroup = pygame.sprite.Group()
# 创建玩家
player = Player(texture, screen)
spriteGroup = pygame.sprite.Group()
spriteGroup.add(player)
# 物资类型
supplyGroup = SupplyGroup(texture)
yindex = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 检测按键按下
keys = pygame.key.get_pressed()
if(keys[pygame.K_w]):
player.moveUp()
if(keys[pygame.K_s]):
player.moveDown()
if(keys[pygame.K_a]):
player.moveLeft()
if(keys[pygame.K_d]):
player.moveRight()
# 动态背景
screen.blit(background, (0, yindex))
screen.blit(background, (0, yindex - SCREEN_HEIGHT))
yindex += 10
if(yindex >= SCREEN_HEIGHT):
yindex = 0
enemy1DownGroup.add(pygame.sprite.groupcollide(enemy1Group.group, player.bulletGroup, False, True))
for enemy1Down in enemy1DownGroup:
# 完成击毁动画再删除
if enemy1Down.finishDownAnimation() == True:
enemy1DownGroup.remove(enemy1Down)
# 碰撞检测
enemy2Group.collide(player.bulletGroup)
enemy3Group.collide(player.bulletGroup)
player.collide(enemy1Group.group)
player.collide(enemy2Group.group)
player.supplyCollide(supplyGroup.group)
# 更新玩家状态
player.bulletGroup.draw(screen)
player.bulletGroup.update()
spriteGroup.draw(screen)
spriteGroup.update()
# 更新敌人状态
enemy1Group.createEnemy()
enemy1Group.group.draw(screen)
enemy1Group.group.update()
enemy2Group.createEnemy(screen)
enemy2Group.group.draw(screen)
enemy2Group.group.update()
enemy3Group.createEnemy(screen)
enemy3Group.group.draw(screen)
enemy3Group.group.update()
# 更新物资状态
supplyGroup.createSupply(screen)
supplyGroup.group.draw(screen)
supplyGroup.group.update()
if player.life <= 0:
screen.blit(gameover, (0, 0))
# 更新屏幕
# pygame.display.update()
pygame.display.flip()
colck.tick(60)
运行效果
运行效果.PNG
碰撞爆炸.PNG
碰撞爆炸.PNG 游戏结束.PNG 运行效果.PNG 空中物资.PNG
材质资源链接 提取码:e7rh
网友评论