1. 程式人生 > 程式設計 >基於python實現坦克大戰遊戲

基於python實現坦克大戰遊戲

本文例項為大家分享了python實現坦克大戰遊戲的具體程式碼,供大家參考,具體內容如下

遊戲介面

基於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()

執行效果

基於python實現坦克大戰遊戲

完整程式碼

# 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經典小遊戲彙總

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。