这次游戏基础完善了,能算的上是一个小游戏了
但还是有两个小问题:
1.两个飞机碰撞时没有爆炸效果(其实这个爆炸效果也不重要)
2.显示game over的时候字跳的太快了
显示字的时候会被别的东西遮盖住(可以结合pyqt进行改进)
与初级飞机大战相比完成的任务:
为了实现碰撞的效果,主要的类都继承了精灵类
两飞机碰撞,自己子弹和敌机碰撞,敌机子弹和自己碰撞
敌机与敌机不能碰撞
飞机死了,相对应的子弹也消失
敌机的子弹不能打敌机,自己的子弹不知道能不能打自己(一般打不到)
写了一个爆炸的类(pumb)来控制爆炸
写了一个Manage类来启动游戏主方法
创建了多个敌机
游戏可以重新开始
之后的问题:
可以不允许飞机出界
子弹之间不能碰撞
可以给飞机,子弹添加动画,甚至物理效果
可以让飞机都继承一个类,子弹都继承一个类
(飞机分为两种,一种向上,一种向下)
不同飞机和子弹有不同性能
飞机可以有生命值,子弹可以有特别的效果
飞机发子弹的时候就像枪一样,需要换弹,有弹夹,弹夹会显示出来
重要的问题
游戏界面有开始,暂停,设置
可以对这个游戏进行非常多的设置,甚至与Ai相结合
可以与pyqt相结合,pyqt提供了很多控件,可以对游戏进行设置
在pyqt5大窗口中开一个略小的pygame窗口,pyqt窗口中可以显示生命值,飞机得分什么的
有一些重要的常量要提取出来
给敌机写一个Ai
可以选择单人游戏和双人游戏甚至多人游戏(socket联网)
双人游戏可以联网也可以同一台电脑联网
每次打敌机会有得分,每一次得分都会记录下来,最后总结成一个排行榜
此游戏的目的
学pygame的目的不在于要做一个很牛的游戏
而在于借助pygame的实践项目来深入学习面向对象(如:继承),多线程,socket等知识
`
import pygame
import sys
import time
import random
class Auto(pygame.sprite.Sprite):
#自己的飞机类
topb = pygame.sprite.Group()
#类变量
def __init__(self,screen):
pygame.sprite.Sprite.__init__(self)
self.auto = pygame.image.load("./plane1.jpg")
self.rect = self.auto.get_rect()
# self.x = 300,self.y = 300
self.rect.topleft = [300,300]
self.speed = 5
self.screen = screen
self.bu = pygame.sprite.Group()
def control(self):
#按键控制
key_pressed = pygame.key.get_pressed()
if key_pressed[pygame.K_w]:
self.rect.top -= self.speed
if key_pressed[pygame.K_s]:
self.rect.bottom += self.speed
if key_pressed[pygame.K_a]:
self.rect.left -= self.speed
if key_pressed[pygame.K_d]:
self.rect.right += self.speed
if key_pressed[pygame.K_SPACE]:
b = Bullet(self.screen,self.rect.left,self.rect.top)
self.bu.add(b)
Auto.topb.add(b)
def display(self):
self.screen.blit(self.auto,self.rect)
self.bu.update()
self.bu.draw(self.screen)
def update(self):
self.control()
self.display()
@classmethod
#清空子弹
def clear(cls):
cls.topb.empty()
`
`
class Enemy(pygame.sprite.Sprite):
#敌机类
tope = pygame.sprite.Group()
def __init__(self,screen):
pygame.sprite.Sprite.__init__(self)
self.en = pygame.image.load("./enemy.jpg")
self.rect = self.en.get_rect()
x = random.randrange(1,1000,50)
self.rect.topleft = [x,0]
#相当于self.x,self.y的位置,生成敌机的初始位置
self.speed = 6
self.screen = screen
self.bu = pygame.sprite.Group()
self.dire = True#方向
def display(self):
self.screen.blit(self.en,self.rect)
self.bu.update()
self.bu.draw(self.screen)
def auto(self):
#判断方向
if self.dire:
self.rect.right += self.speed
else:
self.rect.right -= self.speed
#控制转向
if self.rect.right > 850:
self.dire = False
elif self.rect.right < 0:
self.dire = True
self.rect.bottom += self.speed
def ai(self):
#用随机数来判断防止发太多子弹
r = random.randint(1,20)
if r == 6:
bb = Bu(self.screen,self.rect.left,self.rect.top)
self.bu.add(bb)
Enemy.tope.add(bb)
def update(self):
self.auto()
self.ai()
self.display()
@classmethod
# 清空子弹
def clear(cls):
cls.tope.empty()
`
`
class Bullet(pygame.sprite.Sprite):
def init(self,screen,x,y):
pygame.sprite.Sprite.init(self)
self.image = pygame.image.load("./buee.png")
self.rect = self.image.get_rect()
self.rect.topleft = [x,y]
self.screen = screen
self.speed = 10
def update(self):
self.rect.top -= self.speed
if self.rect.top < -20:
#子弹越界则清除子弹对象
self.kill()
class Bu(pygame.sprite.Sprite):
def init(self, screen, x, y):
pygame.sprite.Sprite.init(self)
self.image = pygame.image.load("./buee.png")
self.rect = self.image.get_rect()
self.rect.topleft = [x, y]
self.screen = screen
self.speed = 10
def update(self):
self.rect.top += self.speed
if self.rect.top > 800:
self.kill()
`
`
class Pumb:
def init(self,screen,f):
self.screen = screen
if f:
#判断类型,决定爆炸
self.bo = pygame.image.load("./boom.jpg")
else:
self.bo = pygame.image.load("./boost.jpg")
self.pos = [0,0]
self.look = False
#可见/不可见
def action(self,rect):
self.pos = rect.left
self.look = False
def draw(self):
if not self.look:
return
self.screen.blit(self.bo,(self.pos[0],self.pos[1]))
self.look = False
class Sound:
def init(self):
pygame.mixer.init()
pygame.mixer.music.load("./back.mp3")
pygame.mixer.music.set_volume(0.3)
#音量大小
self._bomb = pygame.mixer.Sound("./gunfire.mp3")
def back(self):
pygame.mixer.music.play(-1)
#背景音乐,-1为循环播放
def boost(self):
pygame.mixer.Sound.play(self._bomb)
#炸弹音乐
class Manager:
create = 20
#敌机定时器
gametime = 10
isgame = False
#判断游戏结束
over = 3
#倒计时
def __init__(self):
self.screen = pygame.display.set_mode((1000,750))#初始化窗口
#self.back = self.screen.fill((250, 250, 250))
self.title = pygame.display.set_caption('飞机大战')
self.players = pygame.sprite.Group()
self.enemys = pygame.sprite.Group()
self.pb = Pumb(self.screen,True)
self.eb = Pumb(self.screen,False)
self.sound = Sound()
def overtime(self):
self.write('game over %d'%Manager.over,500,500)
Manager.over -= 1
#倒计时减去1
if Manager.over == 0:
#倒计时停止
pygame.time.set_timer(Manager.gametime,0)
Manager.over = 3
Manager.isgame = False
self.restart()
def restart(self):
Enemy.clear()
Auto.clear()
ma = Manager()
ma.main()
def player(self):
player = Auto(self.screen)
self.players.add(player)
def enemy(self):
enemy = Enemy(self.screen)
self.enemys.add(enemy)
def write(self,t,x=0,y=0):
#显示字
font = pygame.font.SysFont(['方正粗黑宋简体', 'microsoftsansserif'], 50)
text = font.render(t,True,(255,0,0),None)
r = text.get_rect()
r.topleft = (x,y)
self.screen.blit(text,r)
def main(self):
pygame.init()
self.sound.back()
#创建一个玩家
self.player()
#开启创建敌机定时器
pygame.time.set_timer(Manager.create,1000)
while True:
self.screen.fill((250, 250, 250))
self.write('hp:100')
if Manager.isgame:
self.write('game over %d'%Manager.over,100,100)
for e in pygame.event.get():
if e.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif e.type == Manager.create:
#创建一个敌机
self.enemy()
elif e.type == Manager.gametime:
self.overtime()
#判断飞机间碰撞
self.pb.draw()
self.eb.draw()
if self.players.sprites():
isover = pygame.sprite.spritecollide(self.players.sprites()[0],Enemy.tope,True)
if isover:
Manager.isgsme = True
pygame.time.set_timer(Manager.gametime,1000)
#开始游戏倒计时
self.pb.action(self.players.sprites()[0].rect)
self.players.remove(self.players.sprites()[0])
self.sound.boost()
ppp = pygame.sprite.groupcollide(self.players,self.enemys,True,True)
if ppp:
Manager.isgsme = True
pygame.time.set_timer(Manager.gametime, 1000)
items = list(ppp.items())[0]
x = items[0]
y = items[1][0]
self.pb.action(x.rect)
self.eb.action(y.rect)
self.sound.boost()
#判断子弹与敌机碰撞
isenemy = pygame.sprite.groupcollide(Auto.topb,self.enemys,True,True)
if isenemy:
items = list(isenemy.items())[0]
y = items[1][0]
self.eb.action(y.rect)
self.sound.boost()
self.players.update()
self.enemys.update()
pygame.display.update()
time.sleep(0.1)
if name == 'main':
m = Manager()
m.main()
`