目标效果:
主要功能为坦克各方向射击飞机,飞机只能躲逃,左上角记录射击数量。
(话说小飞机好像苍蝇啊,运行起来飞的嗡嗡的,看的想拿苍蝇拍子)
资源:
文件夹里需存入飞机坦克子弹等图片。
这里我放上一张飞机一张坦克还有子弹的吧,可以用ps旋转下。
代码:
############导入库############
import pygame
import random
from pygame.sprite import Sprite #精灵类,用于检测撞击
############定义变量############
SCREEN_WIDTH=700
SCREEN_HEIGHT=500
BG_COLOR=pygame.Color(0,0,0)
TEXT_COLOR=pygame.Color(255,255,255)
############定义类############
"""基类(飞机被射击后爆炸)"""
class BaseItem(Sprite): #继承精灵类
def __init__(self):
pygame.sprite.Sprite.__init__(self) #精灵类初始化方法
"""主类"""
class MainGame():
window=None #初始化窗口对象(surface对象)
my_tank=None #初始化我方坦克
enemyPlaneList=[] #初始化敌方飞机列表
enemyPlaneCount=5 #初始化地方飞机数量
myBulletList=[] #我方子弹列表
killNum=0
def __init__(self):
pass
def startGame(self): #开始游戏
pygame.display.init() #初始化窗口
MainGame.window=pygame.display.set_mode([SCREEN_WIDTH,SCREEN_HEIGHT])
MainGame.my_tank=MyTank(350,250) #创建我方坦克
self.createEnemyPlane() #创建敌方坦克
pygame.display.set_caption('坦克大战') #设置标题
while True:
MainGame.window.fill(BG_COLOR) #填充背景色
self.getEvent() #获取事件
MainGame.window.blit(self.getTextSurface('共击落%d架飞机'%MainGame.killNum),(10,10)) #窗口上添加文字绘制,(10,10)表示距离左上角x和y座标各为10
MainGame.my_tank.displayTank() #显示我方坦克
self.blitEnemyPlane() #显示敌方飞机
self.blitMyBullet() #显示我方子弹
if not MainGame.my_tank.stop: #如果移动开关变为打开
MainGame.my_tank.move() #我方坦克循环移动
pygame.display.update() #一直显示窗口
if len(MainGame.enemyPlaneList)<1:
self.createEnemyPlane()
def blitMyBullet(self): #循环遍历我方子弹
for myBullet in MainGame.myBulletList:
if myBullet.live==True: #当前子弹状态为活着,则显示或移动
myBullet.displayBullet() # 子弹显示
myBullet.move() # 子弹移动
myBullet.myBullet_hit_enemyPlane() #调用检测碰撞方法
else:
MainGame.myBulletList.remove(myBullet) #销毁子弹
def createEnemyPlane(self): #创建敌方飞机
top=100
for i in range(MainGame.enemyPlaneCount): #生成要求数量的敌方飞机
left=random.randint(0,600) #随机生成距离左边界的数值
enemy=EnemyPlane(left,top)
MainGame.enemyPlaneList.append(enemy) #飞机列表添加飞机
def blitEnemyPlane(self): #显示敌方飞机
for enemyPlane in MainGame.enemyPlaneList:
if enemyPlane.live==True:
enemyPlane.displayPlane() #显示飞机
enemyPlane.randMove() #飞机移动
else:
MainGame.enemyPlaneList.remove(enemyPlane)
def endGame(self): #结束游戏
exit()
def getTextSurface(self,text): #左上角文字绘制
pygame.font.init() #初始化字体
font=pygame.font.SysFont('kaiti',18) #获取字体font对象
textSurface=font.render(text,True,TEXT_COLOR) #绘制文字信息,True表示抗锯齿
return textSurface
def getEvent(self): #获取事件
evenList=pygame.event.get() #获取所有时间
for event in evenList: #遍历事件
if event.type==pygame.QUIT: #如果按的是退出,关闭窗口
self.endGame()
if event.type==pygame.KEYDOWN: #如果是键盘按下
if event.key==pygame.K_LEFT: #按下左键,坦克向左移动
MainGame.my_tank.direction='L' #方向改为向左
MainGame.my_tank.stop = False # 移动开关打开
MainGame.my_tank.move() # 调用移动方向
elif event.key==pygame.K_RIGHT: #按下右键,坦克向右移动
MainGame.my_tank.direction = 'R' # 方向改为向右
MainGame.my_tank.stop = False # 移动开关打开
MainGame.my_tank.move() # 调用移动方向
elif event.key == pygame.K_UP: # 按下上键,坦克向上移动
MainGame.my_tank.direction = 'U' # 方向改为向上
MainGame.my_tank.stop = False # 移动开关打开
MainGame.my_tank.move() # 调用移动方向
elif event.key == pygame.K_DOWN: # 按下下键,坦克向下移动
MainGame.my_tank.direction = 'D' # 方向改为向下
MainGame.my_tank.stop = False # 移动开关打开
MainGame.my_tank.move() # 调用移动方向
elif event.key == pygame.K_SPACE and len(MainGame.myBulletList)<3: # 按下空格键
myBullet=Bullet(MainGame.my_tank) #我方创建子弹
MainGame.myBulletList.append(myBullet) #添加到我方子弹列表
if event.type==pygame.KEYUP: #如果松开键盘
if event.key==pygame.K_UP or event.key==pygame.K_DOWN or event.key==pygame.K_LEFT or event.key==pygame.K_RIGHT: #判断刚才释放的键是否是上下左右键
MainGame.my_tank.stop=True #坦克停止
"""我方坦克类"""
class MyTank():
def __init__(self,left,top): #初始化传入坦克到左边和上边的距离是多少
self.images={
'U':pygame.image.load('img/tankUp.png'),
'R': pygame.image.load('img/tankRight.png'),
'D': pygame.image.load('img/tankDown.png'),
'L': pygame.image.load('img/tankLeft.png')
} #保存加载的图片
self.direction='U' #默认方向向上
self.image=self.images[self.direction] #根据方向获取图片
self.rect=self.image.get_rect() #获取当前图片的矩形区域
self.rect.left=left #设置区域left
self.rect.top=top #设置区域top
self.speed=1 #移动的速度
self.stop=True #坦克移动的开关,默认关闭
def move(self): #移动
if self.direction=='L': #如果方向向左
if self.rect.left > 0: #不能超过左边界
self.rect.left-=self.speed
elif self.direction=='U':
if self.rect.top>0: #不能超过上边界
self.rect.top -= self.speed
elif self.direction=='R':
if self.rect.left+self.rect.height<SCREEN_WIDTH: #不能超过右边界
self.rect.left+=self.speed
elif self.direction=='D':
if self.rect.top+self.rect.width<SCREEN_HEIGHT: #不能超过下边界
self.rect.top+=self.speed
def displayTank(self): #展示坦克
self.image=self.images[self.direction] #获取战是的对象
MainGame.window.blit(self.image,self.rect) #调用blit方法展示
"""敌方飞机类"""
class EnemyPlane():
def __init__(self,left,top):
self.images = {
'U': pygame.image.load('img/enemyUp.png'),
'R': pygame.image.load('img/enemyRight.png'),
'D': pygame.image.load('img/enemyDown.png'),
'L': pygame.image.load('img/enemyLeft.png')
} # 保存加载的图片
self.direction=self.randDirection() #随机生成飞机方向
self.image=self.images[self.direction] #根据方向获取图片
self.rect=self.image.get_rect() #获取图片区域
self.rect.left=left #设置区域的left
self.rect.top=top #设置区域的top
self.speed=1 #移动速度
self.step=100 #步数
self.live=True
def randDirection(self):
num=random.randint(1,4) #随机生成1-4内的数,表示四个方向
if num==1:
return 'U'
elif num==2:
return 'D'
elif num==3:
return 'L'
elif num==4:
return 'R'
def randMove(self):
if self.step<=0:
self.direction=self.randDirection() #每20步随机赋值一个方向
self.step=100 #步数复位
else:
self.move() #飞机移动
self.step-=1 #步数递减
def displayPlane(self): #展示飞机
self.image=self.images[self.direction] #根据方向获取图片
MainGame.window.blit(self.image,self.rect) #调用blit方法展示
def move(self): #移动
if self.direction=='L': #如果方向向左
if self.rect.left > 0: #不能超过左边界
self.rect.left-=self.speed
elif self.direction=='U':
if self.rect.top>0: #不能超过上边界
self.rect.top -= self.speed
elif self.direction=='R':
if self.rect.left+self.rect.height<SCREEN_WIDTH: #不能超过右边界
self.rect.left+=self.speed
elif self.direction=='D':
if self.rect.top+self.rect.width<SCREEN_HEIGHT: #不能超过下边界
self.rect.top+=self.speed
"""子弹类"""
class Bullet(MyTank):
def __init__(self,tank):
self.image=pygame.image.load('img/bullet.png') #加载子弹图片
self.direction=tank.direction #子弹方向和坦克方向一致
self.speed=2
self.live=True #子弹状态,若子弹碰到墙壁,则销毁子弹
self.rect=self.image.get_rect() #获取子弹区域
if self.direction=='U': #如果坦克向上,那么子弹应该在上方
self.rect.left = tank.rect.left + self.rect.width # 子弹的left值
self.rect.top = tank.rect.top - self.rect.height # 子弹的top值
elif self.direction == 'D': # 如果坦克向下,那么子弹应该在下方
self.rect.left = tank.rect.left+20 # 子弹的left值
self.rect.top = tank.rect.top +tank.rect.height # 子弹的top值
elif self.direction == 'L': # 如果坦克向左,那么子弹应该在左方
self.rect.left = tank.rect.left-self.rect.width # 子弹的left值
self.rect.top = tank.rect.top+20 # 子弹的top值
elif self.direction == 'R': # 如果坦克向右,那么子弹应该在右方
self.rect.left = tank.rect.left + tank.rect.width-10 # 子弹的left值
self.rect.top = tank.rect.top + self.rect.width # 子弹的top值
def move(self): #移动
if self.direction=='U':
if self.rect.top>0:
self.rect.top -= self.speed
else:
self.live=False #修改子弹状态
elif self.direction=='R':
if self.rect.left+self.rect.width<SCREEN_WIDTH:
self.rect.left+=self.speed
else:
self.live = False #修改子弹状态
elif self.direction=='D':
if self.rect.top+self.rect.height<SCREEN_HEIGHT:
self.rect.top+=self.speed
else:
self.live = False #修改子弹状态
elif self.direction=='L':
if self.rect.left>0:
self.rect.left-=self.speed
else:
self.live = False #修改子弹状态
def displayBullet(self): #展示子弹
MainGame.window.blit(self.image,self.rect) #将图片surface加载到窗口
def myBullet_hit_enemyPlane(self): #我方子弹与敌方坦克碰撞
for enemyPlane in MainGame.enemyPlaneList: #循环遍历敌方坦克列表,判断是否发生碰撞
if pygame.sprite.collide_rect(enemyPlane,self): #如果发生碰撞
MainGame.killNum+=1
enemyPlane.live=False #坦克生存属性改为False
self.live=False #子弹生存属性改为False
############主程序############
if __name__=='__main__':
MainGame().startGame()