通过pygame实现的python飞机大战项目
程序员文章站
2022-05-28 10:23:48
...
飞机大战
游戏主要特点
- 游戏自带时间计数和成绩计数。
- 游戏的子弹有7种,通过拾取道具可以升级子弹,子弹拥有持续时间,超过持续时间会降级。
- 游戏道具有6种,分别为“伪三连散射”,“EXP X2”,“毫无特效的保护盾”,“升级为好看子弹1号”,“升级为好看子弹2号”,“普通子弹升级”。
- 游戏我方飞机为4种,为“粉”,“红”,“黄”,“蓝”四种飞机,没有区别,顶多碰撞箱大小不一样,开局随机,吃到“子弹升级”飞机同时升级(碰撞箱变大)。
- 游戏有四种背景,开局随机。
- 游戏子弹击中敌机有1分爆炸特效,敌机爆炸也有1毛特效。
- 游戏敌机分大中小三种,它们的血量不同,分数不同,小敌机8种,中敌机5种,大敌机2种。
- 游戏飞机只能y轴移动,不会开火,非常沙雕。
- 游戏敌机血量在一定范围内随机。
- 我方飞机为鼠标控制,开火鼠标左击。开火有间隔。
一个佛系介绍
素材使用网络素材,腾讯全民飞机大战同款素材,只用于学习(shui文章)
老师要求的python练习题目为飞机大战,使用pygame完成。
由于面向对象掌握不太行,代码可读性。。。能跑就行。
pygame函数众多,学习时间较短,pygame的教程为英文,对于英语渣十分不友好,于是很多的操作使用基础函数魔改而成,没有运用自带的函数。
下面为游戏截图:
游戏没有开始界面,解释编译即玩。
游戏退出极其简单,撞死就行,或右上角X。
游戏玩法
- 运行代码
- 移动鼠标,控制飞机
- 鼠标左击,发射子弹
- 捡道具升级飞机
- 等待狗带
介绍完毕,放代码。。。
一段没有素材等于废话的全代码
import pygame
import sys
import random
import json
import time
from pygame.locals import *
pygame.init()
#导入我方飞机模型
with open("data/plane.json","r") as f:
plane_data1=json.loads(f.read())
plane_model = pygame.image.load("data/Skin.png")
planeRandom = random.randint(1,4)
plane=plane_data1["plane{}".format(planeRandom)]
plane1_1=plane["level1"]
plane1=plane_model.subsurface(Rect(plane1_1))#对应飞机模型切割导入
#导入敌方飞机模型
with open("data/enemy_model.json","r") as f:
enemy_data1=json.loads(f.read())
enemy_model = pygame.image.load("data/enemyplane.png")
#导入子弹模型
with open("data/bullet.json","r") as f:
bullet_data1=json.loads(f.read())
bullet_model = pygame.image.load("data/bullet.png")
bullet_yellow = bullet_data1["yellow"]
bullet_blue = bullet_data1["blue"]
bullet1 = bullet_model.subsurface(bullet_yellow["1"])
#导入奖励箱模型
with open("data/luckbox.json","r") as f:
luckbox_data1=json.loads(f.read())
luckbox_model = pygame.image.load("data/luckbox.png")
#导入数字模型
with open("data/numY.json","r") as f:
num_data=json.loads(f.read())
num_model=pygame.image.load("data/num_Y.png")
#导入爆炸画面
with open("data/break.json","r") as f:
break_data=json.loads(f.read())
break_model=pygame.image.load("data/Break.png")
break_1 = break_data["cratch"]
break_2 = break_data["break"]
#显示时间
def digital_time(screen):#63,85#125,261
playtime = int(time.time()-start)
if playtime//60<10:
showmin = "0"+str(playtime//60)
else:
showmin = str(playtime // 60)
if playtime%60<10:
showsec = "0"+str(playtime%60)
else:
showsec = str(playtime%60)
j=0
for i in showmin:
num=num_model.subsurface(Rect(num_data[i]))
num=pygame.transform.smoothscale(num,(30,40))
screen.blit(num,(30*j,0))
j=1
j=0
for i in showsec:
num=num_model.subsurface(Rect(num_data[i]))
num=pygame.transform.smoothscale(num,(30,40))
screen.blit(num,(65+30*j,0))
j=1
#显示积分
def digital_num(screen):
global score
showscore=str(score)
j=0
for i in showscore[::-1]:
num = num_model.subsurface(Rect(num_data[i]))
num = pygame.transform.smoothscale(num, (30, 40))
screen.blit(num, (482 - 30 * j, 0))
j+=1
#制造小飞机
def plan_s():
modelNum=random.randint(1,8)
enemy_rectS = enemy_data1["enemyS"]
enemyrect = enemy_rectS["enemy{}".format(modelNum)]
whatX = random.randint(-50, 300 - enemyrect[2])
position = random.randint(enemyrect[2], enemyrect[2]+30)
planeNum=random.randint(3,6)
planeHealth=random.randint(2,4)
for i in range(planeNum):
if whatX+position*i+ enemyrect[2]>550:
break
p1=[1,modelNum,[whatX+position*i,-enemyrect[3]]]
c1=[p1,enemyrect[2],enemyrect[3],planeHealth]
enemyPlane.append(p1)
collisionBox.append(c1)
#制造中飞机
def plan_m():
modelNum=random.randint(1,5)
enemy_rectM = enemy_data1["enemyM"]
enemyrect = enemy_rectM["enemy{}".format(modelNum)]
whatX = random.randint(-60, 230 - enemyrect[2])
position = random.randint(enemyrect[2], enemyrect[2] + 30)
planeNum = random.randint(2, 4)
planeHealth = random.randint(7, 9)
for i in range(planeNum):
if whatX+position*i+ enemyrect[2] > 570:
break
p1 = [2, modelNum, [whatX + position * i, -enemyrect[3]]]
c1 = [p1, enemyrect[2], enemyrect[3], planeHealth]
enemyPlane.append(p1)
collisionBox.append(c1)
#制造Boss飞机
def plan_l():
modelNum=random.randint(1,2)
enemy_rectL = enemy_data1["enemyL"]
enemyrect = enemy_rectL["enemy{}".format(modelNum)]
whatX = random.randint(0, 512 - enemyrect[2])
planeHealth = random.randint(14, 18)
p1 = [3, modelNum, [whatX, -enemyrect[3]]]
c1 = [p1, enemyrect[2], enemyrect[3], planeHealth]
enemyPlane.append(p1)
collisionBox.append(c1)
#绘制敌人
def blict_enemy(screen):
for enemy in enemyPlane:
if enemy == None:
return
if enemy[0] == 1:
if enemy[2][1]>600:
try:
collisionBox.remove(collisionBox[enemyPlane.index(enemy)])
except:
pass
enemyPlane.remove(enemy)
continue
enemy_rectS = enemy_data1["enemyS"]
enemyrect = enemy_rectS["enemy{}".format(enemy[1])]
enemyNow=enemy_model.subsurface(Rect(enemyrect))
enemy[2][1]+=3
screen.blit(enemyNow,enemy[2])
continue
if enemy[0] == 2:
if enemy[2][1]>600:
try:
collisionBox.remove(collisionBox[enemyPlane.index(enemy)])
except:
pass
enemyPlane.remove(enemy)
continue
enemy_rectM = enemy_data1["enemyM"]
enemyrect = enemy_rectM["enemy{}".format(enemy[1])]
enemyNow=enemy_model.subsurface(Rect(enemyrect))
enemy[2][1]+=2
screen.blit(enemyNow,enemy[2])
continue
if enemy[0] == 3:
if enemy[2][1]>600:
try:
collisionBox.remove(collisionBox[enemyPlane.index(enemy)])
except:
pass
enemyPlane.remove(enemy)
continue
enemy_rectL = enemy_data1["enemyL"]
enemyrect = enemy_rectL["enemy{}".format(enemy[1])]
enemyNow=enemy_model.subsurface(Rect(enemyrect))
enemy[2][1]+=1
screen.blit(enemyNow,enemy[2])
continue
#爆炸动画
def blit_break(screen):
for br in breakPos:
if br[0]==1:
rect = break_1["{}".format(br[1])]
img = break_model.subsurface(rect)
rect = img.get_rect()
rect.center = br[2]
screen.blit(img,rect)
br[3]-=1
if br[3]==0:
br[3]=2
br[1]+=1
if br[1]==10:
breakPos.remove(br)
if br[0]==2:
rect = break_2["{}".format(br[1])]
img = break_model.subsurface(rect)
rect = img.get_rect()
rect.center = br[2]
screen.blit(img, rect)
br[3] -= 1
if br[3] == 0:
br[3] = 5
br[1] += 1
if br[1] == 7:
breakPos.remove(br)
#检查子弹碰撞
def checkTouch(bulletHeart):
global bulletsize
for bullet in bulletPos:
if bullet == None:
return
for check in collisionBox:
if check == None:
return
if bullet[0]+bulletsize//2<check[0][2][0] or bullet[0]-bulletsize//2>check[0][2][0]+check[1]:
continue
if bullet[1]>check[0][2][1]+check[2] or bullet[1]<check[0][2][1]:
continue
bulletPos.remove(bullet)
br=[1,1,bullet,2]
breakPos.append(br)
check[3]-=bulletHeart
if check[3]<=0 :
enemyPlane.remove(enemyPlane[collisionBox.index(check)])
collisionBox.remove(check)
br = [2, 1, [check[0][2][0]+check[1]//2,check[0][2][1]+check[2]//2], 5]
breakPos.append(br)
global score,exp_value
if check[0][0]==1:
score+=1*exp_value
elif check[0][0]==2:
score+=5*exp_value
elif check[0][0]==3:
score+=20*exp_value
if check[0][2][1]>600:
collisionBox.remove(check)
break
#飞机碰撞
def cratchDetect(nowsPos):
global protect_value
for check in collisionBox:
if nowsPos[0]<check[0][2][0] or nowsPos[0]>check[0][2][0]+check[1]:
continue
if nowsPos[1]<check[0][2][1]+20 or nowsPos[1]>check[0][2][1]+check[2]:
continue
enemyPlane.remove(enemyPlane[collisionBox.index(check)])
collisionBox.remove(check)
if protect_value ==0:
sys.exit()
else:
protect_value =0
for box in goodluckBox:
rect=[]
if box[0]==1:
rect = luckbox_data1["speed"]
elif box[0]==2:
rect = luckbox_data1["three"]
elif box[0]==3:
rect = luckbox_data1["exp"]
elif box[0]==4:
rect = luckbox_data1["blue1"]
elif box[0]==5:
rect = luckbox_data1["blue2"]
elif box[0]==6:
rect = luckbox_data1["protect"]
if nowsPos[0]<box[1][0] or nowsPos[0]>box[1][0]+rect[2]:
continue
if nowsPos[1]<box[1][1] or nowsPos[1]>box[1][1]+rect[3]:
continue
if box[0]==1:
global speedState,levelState
speedState=900
if levelState[0]<4:
levelState[0]+=1
levelState[1]=1
if box[0]==2:
global threeState,three_value
threeState=400
three_value=1
if box[0]==3:
global expState,exp_value
expState=400
exp_value=2
if box[0]==4:
global blue1State,blue1_value
blue1State=150
blue1_value[0] = 1
blue1_value[1] = 1
if box[0]==5:
global blue2State,blue2_value
blue2State=150
blue2_value[0] = 1
blue2_value[1] = 1
if box[0]==6:
protect_value=1
goodluckBox.remove(box)
#增加幸运箱
def add_luckbox():
ran = random.random()
if ran<0.003:
nowX = random.randint(0,434)
ranX = random.randint(1,4)
ranY = random.randint(-3,3)
g1=[1,[nowX,-49],ranX,ranY]
goodluckBox.append(g1)
elif ran<0.004:
nowX = random.randint(0, 434)
ranX = random.randint(1, 4)
ranY = random.randint(-3, 3)
g2 = [2, [nowX, -49], ranX,ranY]
goodluckBox.append(g2)
elif ran < 0.005:
nowX = random.randint(0, 434)
ranX = random.randint(1, 4)
ranY = random.randint(-3, 3)
g3 = [3, [nowX, -49], ranX,ranY]
goodluckBox.append(g3)
elif ran < 0.006:
nowX = random.randint(0, 444)
ranX = random.randint(1, 4)
ranY = random.randint(-3, 3)
g4 = [4, [nowX, -76], ranX,ranY]
goodluckBox.append(g4)
elif ran < 0.007:
nowX = random.randint(0, 390)
ranX = random.randint(1, 4)
ranY = random.randint(-3, 3)
g5 = [5, [nowX, -97], ranX,ranY]
goodluckBox.append(g5)
elif ran < 0.008:
nowX = random.randint(0, 434)
ranX = random.randint(1, 4)
ranY = random.randint(-3, 3)
g6 = [6, [nowX, -78], ranX,ranY]
goodluckBox.append(g6)
#绘制幸运箱
def blit_luckbox(screen):
for box in goodluckBox:
if box[0]==1:
boxmodel=luckbox_model.subsurface(luckbox_data1["speed"])
screen.blit(boxmodel,box[1])
box[1][0]+=box[2]
box[1][1]+=box[3]
if box[1][0]<0 or box[1][0]>434:
box[2]=-box[2]
if box[1][1]<-49 or box[1][1]>551:
box[3]=-box[3]
elif box[0]==2:
boxmodel=luckbox_model.subsurface(luckbox_data1["three"])
screen.blit(boxmodel,box[1])
box[1][0]+=box[2]
box[1][1]+=box[3]
if box[1][0]<0 or box[1][0]>434:
box[2]=-box[2]
if box[1][1]<-49 or box[1][1]>551:
box[3]=-box[3]
elif box[0]==3:
boxmodel=luckbox_model.subsurface(luckbox_data1["exp"])
screen.blit(boxmodel,box[1])
box[1][0]+=box[2]
box[1][1]+=box[3]
if box[1][0]<0 or box[1][0]>434:
box[2]=-box[2]
if box[1][1]<-49 or box[1][1]>551:
box[3]=-box[3]
elif box[0]==4:
boxmodel=luckbox_model.subsurface(luckbox_data1["blue1"])
screen.blit(boxmodel,box[1])
box[1][0]+=box[2]
box[1][1]+=box[3]
if box[1][0]<0 or box[1][0]>444:
box[2]=-box[2]
if box[1][1]<-76 or box[1][1]>524:
box[3]=-box[3]
elif box[0]==5:
boxmodel=luckbox_model.subsurface(luckbox_data1["blue2"])
screen.blit(boxmodel,box[1])
box[1][0]+=box[2]
box[1][1]+=box[3]
if box[1][0]<0 or box[1][0]>390:
box[2]=-box[2]
if box[1][1]<-97 or box[1][1]>503:
box[3]=-box[3]
elif box[0]==6:
boxmodel=luckbox_model.subsurface(luckbox_data1["protect"])
screen.blit(boxmodel,box[1])
box[1][0]+=box[2]
box[1][1]+=box[3]
if box[1][0]<0 or box[1][0]>434:
box[2]=-box[2]
if box[1][1]<-78 or box[1][1]>552:
box[3]=-box[3]
#幸运箱效果
def box_effect():
global speedState,threeState,expState,blue1State,blue2State,protectState,levelState,blue1_value,blue2_value
global plane1,bullet1,bullet_speed,open_fire_speed,bullet_heart,bulletsize
if speedState>0:
speedState-=1
elif speedState==0 and levelState[0]>1:
levelState[0] -= 1
levelState[1] = 1
speedState =900
if threeState>0:
threeState-=1
elif threeState==0:
global three_value
three_value = 0
threeState=-1
if expState>0:
expState-=1
elif expState==0:
global exp_value
exp_value=1
expState=-1
if blue1State>0:
blue1State-=1
elif blue1State==0:
blue1_value[0]=0
blue1_value[1]=1
blue1State=-1
if blue2State>0:
blue2State-=1
elif blue2State == 0:
blue2_value[0]=0
blue2_value[1]=1
blue2State=-1
if levelState[1]==1:
plane1 = plane_model.subsurface(plane["level{}".format(levelState[0])])
if blue1_value[0]==0 and blue2_value[0]==0:
bullet1 = bullet_model.subsurface(bullet_yellow["{}".format(levelState[0])])
bullet_heart = 1 + 0.3 * (levelState[0] - 1)
else:
bullet_heart = 1.7 + 0.3 * (levelState[0] - 1)
bullet_speed = 4 * levelState[0]
open_fire_speed=50-10*levelState[0]
levelState[1]=0
if blue1_value[1]==1:
if blue1_value[0]==1:
bullet1 = bullet_model.subsurface(bullet_blue["1"])
bullet_heart = 2 + 0.3 * (levelState[0] - 1)
bulletsize = bullet_blue["1"][2]
blue1_value[1]=0
else:
bullet1 = bullet_model.subsurface(bullet_yellow["{}".format(levelState[0])])
bullet_heart = 1 + 0.3 * (levelState[0] - 1)
bulletsize = bullet_yellow["{}".format(levelState[0])][2]
blue1_value[1] = 0
if blue2_value[1]==1:
if blue2_value[0] == 1:
bullet1 = bullet_model.subsurface(bullet_blue["2"])
bullet_heart = 2 + 0.3 * (levelState[0] - 1)
bulletsize = bullet_blue["2"][2]
blue2_value[1] = 0
else:
bullet1 = bullet_model.subsurface(bullet_yellow["{}".format(levelState[0])])
bullet_heart = 1 + 0.3 * (levelState[0] - 1)
bulletsize = bullet_yellow["{}".format(levelState[0])][2]
blue2_value[1] = 0
#主背景加载
size = width,height = 512,600
backLuck = random.randint(1,4)
background = pygame.image.load("data/background{}.jpg".format(backLuck))
screen = pygame.display.set_mode(size)
pygame.display.set_caption("努力施工dog")
clock = pygame.time.Clock()
#参数初始化
bulletPos=[]
enemyPlane=[]
collisionBox=[]
breakPos=[]
goodluckBox=[]
bullet_speed=4
bullet_heart=1
open_fire=0
open_fire_speed=40
bgn=0
bgnn=0
Count_fire=open_fire_speed
Count_240=180
Count_boss=1200
bulletsize=0
score=0
#状态
levelState=[1,0]
threeState=0
three_value=0
expState=-1
exp_value=1
blue1State=-1
blue1_value=[0,0]
blue2State=-1
blue2_value=[0,0]
speedState=0
protect_value=0
#启动游戏
start = time.time()
while True:
#game刷新率限制60hz
clock.tick(60)
# 遍历所有的事件
for event in pygame.event.get():
# 如果单击关闭窗口,则退出
if event.type == pygame.QUIT:
sys.exit()
# 添加子弹
if event.type == pygame.MOUSEBUTTONDOWN:
open_fire = 1
if event.type == pygame.MOUSEBUTTONUP:
open_fire = 0
#刷新敌机
if Count_fire>0:
Count_fire-=1
if Count_240>0:
Count_240-=1
if Count_boss>0:
Count_boss-=1
if Count_240%120==0:
plan_s()
if Count_240==0:
plan_m()
Count_240=239
if Count_boss==0:
plan_l()
Count_boss=1200
if open_fire == 1 and Count_fire==0:
if three_value==0:
bulletPos.append(list(pygame.mouse.get_pos()))
Count_fire=open_fire_speed
else:
three_pos=list(pygame.mouse.get_pos())
bulletPos.append([three_pos[0],three_pos[1]-8])
bulletPos.append([three_pos[0]-35,three_pos[1]])
bulletPos.append([three_pos[0]+35,three_pos[1]])
Count_fire=open_fire_speed
add_luckbox()
box_effect()
# 背景循环移动效果
if bgn !=168:
backgroundNOW = background.subsurface(Rect((0, 168 - bgn), (512, 600)))
screen.blit(backgroundNOW, (0, 0))
bgn+=1
else:
backgroundOLD = background.subsurface(Rect((0, 0), (512, 600 - bgnn)))
backgroundNEW = background.subsurface(Rect((0, 768-bgnn), (512, bgnn)))
screen.blit(backgroundOLD, (0, bgnn))
screen.blit(backgroundNEW, (0,0))
bgnn+=1
if bgnn == 600:
bgnn=0
bgn=0
checkTouch(bullet_heart)
# 主机的子弹发射
for bullet_one in bulletPos:
if bullet_one == None:
break
bullet1R = bullet1.get_rect()
bulletsize=bullet1R[2]
if bullet_one[1] > -bullet1R[3]:
bullet1R.center = bullet_one
bullet_one[1] -=bullet_speed
screen.blit(bullet1, bullet1R)
else:
bulletPos.remove(bullet_one)
blict_enemy(screen)
blit_luckbox(screen)
# 主机追随鼠标移动
mouse_pos = pygame.mouse.get_pos()
cratchDetect(mouse_pos)
mou_plane = plane1.get_rect()
mou_plane.center = mouse_pos
screen.blit(plane1, mou_plane)
#爆炸动画
blit_break(screen)
# 更新界面
digital_time(screen)
digital_num(screen)
pygame.display.flip()