python實(shí)現(xiàn)坦克大戰(zhàn)游戲 附詳細(xì)注釋
本文實(shí)例為大家分享了python實(shí)現(xiàn)坦克大戰(zhàn)的具體代碼,供大家參考,具體內(nèi)容如下
#功能實(shí)現(xiàn)游戲主窗口
import pygame,time,random#導(dǎo)入模塊
_display = pygame.display#賦值給一個(gè)變量 調(diào)用時(shí)方便
color_red = pygame.Color(255,0,0)#同上 v
class MainGame(object):
screen_width = 900#游戲界面寬度
screen_height = 550#界面的高度
Tank_p1 = None#坦克對(duì)象
window = None #窗口對(duì)象
EnemyTank_list = []# 存儲(chǔ)所有敵方坦克
EnemTank_count = 10# 要?jiǎng)?chuàng)建的敵方坦克的數(shù)量
Bullet_list = [] #創(chuàng)建我方子彈列表
EnemyTank_bullet_list = []
Explode_list= []
wall_list = []
def startGame(self):
pygame.display.init()#初始化游戲模塊的顯示
MainGame.window = _display.set_mode([MainGame.screen_width,MainGame.screen_height])#生成并加載游戲窗口、\
#pygame.display模塊及set_mode方法和pygame相關(guān)方法調(diào)用設(shè)置
# 見(jiàn)<<https://www.pygame.org/docs/ref/display.html#pygame.display.set_mode>> UC瀏覽器實(shí)現(xiàn)自動(dòng)翻譯
pygame.display.set_caption("坦克大戰(zhàn)v1.0")#s設(shè)置游戲標(biāo)題
self.creatEnemyTank()#類(lèi)中調(diào)用初始敵方坦克方法
self.creatMyTank()#創(chuàng)建我方坦克
self.creatWalls()#創(chuàng)建障礙物
while True:#無(wú)限循環(huán) 所有行為方法都要無(wú)限制的顯示
MainGame.window.fill(pygame.Color(0,0,0))#窗口顏色設(shè)置 Window在開(kāi)始方法已設(shè)置為游戲窗口
self.getEvent()#死循環(huán)中 獲取事件的值 對(duì)其進(jìn)行相應(yīng)處理
MainGame.window.blit(self.drawText("剩余敵方數(shù)量%d" %len(MainGame.EnemyTank_list)),(7, 7))#循環(huán)游戲窗口加載文本 bilt方法在頁(yè)面寫(xiě)入另一個(gè)
self.blitWalls()
if MainGame.Tank_p1 and MainGame.Tank_p1.alive:
MainGame.Tank_p1.displayTank()#循環(huán)調(diào)用生成的坦克對(duì)象(顯示)方法
self.blitEnemyTank()# 此類(lèi)中用self 循環(huán)展示敵方坦克
if MainGame.Tank_p1 and not MainGame.Tank_p1.stop:
MainGame.Tank_p1.move()# 移動(dòng)
MainGame.Tank_p1.hitWall()#撞擊墻壁
MainGame.Tank_p1.hitEnemyTank()#撞擊敵方坦克方法
self.blitEnemyBullet()#顯示敵方坦克子彈
self.blitBullet()#顯示炮彈
self.blitExplode()#顯示爆炸效果
time.sleep(0.02)
_display.update()#獲取更新
#將帶有文字的surface 繪制到窗口中 循環(huán)
# 創(chuàng)建敵方坦克
def creatEnemyTank(self):#創(chuàng)建敵方坦克
top = 100
for i in range(MainGame.EnemTank_count):#MainGame.EnemTank_count=5 五次循環(huán)創(chuàng)建敵方坦克
speed = random.randint(3, 6) # 隨機(jī)模塊 random.randint
# 每次都隨機(jī)生成一個(gè)left值
left = random.randint(1, 7)
eTank = EnemyTank(left * 100, top, speed)#生成敵方坦克類(lèi)對(duì)象 傳入?yún)?shù) left為隨機(jī)
MainGame.EnemyTank_list.append(eTank)#將創(chuàng)建的每一個(gè)敵方坦克添加到列表
# 將坦克加入到窗口中
def creatMyTank(self):
MainGame.Tank_p1 = MyTank(400, 480) # 生成一個(gè)坦克類(lèi)的實(shí)例對(duì)象
music = Music("img/start.wav")
music.play()
def creatWalls(self):
for i in range(1,10):
wall = Wall(60*i,250)
MainGame.wall_list.append(wall)
def blitWalls(self):
for wall in MainGame.wall_list:
if wall.live == True:
wall.displayWall()
else:
MainGame.wall_list.remove(wall)
def blitEnemyTank(self):#顯示敵方坦克 若出現(xiàn)坦克圖片重疊也是符合邏輯
for eTank in MainGame.EnemyTank_list:
if eTank.live :
eTank.displayTank()#將列表中每一個(gè)進(jìn)行顯示 eTank為敵方坦克類(lèi)對(duì)象 調(diào)用父類(lèi)Tank類(lèi)中顯示方法
eTank.randMove()
eTank.hitWall()
eTank.hitMyTank()
ebullet = eTank.shot()
if ebullet:#如果不為空
MainGame.EnemyTank_bullet_list.append(ebullet)
else:
MainGame.EnemyTank_list.remove(eTank)
def blitEnemyBullet(self):#將敵方坦克加入到窗口中
for ebullet in MainGame.EnemyTank_bullet_list:
if ebullet.alive:
ebullet.display_bullet()
ebullet.bulletMove()
ebullet.hitWalls()
if MainGame.Tank_p1.alive:
ebullet.hitMyTank()
else:
MainGame.EnemyTank_bullet_list.remove(ebullet)
def blitBullet(self):#顯示子彈
for bullet in MainGame.Bullet_list:#事件中獲的子彈的列表進(jìn)行遍歷 類(lèi)似顯示坦克方法 逐個(gè)展示
if bullet.alive:#Bullet類(lèi)中設(shè)置的標(biāo)簽 來(lái)判斷子彈的存活 True為生 根據(jù)炮彈移動(dòng)方法bulletmove()中所加限制條件
bullet.display_bullet()#調(diào)用列表中子彈對(duì)象的顯示方法
bullet.bulletMove()#子彈的移動(dòng)
bullet.hitEnemyTank()#調(diào)用與敵方坦克的碰撞檢測(cè)方法
bullet.hitWalls()#d調(diào)用子彈碰撞墻壁
else:
MainGame.Bullet_list.remove(bullet)#如果為False bulletmove()中觸碰墻壁就是False 就從列表刪除 循環(huán)執(zhí)行
def blitExplode(self):
for explode in MainGame.Explode_list:
if explode.live:
explode.display_explode()
music = Music("img/blast.wav")
music.play()
else:
MainGame.Explode_list.remove(explode)
def drawText(self,content):#文本 寫(xiě)入游戲窗口
pygame.font.init()#初始化字體
font = pygame.font.SysFont("kaiti",18)#創(chuàng)建字體對(duì)象
text_sf = font.render(content,True,color_red)#字體樣式對(duì)象
return text_sf #返回內(nèi)容的surface
def getEvent(self):#獲取所有事件
eventlist = pygame.event.get()#所有事件列表
for event in eventlist:#遍歷每一個(gè)事件進(jìn)行判斷 鍵盤(pán)輸入的字符
#type屬性
if event.type == pygame.QUIT:#如果是QUIT(就是點(diǎn)擊窗口的退出按鈕 叉號(hào))
print("退出游戲")
self.gameOver()#退出方法
if event.type == pygame.KEYUP:#如果鍵盤(pán)按鈕抬起 并且是上下左右鍵
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP\
or event.key == pygame.K_DOWN:
if MainGame.Tank_p1 and MainGame.Tank_p1.alive:
MainGame.Tank_p1.stop = True#stop為T(mén)rue 按鈕抬起就停止 start方法中的開(kāi)關(guān) 實(shí)現(xiàn)坦克按住按鈕持續(xù)移動(dòng)
if event.type == pygame.KEYDOWN:#如果事件的類(lèi)型為按下按鍵進(jìn)行如下判斷
if event.key == pygame.K_ESCAPE :
self.creatMyTank()
if MainGame.Tank_p1 and MainGame.Tank_p1.alive:
if event.key == pygame.K_LEFT:#如果為左方向鍵 如下為同一類(lèi)型
print("向左移動(dòng)")
MainGame.Tank_p1.direction = "L"#設(shè)置坦克方向進(jìn)行判斷向左就是L,
# 并設(shè)置游戲窗口的界限 還可以利用方向作為字典的鍵獲取坦克圖片 坦克的移動(dòng)方向
#就是加載不同方向的坦克圖片 呈現(xiàn)出移動(dòng)的效果
MainGame.Tank_p1.stop = False#坦克移動(dòng)的開(kāi)關(guān) 循環(huán)使用 False為移動(dòng)
if event.key == pygame.K_RIGHT:
print("向右移動(dòng)")
MainGame.Tank_p1.direction = "R"
MainGame.Tank_p1.stop = False
if event.key ==pygame.K_UP:
print("向上移動(dòng)")
MainGame.Tank_p1.direction = "U"
MainGame.Tank_p1.stop = False
if event.key == pygame.K_DOWN:
print("向下移動(dòng)")
MainGame.Tank_p1.direction = "D"
MainGame.Tank_p1.stop = False
if event.key == pygame.K_SPACE:#空格鍵發(fā)射子彈
if len(MainGame.Bullet_list) < 3:#控制子彈在屏幕顯示的數(shù)量 太多沒(méi)有游戲體驗(yàn) 列表中存儲(chǔ)三個(gè)
m = Bullet(MainGame.Tank_p1)#子彈類(lèi)對(duì)象 添加到列表 開(kāi)始方法調(diào)用顯示子彈 子彈觸碰墻壁列表內(nèi)移除對(duì)象
MainGame.Bullet_list.append(m)
music =Music("img/fire.wav")
music.play()
def gameOver(self):#游戲結(jié)束方法
exit()
class BaseItem(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class Tank(BaseItem):#坦克的父類(lèi)
def __init__(self,left,top):
#坦克圖片集合
self.images = {"U":pygame.image.load("img/p1tankU.gif"),
"D": pygame.image.load("img/p1tankD.gif"),
"L":pygame.image.load("img/p1tankL.gif"),
"R": pygame.image.load("img/p1tankR.gif"),}#坦克各方向圖片的加載
#坦克的方向
self.direction = "U"
#坦克初始化時(shí)候的默認(rèn)圖片,根據(jù)坦克的方向從字典里去提取
self.image = self.images[self.direction]
#坦克的區(qū)域(left,top,width,height)坦克位置以及坦克的大小
self.rect = self.image.get_rect()
self.rect.left = left#坦克距離左邊位置修改默認(rèn)參數(shù)指定的位置
self.rect.top = top#將坦克距離上邊的位置修改我指定的位置
self.speed = 15#設(shè)置坦克的速度
self.stop = True #設(shè)置移動(dòng)的開(kāi)關(guān)
self.oldtop = self.rect.top
self.oldleft = self.rect.left
def move(self):
self.oldtop = self.rect.top
self.oldleft = self.rect.left
if self.direction == "U":#向上時(shí)
if self.rect.top > 0:#self.rect = self.image.get_rect()
# self.rect.top = top#將坦克距離上邊的位置修改我指定的位置
self.rect.top -= self.speed#坦克的速度距離每一次調(diào)用時(shí)相減 直到<0時(shí)
elif self.direction == "D":#向下時(shí)
if self.rect.top < MainGame.screen_height-MainGame.Tank_p1.rect.height:#下邊界小于窗口的高度減去坦克自身的高度的距離
self.rect.top += self.speed #距離加速度的距離 循環(huán)一次添加一次
elif self.direction == "L":
if self.rect.left > 0:
self.rect.left -= self.speed
elif self.direction == "R":
if self.rect.left < MainGame.screen_width -MainGame.Tank_p1.rect.width:
self.rect.left += self.speed
def stay(self):
self.rect.left = self.oldleft
self.rect.top = self.oldtop
def hitWall(self):
for wall in MainGame.wall_list:
if pygame.sprite.collide_rect(wall,self):
self.stay()
def shot(self):
return Bullet(self)
def displayTank(self):#坦克顯示方法
#1.重新設(shè)置坦克的圖片
self.image = self.images[self.direction]
#2.將坦克加入到窗口中
MainGame.window.blit(self.image,self.rect)#調(diào)用MainGame window方法
# 傳入圖片和位置 self.rect = self.image.get_rect()
class MyTank(Tank):
def __init__(self,left,top):
super(MyTank,self).__init__(left,top)
def hitEnemyTank(self):
for etank in MainGame.EnemyTank_list:
if pygame.sprite.collide_rect(etank,self):
self.stay()
class EnemyTank(Tank):#敵方坦克類(lèi)
def __init__(self,left,top,speed):#初始化敵方坦克 三個(gè)參數(shù)
self.images = {"U": pygame.image.load("img/enemy1U.gif"),
"D": pygame.image.load("img/enemy1D.gif"),
"L": pygame.image.load("img/enemy1L.gif"),
"R": pygame.image.load("img/enemy1R.gif"), }#加載敵方坦克圖片
# 坦克的方向
self.direction = self.randDirection()#自定義坦克的隨機(jī)方向
self.image = self.images[self.direction]#坦克的信息 從字典中以鍵獲得值
# 坦克所在的區(qū)域 Rect->
self.rect = self.image.get_rect()#獲得坦克圖片的距離 距左和距上
# 指定坦克初始化位置 分別距x,y軸的位置
self.rect.left = left#距左的位置>>形參
self.rect.top = top#距上的位置
# 新增速度屬性
self.speed = speed #速度>>初始化時(shí)設(shè)置
self.stop = True
self.step = 50#設(shè)置步數(shù)
self.live = True
def randDirection(self):#隨機(jī)生成敵方坦克的方向圖片
num = random.randint(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):#敵方坦克隨機(jī)移動(dòng)
if self.step <= 0:#如果步數(shù)為0
self.direction = self.randDirection()#方向?yàn)殡S機(jī)方向
self.step = 30# 重置步數(shù)
else:
self.move()#移動(dòng) 坦克位置不斷改變
self.step -= 1#步數(shù)每次循環(huán)減一
def shot(self):
s = random.randint(1,1000)
if s <30:
return Bullet(self)
def hitMyTank(self):
if pygame.sprite.collide_rect(self,MainGame.Tank_p1):
self.stay()
class Bullet(BaseItem):#炮彈類(lèi)
def __init__(self,tank):
self.image = pygame.image.load("img\enemymissile.gif")
self.direction = tank.direction
#子彈速度
self.speed = 18
self.rect = self.image.get_rect()#獲得子彈的對(duì)象的坐標(biāo) 只計(jì)算距離左側(cè)和和上面
#子彈初始化位置要根據(jù)坦克大方向進(jìn)行調(diào)整 可以自己畫(huà)圖計(jì)算
if self.direction == "U":
#子彈的位置 left += 坦克寬度的一半 - 子彈的寬度的一半
self.rect.left = tank.rect.left + tank.rect.width/2 - self.rect.width/2
self.rect.top = tank.rect.top - self.rect.height
elif self.direction == "D":
self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2
self.rect.top = tank.rect.top - self.rect.height
elif self.direction == "L":
self.rect.left = tank.rect.left - tank.rect.width / 2 - self.rect.width / 2
self.rect.top = tank.rect.top + tank.rect.width/2 -self.rect.width/2
elif self.direction == "R":
self.rect.left = tank.rect.left + tank.rect.width / 2
self.rect.top = tank.rect.top + tank.rect.width/2 -self.rect.width/2
speed = 10#速度
alive = True#設(shè)置一個(gè)小標(biāo)簽 作判斷
def bulletMove(self):#炮彈移動(dòng)
if self.direction == "U":
if self.rect.top > 0 :#距離限制計(jì)算 self子彈對(duì)象本身 rect.top距離窗口上方 rect.left左側(cè)
self.rect.top -= self.speed
else:
self.alive = False#此為<0時(shí)的情況 同下都是觸碰墻壁時(shí)的情況
elif self.direction == "D":
if self.rect.top < MainGame.screen_height - self.rect.height:#屏幕高度 - 子彈的高度
self.rect.top += self.speed
else:
self.alive = False
elif self.direction == "L":
if self.rect.left > 0:
self.rect.left -= self.speed
else:
self.alive = False
elif self.direction == "R":
if self.rect.left < MainGame.screen_width - self.rect.width:
self.rect.left += self.speed
else:
self.alive = False
def hitEnemyTank(self):#我方子彈與敵方坦克相碰
for etank in MainGame.EnemyTank_list:#敵方坦克列表
if pygame.sprite.collide_rect(etank,self):#sprite中的相撞測(cè)試
explode = Explode(etank)#產(chǎn)生一個(gè)爆炸效果
MainGame.Explode_list.append(explode)
self.alive = False
etank.live = False
def hitMyTank(self):
if pygame.sprite.collide_rect(self,MainGame.Tank_p1):
explode = Explode(MainGame.Tank_p1)
MainGame.Explode_list.append(explode)
MainGame.Tank_p1.alive = False
self.alive = False
def hitWalls(self):
for wall in MainGame.wall_list:
if pygame.sprite.collide_rect(wall,self):
self.alive = False
wall.hp -= 1
if wall.hp <= 0:
wall.live = False
def display_bullet(self):#顯示子彈方法
MainGame.window.blit(self.image,self.rect)#窗口寫(xiě)入
class Explode:#爆炸效果
def __init__(self,tank):
self.step = 0
self.rect = tank.rect
self.images = [pygame.image.load("img/blast0.gif"),
pygame.image.load("img/blast1.gif"),
pygame.image.load("img/blast2.gif"),
pygame.image.load("img/blast3.gif"),
pygame.image.load("img/blast4.gif"),
pygame.image.load("img/blast5.gif"),
pygame.image.load("img/blast6.gif"),
pygame.image.load("img/blast7.gif"),]
self.live = True
self.image = self.images[self.step]
def display_explode(self):#顯示爆炸效果
if self.step < len(self.images):
MainGame.window.blit(self.image,self.rect)
self.image = self.images[self.step]
self.step += 1
else:
self.live = False
self.step = 0
class Wall:
def __init__(self,left,top):
self.image = pygame.image.load("img/steels.gif")
self.rect = self.image.get_rect()
self.rect.left = left
self.rect.top = top
self.live = True
self.hp = 3
def displayWall(self):#顯示障礙物
MainGame.window.blit(self.image,self.rect)
class Music:#音效
def __init__(self,filename):
self.filename = filename
pygame.mixer.init()#混合器的初始
pygame.mixer.music.load(self.filename)#加載音樂(lè)文件
def play(self):
pygame.mixer.music.play(loops=0)#播放音樂(lè)
MainGame().startGame()
更多關(guān)于python游戲的精彩文章請(qǐng)點(diǎn)擊查看以下專(zhuān)題:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- python中的三種注釋方法
- Python爬蟲(chóng)庫(kù)BeautifulSoup獲取對(duì)象(標(biāo)簽)名,屬性,內(nèi)容,注釋
- Python中的多行注釋文檔編寫(xiě)風(fēng)格匯總
- Python中注釋?zhuān)ǘ嘈凶⑨尯蛦涡凶⑨專(zhuān)┑挠梅▽?shí)例
- Python文件去除注釋的方法
- Python實(shí)現(xiàn)多行注釋的另類(lèi)方法
- Python注釋詳解
- VSCode中自動(dòng)為Python文件添加頭部注釋
- python3新特性函數(shù)注釋Function Annotations用法分析
- Python 注釋?zhuān)航忉尯蛢?yōu)化代碼可讀性
相關(guān)文章
Python實(shí)現(xiàn)統(tǒng)計(jì)圖像連通域的示例詳解
這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)統(tǒng)計(jì)圖像連通域的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-04-04
全網(wǎng)最全python庫(kù)selenium自動(dòng)化使用詳細(xì)教程
這篇文章主要介紹了python庫(kù)selenium自動(dòng)化使用詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-01-01
Python?Poetrya項(xiàng)目依賴(lài)管理安裝使用詳解
這篇文章主要為大家介紹了Python?Poetrya項(xiàng)目依賴(lài)管理安裝使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
Python3 關(guān)于pycharm自動(dòng)導(dǎo)入包快捷設(shè)置的方法
今天小編就為大家分享一篇Python3 關(guān)于pycharm自動(dòng)導(dǎo)入包快捷設(shè)置的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
淺談pyhton學(xué)習(xí)中出現(xiàn)的各種問(wèn)題(新手必看)
下面小編就為大家?guī)?lái)一篇淺談pyhton學(xué)習(xí)中出現(xiàn)的各種問(wèn)題(新手必看)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05
python第三方包安裝路徑site-packages下.libs作用詳解
這篇文章主要為大家介紹了python?第三方包安裝路徑?site-packages?下面的以?.libs?結(jié)尾的路徑作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
使用Python對(duì)Syslog信息進(jìn)行分析并繪圖的實(shí)現(xiàn)
這篇文章主要介紹了使用Python對(duì)Syslog信息進(jìn)行分析并繪圖的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04

