坦克大戰小遊戲 版本號v1.10
阿新 • • 發佈:2018-12-18
python 初階
''' v1.10 實現子彈的移動與消失 ''' import pygame,time,random SCREEN_WIDTH = 900 SCREEN_HEIGHT = 550 VERSION = 'V1.10' # v1.07新增 記錄敵方坦克的數量 ENEMY_TANK_COUNT = 5 # 主邏輯類 class MainGame(): # 遊戲主視窗 window = None # 我方坦克(唯一性)設定成類屬性 tank1 = None # v1.07新增儲存敵方坦克的列表 enemy_tanklist = [] # v1.09 新增儲存我方子彈的列表 mybullet_list = [] def startGame(self): # 呼叫視窗初始化方法 pygame.display.init() # 在視窗左上角設定遊戲標題 pygame.display.set_caption('坦克大戰'+VERSION) # 建立一個視窗螢幕顯示錶面 MainGame.window = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT)) # 呼叫建立我方坦克的方法 self.createMytank() # 呼叫建立敵方坦克的方法 self.createEnemytank() while True: # 填充視窗背景色 MainGame.window.fill((100,100,200)) # 將獲取的事件型別在填充完視窗背景色後時刻處於迴圈中 self.getEvents() # 展示我方坦克 self.showMytank() # 呼叫展示敵方坦克的方法 self.showEnemyTank() # v1.09 新增呼叫展示我方子彈的方法 self.showMyBullet() # 更新 pygame.display.update() # v1.06 新增程式休眠,優化坦克的移動速度 time.sleep(0.025) # 獲取所有事件處理的方法 def getEvents(self): # 獲取佇列中的所有事件,遍歷事件,對type為QUIT和KEYDOWN的兩種事件型別進行處理 eventList = pygame.event.get() # 遍歷所有事件 for e in eventList: # 當事件型別是QUIT時,退出遊戲 if e.type == pygame.QUIT: self.showMytank() # 退出遊戲 self.gameOver() # 當事件型別是KEYDOWN時,進行細化處理 elif e.type == pygame.KEYDOWN: # 按下鍵盤上的向上按鍵時的處理 if e.key == pygame.K_UP: print('向上移動') MainGame.tank1.direction = 'U' # v1.06修改坦克的移動狀態 MainGame.tank1.stop = False # 按下鍵盤上的向下按鍵時的處理 elif e.key == pygame.K_DOWN: print('向下移動') MainGame.tank1.direction = 'D' # v1.06修改坦克的移動狀態 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~') # v1.09 新增呼叫發射方法,並將子彈裝進列表 b = MainGame.tank1.shoot() MainGame.mybullet_list.append(b) print('子彈的數量%d'%len(MainGame.mybullet_list)) #v1.06新增按鍵鬆開的事件處理 elif e.type == pygame.KEYUP: if e.key == pygame.K_UP or e.key == pygame.K_DOWN or\ e.key == pygame.K_LEFT or e.key == pygame.K_RIGHT: # 將坦克的移動狀態改為停止 MainGame.tank1.stop = True # 建立我方坦克 def createMytank(self): # 建立我方坦克並賦予其位置屬性座標 MainGame.tank1 = MyTank(SCREEN_WIDTH/2,SCREEN_HEIGHT/3*2) #展示我方坦克 def showMytank(self): MainGame.tank1.displayTank() # v1.08 新增將 我方坦克移動程式碼 移動位置 if not MainGame.tank1.stop: # 我方坦克移動 MainGame.tank1.move() # v1.07建立敵方坦克 def createEnemytank(self): # 迴圈建立敵方坦克 for i in range(ENEMY_TANK_COUNT): num = random.randint(1,7) # v1.08新增 隨機速度 randomspeed = random.randint(3,10) # 建立第一個敵方坦克,出現位置為y=150,x隨機出現在(100-700),坦克移動的隨機速度是randomspeed # v1.08新增呼叫修改後的init方法 etank = EnemyTank(100*num,150,randomspeed) # 建立敵方坦克列表,存入所有的敵方坦克 MainGame.enemy_tanklist.append(etank) # v1.07展示敵方坦克 def showEnemyTank(self): # 遍歷展示敵方坦克 for etank in MainGame.enemy_tanklist: etank.displayTank() # v1.08 新增敵方坦克的移動 etank.move() # v1.09 展示我方子彈的方法 def showMyBullet(self): for b in MainGame.mybullet_list: # 如果子彈活著,展示並移動子彈 if b.live == True: b.displayBullet() # v1.10 新增呼叫子彈的移動方法 b.move() # 如果子彈死亡,移除子彈,給子彈列表騰空間,保證打到牆上的子彈消失 else: MainGame.mybullet_list.remove(b) def gameOver(self): exit() # 基本坦克類 class BaseTank(): # 基本坦克屬性 位置 方向 速度 圖片 def __init__(self): self.direction = None self.rect = None self.images = None self.image = None self.speed = 0 #v1.06新增屬性,用來控制坦克是否移動 self.stop = True # v1.08 優化移動 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 # v1.09 新增射擊方法 def shoot(self): bullet = Bullet(self) return bullet # 我方坦克類 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 返回的是一個surface) self.image = self.images[self.direction] # 先基於影象獲取坦克的位置和大小 self.rect = self.image.get_rect() # 修改坦克座標,改成自定義位置 self.rect.centerx = x self.rect.centery = y # 設定坦克速度 self.speed = 5 #將我方坦克加入到視窗中 def displayTank(self): self.image = self.images[self.direction] # 把坦克的影象(即表面)和位置放到另一個影象或表面視窗 MainGame.window.blit(self.image,self.rect) # 敵方坦克類 class EnemyTank(BaseTank): # v1.08新增隨機速度引數 def __init__(self,x,y,randSpeed): # v1.08新增呼叫父類的初始化 super(EnemyTank, self).__init__() # 設定具體的圖片集 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') } # v1.07敵方坦克的初始方向為隨機方向 self.direction = self.randomDirection() # 設定坦克的圖片(self.image 返回的是一個surface) self.image = self.images[self.direction] # 先基於影象獲取坦克的位置和大小 self.rect = self.image.get_rect() # 修改坦克座標,改成自定義位置 self.rect.centerx = x self.rect.centery = y # v1.08新增速度為引數傳進來的速度 self.speed = randSpeed # v1.08新增記錄敵方坦克移動的步數 self.step = 25 # 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.08新增重寫父類中的移動move方法,方法中新增隨機方向的處理 def move(self): if self.step == 0: # 變換方向 self.direction = self.randomDirection() # 將步數重新歸置成25 self.step = 25 else: super(EnemyTank, self).move() self.step -= 1 # 將敵方坦克加入到視窗中 def displayTank(self): self.image = self.images[self.direction] # 把坦克的影象(即表面)和位置放到另一個影象或表面視窗 MainGame.window.blit(self.image, self.rect) #v1.09 新增實現子彈類 class Bullet(): def __init__(self,tank): self.image = pygame.image.load('img/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.centerx = tank.rect.centerx - tank.rect.height/2 - self.rect.height/2 self.rect.centery = tank.rect.centery elif self.direction == 'R': self.rect.centerx = tank.rect.centerx + tank.rect.height / 2 + self.rect.height / 2 self.rect.centery = tank.rect.centery #v1.10 新增子彈移動速度 self.speed = 11 # v1.10 新增子彈的存活狀態,用來記錄子彈是否活著 self.live = True # v1.10 新增子彈的移動方法 def move(self): if self.direction == 'U': if self.rect.centery > self.rect.height/2: self.rect.centery -= self.speed else: self.live = False elif self.direction == 'D': if self.rect.centery < SCREEN_HEIGHT - self.rect.height/2: self.rect.centery += self.speed else: self.live = False elif self.direction == 'L': if self.rect.centerx > self.rect.height / 2: self.rect.centerx -= self.speed else: self.live = False elif self.direction == 'R': if self.rect.centerx < SCREEN_WIDTH - self.rect.height / 2: self.rect.centerx += self.speed else: self.live = False #將子彈的影象展示到遊戲主視窗 def displayBullet(self): MainGame.window.blit(self.image,self.rect) # 爆炸類 class Explode(): pass # 牆壁類 class Wall(): pass # 音效類 class Audio(): pass #建立一個主邏輯類的物件 game = MainGame() # 開始遊戲 game.startGame()