pygame小游戲之坦克大戰


以前在學校的時候無聊的學了會pygame。看了大概一周的教學視頻,做出來個坦克大戰的小游戲

Python3.5  pycharm 

 

import pygame,sys,time
from random import randint
from pygame.locals import *
class TankMain():
    #開始游戲
    width=600
    height=500
    my_tank_missile_list = []
    my_tank = None
    wall=None
    # 創建一個我方坦克
    #enemy_list = []
    enemy_list=pygame.sprite.Group() #敵方坦克的族群
    explode_list =[]
    #敵方坦克的炮彈
    enemy_missile_list=pygame.sprite.Group()

    def startGame(self):
        pygame.init()#pygame
        #創建一個屏幕,屏幕的大小,寬和高,0為固定大小(0,RESIZEBLE,FULLSCREEN
        screem=pygame.display.set_mode((TankMain.width,TankMain.height),0,32)
        pygame.display.set_caption("坦克大戰")

        TankMain.wall=Wall(screem,60,75,30,120)#創建一個牆

        TankMain.my_tank = My_Tank(screem)
        if len(TankMain.enemy_list)==0:
            for i in range(1,6): #敵方坦克隨機數
                TankMain.enemy_list.add(Enemy_Tank(screem))#把敵方坦克放到組里
        while True:
           if len(TankMain.enemy_list)<5:
                TankMain.enemy_list.add(Enemy_Tank(screem))  # 把敵方坦克放到組里


        #color RGB(0,100,200)
        #設置屏幕背景色為黑色
           screem.fill((0,0,0))
           TankMain.wall.display()
           TankMain.wall.hit_other()#碰撞檢測並且顯示牆
        # 顯示左上角的文字
           for i,text in enumerate (self.write_text(),0):
               screem.blit(text,(0,5+(13*i)))#縱x橫y
           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
               #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_list:
               if m.live:
                  m.display()
                  m.hit_tank()#炮彈打中敵方坦克
                  m.move()
               else:
                   TankMain.my_tank_missile_list.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.05)#可以調坦克的速度,越小,速度越快
           pygame.display.update()
        #獲取所有的事件(敲擊鍵盤,鼠標點擊 都屬於事件)
    def get_event(self,my_tank,screem):
        for event in pygame.event.get():
            if event.type==QUIT: #程序退出
                self.stopGame()
            if event.type==KEYDOWN and (not my_tank)and event.key==K_n:
                TankMain.my_tank=My_Tank(screem)
            if event.type==KEYDOWN and my_tank:
                if event.key==K_LEFT:
                    my_tank.direction="L"  #左移
                    my_tank.stop=False
                    #my_tank.move()
                if event.key==K_RIGHT:
                    my_tank.direction="R"  #右邊移動
                    my_tank.stop = False
                    #my_tank.move()
                if event.key==K_UP:
                    my_tank.direction="U"  #上移
                    my_tank.stop = False
                    #my_tank.move()
                if event.key==K_DOWN:
                    my_tank.direction="D"  #下移
                    my_tank.stop = False
                    #my_tank.move()
                if event.key==K_ESCAPE:    #esc退出
                    self.stopGame()
                if event.key==K_SPACE:     #發射炮彈
                    m=my_tank.fire()
                    m.good=True     #我方坦克發射的炮彈
                    TankMain.my_tank_missile_list.append(m)
            if event.type==KEYUP and my_tank:
                if event.key==K_LEFT or event.key==K_RIGHT or event.key==K_DOWN or  event.key==K_UP:
                    my_tank.stop=True

    #停止游戲
    def stopGame(self):
        sys.exit()
    # 在屏幕左上角顯示文字
    def write_text(self):
        font=pygame.font.SysFont("simsunnsimsun",15) #定義一個字體
        text_sf1=font.render("enemy tank:%d"%len(TankMain.enemy_list),True,(255,0,0)) #根據字體創建一個文件的圖像
        text_sf2=font.render("my tank missile:%d" % len(TankMain.my_tank_missile_list), True, (255, 0, 0))
        return text_sf1,text_sf2

#坦克大戰中所有對象的父類
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=35
    height=35
    def __init__(self,screem,left,top):
        super(Tank, self).__init__(screem)
        #self.screem=screem#坦克在移動過程中需要用到屏幕
        self.direction="D" #坦克的方向,默認向下
        self.speed=5 #坦克移動速度
        self.stop=False
        self.images={} #坦克的所有圖片,key 方向 value 圖片(suface)
        self.images["L"]=pygame.image.load("images/tankL.gif")
        self.images["R"]=pygame.image.load("images/tankR.gif")
        self.images["U"]=pygame.image.load("images/tankU.gif")
        self.images["D"]=pygame.image.load("images/tankD.gif")
        self.image=self.images[self.direction] #坦克的圖片由方向決定
        self.rect=self.image.get_rect()
        self.rect.left=left
        self.rect.top=top
        self.live=True #決定坦克生死
        self.oldleft=self.rect.left
        self.oldtop=self.rect.top

    def stay(self):
        self.rect.top=self.oldtop
        self.rect.left=self.oldleft

    def move(self):
        if not self.stop:  # 如果坦克不是停止狀態
            self.oldleft=self.rect.left
            self.oldtop=self.rect.top
            if self.direction == "L":  # 如果坦克的方向向左,那么只需要改坦克的left就ok了。left在減小
                if self.rect.left > 0:  # 判斷坦克是否在屏幕左邊的邊界上
                        self.rect.left -= self.speed
                else:
                        self.rect.left = 0
            elif self.direction == "R":  # 如果坦克方向向右,坦克的right增加就ok了。
                if self.rect.right < TankMain.width:  # 坦克已經在屏幕的最右邊的話就不能往右移動了
                        self.rect.right += self.speed
                else:
                        self.rect.right = TankMain.width
            elif self.direction == "D":  # 如果坦克方向向下,坦克的bottom增加就ok了。
                if self.rect.bottom < TankMain.height:
                    self.rect.top += self.speed
                else:
                        self.rect.bottom = TankMain.height
            elif self.direction == "U":  # 如果坦克方向向上,坦克的top減小就ok了。
                if self.rect.top > 0:
                        self.rect.top -= self.speed
                else:
                        self.rect.top = 0
    def fire(self):
        m = Missile(self.screem,self)
        return m

class My_Tank(Tank):
    def __init__(self,screem):
        super(My_Tank, self).__init__(screem,275,400)#創建一個我方坦克,坦克顯示在屏幕的中下部位置
        self.stop=True
        self.live=True

    def hit_enemy_missile(self):
        hit_list=pygame.sprite.spritecollide(self,TankMain.enemy_missile_list,False)
        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(Enemy_Tank, self).__init__(screem,randint(1,5)*100,200)
        self.speed=4
        self.step=8 #坦克在一個方向移動6步
        self.get_random_direction()

    def get_random_direction(self):
        r = randint(0, 4)  # 得到一個坦克移動方向和停止的隨機數
        if r == 4:
            self.stop = True
        elif r == 0:
            self.direction = "L"
            self.stop=False
        elif r == 1:
            self.direction = "R"
            self.stop=False
        elif r == 2:
            self.direction = "U"
            self.stop=False
        elif r == 3:
            self.direction = "D"
            self.stop=False
      #敵方坦克移動6步后,在隨機換方向接着移動
    def random_move(self):
        if self.live:
            if self.step==0:
                self.get_random_direction()
                self.step=6
            else:
                self.move()
                self.step-=1
    def random_fire(self):
        r=randint(0,50)
        if r==10 or r==25 :
            m=self.fire()
            TankMain.enemy_missile_list.add(m)
        else:
            return


class Missile(BaseItem):
     width=12
     height=12
     def __init__(self,screem,tank):
         super(Missile, self).__init__(screem)
         self.tank=tank
         self.direction = tank.direction  # 炮彈的方向由所發射的坦克決定
         self.speed = 12  # 炮彈移動速度
         self.images = {}  # 炮彈的所有圖片,key 方向 value 圖片(suface)
         self.images["L"] = pygame.image.load("images/bulletL.gif")
         self.images["R"] = pygame.image.load("images/bulletR.gif")
         self.images["U"] = pygame.image.load("images/bulletU.gif")
         self.images["D"] = pygame.image.load("images/bulletD.gif")
         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.food=False

     def move(self):
         if self.live:  # 如果炮彈活着
             if self.direction == "L":  # 如果坦克的方向向左,那么只需要改坦克的left就ok了。left在減小
                 if self.rect.left > 0:  # 判斷坦克是否在屏幕左邊的邊界上
                     self.rect.left -= self.speed
                 else:
                     self.live = False
             elif self.direction == "R":  # 如果坦克方向向右,坦克的right增加就ok了。
                 if self.rect.right < TankMain.width:  # 坦克已經在屏幕的最右邊的話就不能往右移動了
                     self.rect.right += self.speed
                 else:
                     self.live = False
             elif self.direction == "D":  # 如果坦克方向向下,坦克的bottom增加就ok了。
                 if self.rect.bottom < TankMain.height:
                     self.rect.top += self.speed
                 else:
                     self.live = False
             elif self.direction == "U":  # 如果坦克方向向上,坦克的top減小就ok了。
                 if self.rect.top > 0:
                     self.rect.top -= self.speed
                 else:
                     self.live = False
     #炮彈擊中坦克,1我方坦克擊中敵方坦克,敵方坦克擊中我方坦克
     def hit_tank(self):
         if self.good:#我方炮彈
             hit_list =pygame.sprite.spritecollide(self,TankMain.enemy_list,False)
             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)




#爆炸類
class Explode(BaseItem):
    
    def __init__(self,screem,rect):
        super(Explode, self).__init__(screem)
        self.live=True
        self.images=[pygame.image.load("images/0.gif"),\
                     pygame.image.load("images/1.gif"),\
                     pygame.image.load("images/2.gif"),\
                     pygame.image.load("images/3.gif"),\
                     pygame.image.load("images/4.gif"),\
                     pygame.image.load("images/5.gif"),\
                     pygame.image.load("images/6.gif"),\
                     pygame.image.load("images/7.gif"),\
                     pygame.image.load("images/8.gif"),\
                     pygame.image.load("images/9.gif"),\
                     pygame.image.load("images/10.gif"),] #爆炸效果的圖片
        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  Wall(BaseItem):
    def __init__(self,screem,left,top,width,height):
        super(Wall, self).__init__(screem)
        self.rect=Rect(left,top,width,height)#牆的高度
        self.color=(255,142,0) #牆的顏色
    def display(self):
        self.screem.fill(self.color,self.rect)

    def hit_other(self):#檢測牆與其他的碰撞
        if TankMain.my_tank:
            is_hit =pygame.sprite.collide_rect(self,TankMain.my_tank)
            if is_hit:
                TankMain.my_tank.stop=True
                TankMain.my_tank.stay()
            if len(TankMain.enemy_list)!=0:
                hit_list  =pygame.sprite.spritecollide(self,TankMain.enemy_list,False)
                for e in hit_list:
                    e.stop=True
                    e.stay()

game =TankMain()
game.startGame()

 

運行結果,,

 

有想學習pygame的小伙伴可以參考參考!!


免責聲明!

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



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