簡易坦克大戰python版


  # ! /usr/bin/env python
# -*- coding:utf8 -*-
'''
*author:wasua
*purpose:學習python語言,其中的類以及pygame應用
*date:2019/04/20
'''

'''
類:
    sprite:
        1.游戲主界面

        2.坦克:我方坦克\敵方坦克
            1.移動
            2.發射炮彈
        3.炮彈:大炮彈\小炮彈
            1.撞到
            2.爆炸(也是一個連續圖片)
        4.障礙物:
       1.能否闖過
       2.能否擊毀
5.爆炸
''' import pygame, sys, time from random import randint class TankMain(object): """坦克大戰的主窗口""" Width = 1000 Height = 800 live_count = 4 # 3次復活機會 my_tank = None #steel_wall = [] #block_wall = [] #grass_wall = [] wall=[] my_tank_missile = [] enemy_list = pygame.sprite.Group() enemy_missile_list = pygame.sprite.Group() explode_list = [] # 開始游戲的方法 def startGame(self): pygame.init() # 創建一個平面,設置平面大小(寬,高),窗口的屬性(0,RESIZEBLE,FULLSCREEN) screem = pygame.display.set_mode((TankMain.Width, TankMain.Height), 0, 32) # 設置窗口標題 pygame.display.set_caption('坦克大戰') for i in range(6):#此處應該編寫一個函數來進行比較好 TankMain.wall.append(SteelsWall(screem, 100 + i * 60, 100)) TankMain.wall.append(BlockWall(screem, 700, 100 + i * 60)) TankMain.wall.append(GrassWall(screem, 500, 0 + i * 60)) TankMain.wall.append(GrassWall(screem,50,40)) #wall = TankMain.steel_wall + TankMain.grass_wall + TankMain.block_wall TankMain.my_tank = My_TanK(screem) for i in range(0, 20): TankMain.enemy_list.add(Enemy_TanK(screem)) while True: # if len(TankMain.enemy_list)<5:#地獄模式 # TankMain.enemy_list.add(Enemy_TanK(screem)) # 顯示牆 for i in TankMain.wall: i.display() i.hit_tank() i.hit_missile() if not i.live: TankMain.wall.remove(i) pygame.display.update() # 此處不添加則會導致圖片不顯示 # 設置窗口填充(背景---RGB模式) screem.fill((0, 0, 0)) # 顯示左上角的文字 for index, text in enumerate(self.write_text(TankMain.enemy_list)): screem.blit(text, (0, 5 + (15 * index))) # screem.blit(self.write_text(TankMain.enemy_list),(0,0)) self.get_event(TankMain.my_tank, screem) if TankMain.my_tank: TankMain.my_tank.hit_enemy_missile() if TankMain.my_tank and TankMain.my_tank.live: TankMain.my_tank.display() TankMain.my_tank.move() else: TankMain.my_tank = None for enemy in TankMain.enemy_list: enemy.display() enemy.random_move() enemy.random_fire() for m in TankMain.my_tank_missile: if m.live: m.display() m.hit_tank() m.move() else: TankMain.my_tank_missile.remove(m) for m in TankMain.enemy_missile_list: if m.live: m.display() m.move() else: TankMain.enemy_missile_list.remove(m) for explode in TankMain.explode_list: explode.display() # 顯示重置 time.sleep(0.1) pygame.display.update() # 關閉游戲 def stopGame(self): sys.exit() # 屏幕左上角顯示文字內容 def write_text(self, enemy_list): # 定義字體 font = pygame.font.SysFont('微軟雅黑', 15, (255, 255, 255)) # 根據字體創建一個文件圖像 text_sf1 = font.render(u'敵方坦克數量為:%d' % len(enemy_list), True, (255, 255, 255)) text_sf2 = font.render(u'生命數量:%d' % (int(TankMain.live_count) - 1), True, (255, 255, 255)) return text_sf1, text_sf2 # 獲取事件,敲擊鍵盤,鼠標點擊 def get_event(self, my_tank, screem): for event in pygame.event.get(): if event.type == pygame.QUIT: # 我方坦克犧牲后不能按Esc恩退出 self.stopGame() if event.type == pygame.KEYDOWN and (not TankMain.my_tank) and ( event.key == pygame.K_r or event.key == pygame.K_n): # 按n或r復活 TankMain.my_tank = My_TanK(screem) # 我方坦克不復活不可以按Esc退出 TankMain.live_count -= 1 if TankMain.live_count == 0: sys.exit() if event.type == pygame.KEYDOWN and my_tank: if event.key == pygame.K_LEFT or event.key == pygame.K_a: my_tank.direction = "L" my_tank.stop = False if event.key == pygame.K_RIGHT or event.key == pygame.K_d: my_tank.direction = "R" my_tank.stop = False if event.key == pygame.K_UP or event.key == pygame.K_w: my_tank.direction = 'U' my_tank.stop = False if event.key == pygame.K_DOWN or event.key == pygame.K_x: my_tank.direction = "D" my_tank.stop = False if event.key == pygame.K_ESCAPE: self.stopGame() if event.key == pygame.K_SPACE: m = my_tank.fire() m.good = True TankMain.my_tank_missile.append(m) if event.type == pygame.K_UP: if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP or event.key == pygame.K_DOWN or event.key == pygame.K_a or event.key == pygame.K_d or event.key == pygame.K_w or event.key == pygame.K_x: my_tank.stop = True if event.type == pygame.MOUSEMOTION: pass # 坦克大戰中所有對象的父類 class BaseItem(pygame.sprite.Sprite): def __init__(self, screem): pygame.sprite.Sprite.__init__(self) self.screem = screem def display(self): if self.live: self.image = self.images[self.direction] self.screem.blit(self.image, self.rect)
# 坦克類 class Tank(BaseItem): Width = 48 Height = 48 def __init__(self, screem, left, top): super().__init__(screem) self.screem = screem self.direction = "D" # 坦克默認方向向下(上下左右) self.speed = 5 # 坦克移動速度 self.stop = False self.images = {} # 坦克圖集 self.images['L'] = pygame.image.load('image/enemytank/tankl.png') self.images['R'] = pygame.image.load('image/enemytank/tankr.png') self.images['U'] = pygame.image.load('image/enemytank/tanku.png') self.images['D'] = pygame.image.load('image/enemytank/tankd.png') self.image = self.images[self.direction] self.rect = self.image.get_rect() self.rect.left = left self.rect.top = top self.live = True # 覺得坦克是否存活 self.oldtop = self.rect.top self.oldleft = self.rect.left # 將坦克對相應圖片顯示在游戲窗口 def stay(self): self.rect.left = self.oldleft self.rect.top = self.oldtop def move(self): if not self.stop: self.oldtop = self.rect.left self.oldleft = self.rect.top if self.direction == "L": if self.rect.left > 0: # 坦克是否到達左邊界 self.rect.left -= self.speed else: self.rect.left = 0 elif self.direction == "R": if self.rect.right < TankMain.Width: self.rect.right += self.speed else: self.rect.right = TankMain.Width elif self.direction == "U": if self.rect.top > 0: self.rect.top -= self.speed else: self.rect.top = 0 elif self.direction == "D": if self.rect.top < TankMain.Height: self.rect.top += self.speed else: self.rect.top = TankMain.Height else: pass def fire(self): m = Missile(self.screem, self) return m class My_TanK(Tank): def __init__(self, screem): super().__init__(screem, 275, 450) self.images = {} # 坦克圖集 self.images['L'] = pygame.image.load('image/my_tank/mytankl.png') self.images['R'] = pygame.image.load('image/my_tank/mytankr.png') self.images['U'] = pygame.image.load('image/my_tank/mytanku.png') self.images['D'] = pygame.image.load('image/my_tank/mytankd.png') self.image = self.images[self.direction] self.rect = self.image.get_rect() def hit_enemy_missile(self): hit_list = pygame.sprite.spritecollide(self, TankMain.enemy_missile_list, True) for m in hit_list: # 我方坦克中彈 m.live = False TankMain.enemy_missile_list.remove(m) self.live = False explode = Explode(self.screem, self.rect) TankMain.explode_list.append(explode) class Enemy_TanK(Tank): def __init__(self, screem): super().__init__(screem, randint(0, TankMain.Height), randint(0, TankMain.Width)) self.step = randint(5, 10) self.get_random_direction() def get_random_direction(self): r = randint(0, 4) if r == 0: self.stop = True elif r == 1: self.direction = 'L' self.stop = False elif r == 2: self.direction = 'R' self.stop = False elif r == 3: self.direction = 'U' self.stop = False elif r == 4: self.direction = 'D' self.stop = False else: pass # 敵方坦克按隨機方向連續移動多步才改變方向 def random_move(self): if self.live: if self.step == 0: self.get_random_direction() self.step = randint(5, 10) else: self.move() self.step -= 1 def random_fire(self): r = randint(0, 50) if r > 45: m = self.fire() TankMain.enemy_missile_list.add(m) else: return class Missile(BaseItem): Width = 8 Height = 8 def __init__(self, screem, tank): # super().__init__(screem)坑 # print('error') super().__init__(screem) self.screem = screem self.tank = tank self.direction = tank.direction # 炮彈方向隨坦克默認方向向下(上下左右) self.speed = 60 # 炮彈移動速度 self.stop = False self.images = {} # 坦克圖集 self.images['L'] = pygame.image.load('image/missile/missile.png') self.images['R'] = pygame.image.load('image/missile/missile.png') self.images['U'] = pygame.image.load('image/missile/missile.png') self.images['D'] = pygame.image.load('image/missile/missile.png') self.image = self.images[self.direction] self.rect = self.image.get_rect() self.rect.left = tank.rect.left + (tank.Width - self.Width) / 2 self.rect.top = tank.rect.top + (tank.Height - self.Height) / 2 self.live = True # 決定炮彈是否存在 self.good = False def move(self): if self.live: if self.direction == "L": if self.rect.left > 0: # 坦克是否到達左邊界 self.rect.left -= self.speed else: self.live = False elif self.direction == "R": if self.rect.right < TankMain.Width: self.rect.right += self.speed else: self.live = False elif self.direction == "U": if self.rect.top > 0: self.rect.top -= self.speed else: self.live = False elif self.direction == "D": if self.rect.top < TankMain.Height: self.rect.top += self.speed else: self.live = False else: pass # 炮彈擊中坦克:我擊中敵法、敵方擊中我 def hit_tank(self): if self.good: # 如果是我方炮彈 hit_list = pygame.sprite.spritecollide(self, TankMain.enemy_list, True) # 返回發生碰撞的列表 for e in hit_list: e.live = False TankMain.enemy_list.remove(e) self.live = False explode = Explode(self.screem, e.rect) TankMain.explode_list.append(explode) else: # 如果是敵方炮彈 pass class Explode(BaseItem): def __init__(self, screem, rect): super().__init__(screem) self.live = True self.screem = screem self.images = [pygame.image.load('image/explode/0.png'), \ pygame.image.load('image/explode/1.png'), \ pygame.image.load('image/explode/2.png'), \ pygame.image.load('image/explode/3.png'), \ pygame.image.load('image/explode/4.png'), \ pygame.image.load('image/explode/5.png'), \ ] self.step = 0 self.rect = rect # 爆炸的位置和發送爆炸前坦克位置一樣,所以傳入坦克位置 # 循環調用 def display(self): if self.live: if self.step == len(self.images): # 最后一張爆炸圖片已經顯示 self.live = False else: self.image = self.images[self.step] self.screem.blit(self.image, self.rect) self.step += 1 else: pass ''' 牆: 能否被擊毀: 能否穿透 是否存活 草皮: 能穿過、不能擊毀、一直存活 磚牆: 不能闖過、能擊毀、被擊毀則不存活 鐵牆: 不能穿透、不能擊毀、一直存活 ''' class SteelsWall(BaseItem): def __init__(self, screem, left, top): super().__init__(screem) self.live = True # 存活指標 self.via = False # 穿透指標 self.quality = True # 能否被炮彈擊毀,但后來沒用到 self.image = pygame.image.load('image/barrier/steels.png') self.rect = self.image.get_rect() self.rect.left = left # randint(10,500) self.rect.top = top # randint(10,400) def display(self): if self.live: self.screem.blit(self.image, self.rect) else: pass def hit_tank(self): if TankMain.my_tank and (not self.via) and self.live: hit_list1 = pygame.sprite.collide_circle(self, TankMain.my_tank) if hit_list1: TankMain.my_tank.stop = True TankMain.my_tank.stay() # 我方坦克,調用該函數有點小毛病,穿越? else: pass if TankMain.enemy_list and (not self.via) and self.live: hit_list2 = pygame.sprite.spritecollide(self, TankMain.enemy_list, False) for e in hit_list2: e.stop = True e.stay() # 略有問題但不明顯 def hit_missile(self): missile_list = pygame.sprite.Group() for i in TankMain.enemy_missile_list: missile_list.add(i) for j in (TankMain.my_tank_missile): missile_list.add(j) if missile_list and (not self.via) and self.live: hit_list=pygame.sprite.spritecollide(self,missile_list,False) for missile in hit_list: missile.stop=True missile.speed=0 class GrassWall(SteelsWall): def __init__(self, screem, left, top): super().__init__(screem, left, top) self.image = pygame.image.load('image/barrier/grasss.png') self.via = True class BlockWall(SteelsWall): def __init__(self, screem, left, top): super().__init__(screem, left, top) self.image = pygame.image.load('image/barrier/walls.png') self.quality = False self.live = True self.via = False def hit_missile(self): missile_group=pygame.sprite.Group() for i in TankMain.enemy_missile_list: missile_group.add(i) for j in TankMain.my_tank_missile: missile_group.add(j) if missile_group: hit_list=pygame.sprite.spritecollide(self,missile_group,False) if hit_list: self.live=False for i in hit_list: i.speed=0 i.stop=True i.live=False
            ##提取碼:f9lv
if __name__ == '__main__': game = TankMain() game.startGame() game.stopGame()

##完整素材代碼
##鏈接:https://pan.baidu.com/s/1ux3lzD4y9MXSJJH049RCQg

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM