目標效果:
主要功能爲坦克各方向射擊飛機,飛機只能躲逃,左上角記錄射擊數量。
(話說小飛機好像蒼蠅啊,運行起來飛的嗡嗡的,看的想拿蒼蠅拍子)
資源:
文件夾裏需存入飛機坦克子彈等圖片。
這裏我放上一張飛機一張坦克還有子彈的吧,可以用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()