基於python實現坦克大戰遊戲
阿新 • • 發佈:2020-10-28
本文例項為大家分享了python實現坦克大戰遊戲的具體程式碼,供大家參考,具體內容如下
遊戲介面
pygame遊戲引擎的安裝
pip安裝
windows + R --> cmd --> 命令列輸入 pip install 模組名==版本號
pycharm中安裝
File --> setting --> Project --> Project Interpreter --> 右側 + install --> 搜尋框輸入pygame --> 下方
installPackage
面向物件分析
分析組成類
- 實現框架的搭建(類的設計)
- 主邏輯類
- 坦克類
- 我方坦克
- 敵方坦克 子彈類
- 爆炸類
- 牆壁類
- 音效類
框架搭建
import pygame #主邏輯類 class MainGame(): def startGame(self): pass def gameOver(self): pass #基本坦克類 class BaseTank(): pass #我方坦克類 class MyTank(): pass #敵方坦克類 class EnemyTank(): pass #子彈類 class Bullet(): pass #爆炸類 class Explode(): pass #牆壁類 class Wall(): pass #音效類 class Audio(): pass game = MainGame() game.startGame()
展示主視窗
import pygame SCREEN_WIDTH = 900 SCREEN_HEIGHT = 550 #主邏輯類 class MainGame(): #遊戲主視窗 window = None def startGame(self): #呼叫視窗初始化方法 pygame.display.init() MainGame.window = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT)) pygame.display.set_caption('坦克大戰v1.02') while True: #填充視窗背景色 MainGame.window.fill((0,0)) #重新整理 pygame.display.update() def gameOver(self): pass
事件監聽
class MainGame(): #遊戲主視窗 window = None def startGame(self): #呼叫視窗初始化方法 pygame.display.init() MainGame.window = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT)) pygame.display.set_caption('坦克大戰'+VERSION) while True: #填充視窗背景色 MainGame.window.fill((0,0)) #呼叫事件處理方法 self.getEvents() #重新整理 pygame.display.update() #所有事件處理的方法 def getEvents(self): #獲取佇列中所有事件,遍歷事件,對type為QUIT以及KEYDOWN兩種事件型別處理 eventList = pygame.event.get() #遍歷所有事件 for e in eventList: if e.type == pygame.QUIT: #呼叫遊戲結束的方法 self.gameOver() #如果事件型別為按下鍵盤按鍵 elif e.type == pygame.KEYDOWN: #根據具體按鍵做對應處理 if e.key == pygame.K_UP: print("向上移動") elif e.key == pygame.K_DOWN: print("向下移動") elif e.key == pygame.K_LEFT: print("向左移動") elif e.key == pygame.K_RIGHT: print("向右移動") elif e.key == pygame.K_SPACE: print("biubiu~~~") # elif e.type == pygame.MOUSEMOTION: # print(e.pos) def gameOver(self): #結束程式 exit()
顯示我方坦克
#我方坦克類 class MyTank(BaseTank): def __init__(self,x,y): super(MyTank,self).__init__() #設定具體的圖片集 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' #設定坦克的圖片 self.image = self.images[self.direction] #先基於影象獲取坦克的位置以及大小 self.rect = self.image.get_rect() #修改坦克座標,改成自定義位置 self.rect.centerx = x self.rect.centery = y def displayTank(self): self.image = self.images[self.direction] MainGame.window.blit(self.image,self.rect)
實現我方坦克的移動
坦克類中,實現移動方法
def move(self): #移動,基於速度在指定的方向進行移動 if self.direction == 'U': if self.rect.centery > self.rect.height/2: self.rect.centery ‐= self.speed elif self.direction == 'D': if self.rect.centery < SCREEN_HEIGHT ‐ self.rect.height/2: self.rect.centery += self.speed elif self.direction == 'L': if self.rect.centerx > self.rect.height/2: self.rect.centerx ‐= self.speed elif self.direction == 'R': if self.rect.centerx < SCREEN_WIDTH ‐ self.rect.height/2: self.rect.centerx += self.speed
事件處理方法中新增移動處理
#所有事件處理的方法 def getEvents(self): #獲取佇列中所有事件,遍歷事件,對type為QUIT以及KEYDOWN兩種事件型別處理 eventList = pygame.event.get() #遍歷所有事件 for e in eventList: if e.type == pygame.QUIT: #呼叫遊戲結束的方法 self.gameOver() #如果事件型別為按下鍵盤按鍵 elif e.type == pygame.KEYDOWN: #根據具體按鍵做對應處理 if e.key == pygame.K_UP: print("向上移動") MainGame.tank1.direction = 'U' MainGame.tank1.move() elif e.key == pygame.K_DOWN: print("向下移動") MainGame.tank1.direction = 'D' MainGame.tank1.move() elif e.key == pygame.K_LEFT: print("向左移動") MainGame.tank1.direction = 'L' MainGame.tank1.move() elif e.key == pygame.K_RIGHT: print("向右移動") MainGame.tank1.direction = 'R' MainGame.tank1.move() elif e.key == pygame.K_SPACE: print("biubiu~~~")
優化移動方式
事件中新增坦克移動開關控制
#所有事件處理的方法 def getEvents(self): #獲取佇列中所有事件,遍歷事件,對type為QUIT以及KEYDOWN兩種事件型別處理 eventList = pygame.event.get() #遍歷所有事件 for e in eventList: if e.type == pygame.QUIT: #呼叫遊戲結束的方法 self.gameOver() #如果事件型別為按下鍵盤按鍵 elif e.type == pygame.KEYDOWN: #根據具體按鍵做對應處理 if e.key == pygame.K_UP: print("向上移動") MainGame.tank1.direction = 'U' #修改坦克運動狀態 MainGame.tank1.stop = False elif e.key == pygame.K_DOWN: print("向下移動") MainGame.tank1.direction = 'D' MainGame.tank1.stop = False elif e.key == pygame.K_LEFT: print("向左移動") MainGame.tank1.direction = 'L' MainGame.tank1.stop = False elif e.key == pygame.K_RIGHT: print("向右移動") MainGame.tank1.direction = 'R' MainGame.tank1.stop = False elif e.key == pygame.K_SPACE: print("biubiu~~~")
主邏輯的迴圈中優化移動
def startGame(self): #呼叫視窗初始化方法 pygame.display.init() MainGame.window = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT)) pygame.display.set_caption('坦克大戰'+VERSION) #呼叫建立我方坦克的方法 self.creatMyTank() while True: #填充視窗背景色 MainGame.window.fill((0,0)) #呼叫事件處理方法 self.getEvents() #展示我方坦克 self.showMyTank() if not MainGame.tank1.stop: # 我方坦克移動 MainGame.tank1.move() #重新整理 pygame.display.update() #新增,程式休眠,優化坦克移動速度 time.sleep(0.020)
實現敵方坦克的載入
完善敵方坦克類
#敵方坦克類 class EnemyTank(BaseException): #v1.07 def __init__(self,y): 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.randomDirection() # 設定坦克的圖片 self.image = self.images[self.direction] # 先基於影象獲取坦克的位置以及大小 self.rect = self.image.get_rect() # 修改坦克座標,改成自定義位置 self.rect.centerx = x self.rect.centery = y #v1.07生成坦克的隨機方向 def randomDirection(self): 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' #v1.07將敵方坦克加入到視窗中 def displayTank(self): self.image = self.images[self.direction] MainGame.window.blit(self.image,self.rect)
主邏輯中實現敵方坦克的載入
class MainGame(): #遊戲主視窗 window = None tank1 = None #v1.07 新增儲存敵方坦克的列表 enemy_tanklist = [] def startGame(self): #呼叫視窗初始化方法 pygame.display.init() MainGame.window = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT)) pygame.display.set_caption('坦克大戰'+VERSION) #呼叫建立我方坦克的方法 self.creatMyTank() #v1.07呼叫建立敵方坦克的方法 self.creatEnemyTank() while True: #填充視窗背景色 MainGame.window.fill((0,0)) #呼叫事件處理方法 self.getEvents() #展示我方坦克 self.showMyTank() #v1.07呼叫展示敵方坦克的方法 self.showEnemyTank() if not MainGame.tank1.stop: # 我方坦克移動 MainGame.tank1.move() #重新整理 pygame.display.update() #v1.06新增,程式休眠,優化坦克移動速度 time.sleep(0.020) #建立我方坦克 def creatMyTank(self): MainGame.tank1 = MyTank(SCREEN_WIDTH/2,SCREEN_HEIGHT/3*2) #展示我方坦克 def showMyTank(self): MainGame.tank1.displayTank() #v1.07建立敵方坦克 def creatEnemyTank(self): for i in range(ENEMM_TANK_COUNT): num = random.randint(1,7) etank = EnemyTank(100*num,150) MainGame.enemy_tanklist.append(etank) #v1.07展示敵方坦克 def showEnemyTank(self): for etank in MainGame.enemy_tanklist: etank.displayTank()
執行效果
完整程式碼
# from pygame import * import pygame,time,random SCREEN_WIDTH = 900 SCRREN_HEIGHT = 600 COLOR_BLACK = pygame.Color(0,0) VERSION = 'v2.5' class MainGame(): #遊戲視窗 window = None P1 = None #敵方坦克列表 enemyTankList = [] #我方子彈列表 myBulletList = [] #儲存敵方子彈 enemyBulletList = [] #儲存爆炸效果的列表 bombList = [] #儲存牆壁的列表 wallList = [] def __init__(self): self.version = VERSION def startGame(self): print('遊戲開始') #初始化展示模組 pygame.display.init() #呼叫自定義的建立視窗的方法 self.creatWindow() #設定遊戲標題 pygame.display.set_caption('坦克大戰'+self.version) #呼叫建立牆壁的方法 self.creatWalls() #呼叫建立坦克方法 self.creatMyTank() #呼叫建立敵方坦克 self.creatEnemyTank() while True: #設定遊戲背景的填充色 MainGame.window.fill(COLOR_BLACK) #呼叫展示牆壁的方法 self.showAllWalls() # 呼叫展示我方坦克的方法 self.showMyTank() #呼叫展示我方子彈的方法 self.showAllMyBullet() #呼叫展示所有爆炸效果的方法 self.showAllBombs() #呼叫展示敵方坦克的方法 self.showEnemyTank() #呼叫展示敵方子彈的方法 self.showAllEnemyBullet() #呼叫獲取事件,處理事件的方法 self.getAllEvents() #視窗持續重新整理以即時顯示 pygame.display.update() time.sleep(0.02) def creatWindow(self): MainGame.window = pygame.display.set_mode((SCREEN_WIDTH,SCRREN_HEIGHT)) def getAllEvents(self): #獲取所有的事件 event_list = pygame.event.get() for e in event_list: if e.type == pygame.QUIT: #關閉視窗,結束遊戲,呼叫gameOver方法 self.gameOver() elif e.type == pygame.KEYDOWN: print('點選鍵盤按鍵') if e.key == pygame.K_SPACE: bullet = MainGame.P1.shot() #控制子彈發射的數量 if len(MainGame.myBulletList) < 4: print('發射子彈') MainGame.myBulletList.append(bullet) print('當前我方子彈數量為:',len(MainGame.myBulletList)) #建立音效物件,播放音效檔案 audio = Audio('tank-images/boom.wav') audio.play() #建立牆壁的方法 def creatWalls(self): for i in range(1,8): wall = Wall(i*120,380,'tank-images/steels.gif') MainGame.wallList.append(wall) #展示牆壁的方法 def showAllWalls(self): for w in MainGame.wallList: w.displayWall() def creatMyTank(self): MainGame.P1 = MyTank(SCREEN_WIDTH/2,SCRREN_HEIGHT/4*3) def showMyTank(self): MainGame.P1.displayTank() MainGame.P1.move() MainGame.P1.hitWalls() #展示我方子彈 def showAllMyBullet(self): for b in MainGame.myBulletList: if b.live: b.displayBullet() #呼叫子彈的移動方法 b.move() #呼叫是否打中敵方坦克的方法 b.hitEnemyTank() #呼叫是否打中牆壁的方法 b.hitWalls() else: MainGame.myBulletList.remove(b) #展示敵方子彈 def showAllEnemyBullet(self): for b in MainGame.enemyBulletList: if b.live: b.displayBullet() b.move() #呼叫是否打中牆壁的方法 b.hitWalls() else: MainGame.enemyBulletList.remove(b) def creatEnemyTank(self): for i in range(5): etank = EnemyTank(random.randint(1,8)*100,150) MainGame.enemyTankList.append(etank) def showEnemyTank(self): for etank in MainGame.enemyTankList: etank.displayTank() etank.move() etank.hitWalls() #呼叫射擊方法 etank.shot() #展示所有爆炸效果 def showAllBombs(self): for bomb in MainGame.bombList: if bomb.live: bomb.displayBomb() else: MainGame.bombList.remove(bomb) def gameOver(self): print('遊戲結束') exit() class Tank(): def __init__(self,y): #圖片集(儲存4個方向的所有圖片) self.images = { 'U':pygame.image.load('tank-images/tankU.gif'),'D':pygame.image.load('tank-images/tankD.gif'),'L':pygame.image.load('tank-images/tankL.gif'),'R':pygame.image.load('tank-images/tankR.gif'),} self.direction = 'U' #從圖片集中根據方向獲取圖片 self.image = self.images[self.direction] self.rect = self.image.get_rect() self.rect.centerx = x self.rect.centery = y self.speed = 3 self.isDead = False #新增屬性用來記錄上一步的座標 self.oldx = self.rect.centerx self.oldy = self.rect.centery def stay(self): self.rect.centerx = self.oldx self.rect.centery = self.oldy def hitWalls(self): index = self.rect.collidelist(MainGame.wallList) if index != -1: self.stay() def move(self): #記錄移動之前的座標 self.oldx = self.rect.centerx self.oldy = self.rect.centery if self.direction == 'U': if self.rect.centery > self.rect.height/2: self.rect.centery -= self.speed elif self.direction == 'D': if self.rect.centery < SCRREN_HEIGHT - self.rect.height/2: self.rect.centery += self.speed elif self.direction == 'L': if self.rect.centerx > self.rect.height/2: self.rect.centerx -= self.speed elif self.direction == 'R': if self.rect.centerx < SCREEN_WIDTH - self.rect.height/2: self.rect.centerx += self.speed def shot(self): return Bullet(self) def displayTank(self): # 重新設定坦克圖片 self.image = self.images[self.direction] # 將坦克載入的到視窗 MainGame.window.blit(self.image,self.rect) class MyTank(Tank): def __init__(self,self).__init__(x,y) def move(self): #pygame.key pressed_list = pygame.key.get_pressed() #分別判斷上下左右四個方向的按鍵,按下的狀態 if pressed_list[pygame.K_LEFT]: #修改坦克的方向 self.direction = 'L' super(MyTank,self).move() elif pressed_list[pygame.K_RIGHT]: self.direction = 'R' super(MyTank,self).move() elif pressed_list[pygame.K_UP]: self.direction = 'U' super(MyTank,self).move() elif pressed_list[pygame.K_DOWN]: self.direction = 'D' super(MyTank,self).move() class EnemyTank(Tank): def __init__(self,y): super(EnemyTank,y) #隨機速度 self.speed = self.randSpeed(2,5) #隨機方向 self.direction = self.randDirection() #圖片 # self.image = self.images[self.direction] #座標位置 self.rect = self.image.get_rect() self.rect.centerx = x self.rect.centery = y #記錄坦克移動步數的變數 self.step = random.randint(25,50) #生成隨機速度值 def randSpeed(self,from_,to_): return random.randint(from_,to_) def randDirection(self): list1 = ['U','D','L','R'] return list1[random.randint(0,3)] def move(self): if self.step > 0: super(EnemyTank,self).move() self.step -= 1 else: #1.生成新的方向 self.direction = self.randDirection() #2.步數還原 self.step = random.randint(25,50) def shot(self): num = random.randint(1,40) if num == 1: b = Bullet(self) MainGame.enemyBulletList.append(b) class Bullet(): def __init__(self,tank): #圖片 if isinstance(tank,MyTank): self.image = pygame.image.load('tank-images/tankmissile.gif') else: self.image = pygame.image.load('tank-images/enemymissile.gif') #方向 self.direction = tank.direction #座標位置 self.rect = self.image.get_rect() #子彈的具體位置 if self.direction == 'U': self.rect.centerx = tank.rect.centerx self.rect.centery = tank.rect.centery - tank.rect.height/2 - self.rect.height/2 elif self.direction == 'D': self.rect.centerx = tank.rect.centerx self.rect.centery = tank.rect.centery + tank.rect.height / 2 + self.rect.height / 2 elif self.direction == 'L': self.rect.centery = tank.rect.centery self.rect.centerx = tank.rect.centerx - tank.rect.height/2 - self.rect.height/2 elif self.direction == 'R': self.rect.centery = tank.rect.centery self.rect.centerx = tank.rect.centerx + tank.rect.height / 2 + self.rect.height / 2 #移動速度 self.speed = 8 #子彈的狀態(live) self.live = True def move(self): if self.direction == 'U': #邊界控制 if self.rect.centery > 0: self.rect.centery -= self.speed else: self.live = False elif self.direction == 'D': if self.rect.centery < SCRREN_HEIGHT: self.rect.centery += self.speed else: self.live = False elif self.direction == 'L': if self.rect.centerx > 0: self.rect.centerx -= self.speed else: self.live = False elif self.direction == 'R': if self.rect.centerx < SCREEN_WIDTH: self.rect.centerx += self.speed else: self.live = False def displayBullet(self): MainGame.window.blit(self.image,self.rect) #子彈與牆壁的碰撞 def hitWalls(self): index = self.rect.collidelist(MainGame.wallList) if index != -1: self.live = False # 我方子彈是否碰撞到敵方坦克 def hitEnemyTank(self): index = self.rect.collidelist(MainGame.enemyTankList) if index != -1: # 打中敵方坦克後的業務邏輯 # 修改子彈的live屬性 self.live = False tank = MainGame.enemyTankList.pop(index) # 打中敵方坦克之後產生一個爆炸效果,裝進爆炸效果列表中 bomb = Bomb(tank) MainGame.bombList.append(bomb) class Bomb(): def __init__(self,tank): #儲存多張爆炸效果的圖片 self.images = [ pygame.image.load('tank-images/0.gif'),pygame.image.load('tank-images/1.gif'),pygame.image.load('tank-images/2.gif'),pygame.image.load('tank-images/3.gif'),pygame.image.load('tank-images/4.gif'),pygame.image.load('tank-images/5.gif'),pygame.image.load('tank-images/6.gif') ] #用來記錄圖片為圖片集中的第幾張 self.index = 0 self.image = self.images[self.index] self.live = True self.rect = self.image.get_rect() self.rect.centerx = tank.rect.centerx self.rect.centery = tank.rect.centery def displayBomb(self): if self.index < len(self.images): self.image = self.images[self.index] self.index += 1 MainGame.window.blit(self.image,self.rect) else: self.index = 0 self.live = False class Audio(): def __init__(self,musicpath): pygame.mixer.init() pygame.mixer.music.load(musicpath) def play(self): pygame.mixer.music.play() class Wall(): def __init__(self,y,imagepath): self.image = pygame.image.load(imagepath) self.rect = self.image.get_rect() self.rect.centerx = x self.rect.centery = y def displayWall(self): MainGame.window.blit(self.image,self.rect) game = MainGame() game.startGame()
更多關於python遊戲的精彩文章請點選檢視以下專題:
python俄羅斯方塊遊戲集合
python經典小遊戲彙總
python微信跳一跳遊戲集合
更多有趣的經典小遊戲實現專題,分享給大家:
C++經典小遊戲彙總
python經典小遊戲彙總
python俄羅斯方塊遊戲集合
JavaScript經典遊戲 玩不停
javascript經典小遊戲彙總
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。