用python的tkinter做游戏(六)—— 坦克大战或射击游戏Demo 篇

这几天终于把类与对象给整明白了,于是做了一个游戏Demo。
根据这个Demo的设计思路,就可以用tkinter来做坦克大战或其它射击类的游戏了。

之前的几篇博文如下:
用python自带的tkinter做游戏(一)—— 贪吃蛇 篇
用python自带的tkinter做游戏(二)—— 俄罗斯方块 篇
用python自带的tkinter做游戏(三)—— 推箱子简易版 篇
用python自带的tkinter做游戏(四)—— 重制版 篇
用python自带的tkinter做游戏(五)—— 魔塔 篇

因为是自学的python,所以代码写的杂乱,现在再回头看看我自己之前敲的代码,实在是不堪入目,尤其是全局变量漫天飞~
从今天开始,要正式规范起来,至少要尽量避免使用全局变量。
所以今天所展示的Demo里,没有申明过一次全局变量,希望高手能给点鼓励,新手也能互勉(本人WX:znix1116)。

在没搞懂类之前,用tkinter做游戏有很多的局限性,主要有以下三点:
一个是操控的路线。人物只能是做十字移动,即人物移动只有四个方向,没法做到同时按下2个方向键让人物做斜线移动。
既然不能同时按下2个按键,引申出来的第二个问题就是无法进行双人游戏。
最后一个就是子弹,满屏幕的子弹都是一个个的对象,不用类的话工作量实在是太大。

今天的Demo将一并解决这三大难题,顺便再展现下tkinter里是如何使用gif文件。

先展现一下本Demo里需要用到的图片素材:
小鸟动图,下载好后改名为x.gif
子弹的图片改名为b.png
两张图片和py文件放在同一个目录下即可。

如果没有图片文件的话代码也可以运行,只不过不显示图片了,只有线框显示。


tkinter并不直接支持gif动图,但可以读取gif里其中的一帧。
通过分解x.gif可以得知这个gif里有七帧图片。
所以只要不断地刷新帧数就可以实现动图效果了,原理还是很简单的。

因为小鸟动图没有反向图,所以这次小鸟的移动,头部始终是面向右边,子弹的动作也是一直从左向右,倒也省力了不少。

因为是个Demo,所以游戏界面简单了些,各种目标对象也懒得找图片了,直接用线框替代了,反正有了坐标等数据,加载图片也容易。

map_data =   [[1, 450, 100, 50, 50, 0, 0],
              [1, 200, 100, 50, 50, 1, 0],
              [1, 500, 300, 50, 50, 1, 1],
              [1, 200, 300, 50, 50, 2, 2],
              [1, 300, 300, 50, 50, 2, 2],
              [1, 400, 300, 50, 50, 2, 2]]
    
# map_data 用于存放游戏地图中各种目标对象的列表
# map_data[i][0] 显示开关,0=隐藏,1=显示
# map_data[i][1] 目标对象的X坐标
# map_data[i][2] 目标对象的Y坐标
# map_data[i][3] 目标对象的宽度
# map_data[i][4] 目标对象的高度
# map_data[i][5] 小鸟与目标对象的属性,0=可穿越,1=限制移动区域,2=可消除(接触后即刻消失)
# map_data[i][6] 子弹对目标对象的属性,0=可穿越,1=抵挡子弹穿越,2=可消除(接触后和子弹一起消失)

map_data就是游戏地图里各种数据,每个目标对象分两种状况,分别对应着小鸟和子弹接触后的效果。
这点就如坦克大战中,河流可以阻挡坦克前进,但子弹却可以穿越。

根据map_data里的数据,所展示的画面如下:
在这里插入图片描述

其中粉色的小方块小鸟和子弹都可以穿越,下面三个绿色的小方块是可以用子弹消除的,被小鸟接触到也会消除。
上方的黑色方块小鸟不可穿越,但子弹可以。
下方的黑色方块小鸟和子弹都不可以。

因为是Demo,所以P1和P2都用了相同的图片,用了不同颜色线框来区分。
当然了,线框觉得碍眼的话可以在设置里去除。

现在再来说说控制的按键。
先看下按键的设置,放在一个字典中:

self.pressed_dict     = {}               # 记录按键情况
self.key_set =  [  'w',   's',   'a',    'd',      # 1P 方向控制键
                  'Up','Down','Left','Right',      # 2P 方向控制键
                  'j' ,'0']                        # 1P,2P 射击按键

因为就2只小鸟,也不高兴用类了,放一起设置了。
如果是正式游戏的话,还是需要用类的,毕竟还有敌机或敌方坦克。

记录下每个按键的情况,按下时为True,弹起后为False。

    def set_bindings(self):
        
        def pressed_key(event):
            self.pressed_dict[event.keysym] = True
        def released_key(event):
            self.pressed_dict[event.keysym] = False
        
        for x in self.key_set:
            self.window.bind("<KeyPress-"   + str(x) + ">",  pressed_key )
            self.window.bind("<KeyRelease-" + str(x) + ">",  released_key)
            self.pressed_dict[x] = False

根据每个按键的状态,就可以实现同时按键了。

一般射击游戏控制路线是自由飞行的。
但坦克大战这类的游戏是只能做十字路线移动,即只有上下左右四个方向可行动。
也就说,只要是按了其中某一个方向键,那其它三个方向的按键则是无效的。
所以解决的方法也很简单,当按下某一个方向键时,使其它三个方向键的移动系数改为0即可(原本系数为1,可移动)。

最后展示一下完整的代码(本人WX:znix1116,欢迎交流):

2022.03.25更新:
修复了出错报警的BUG

还发布了坦克大战Demo的升级版:
用python的tkinter做游戏(七)—— 双人射击游戏Demo(类的应用) 篇

2022.04.07
坦克大战的正式版来啦~
用python的tkinter做游戏(九)—— 坦克大战 正式篇

# -*- coding: utf-8 -*-
"""
Created on Sun Mar  6 10:51:17 2022

@author: znix
"""

import tkinter as tk


map_data =   [[1, 450, 100, 50, 50, 0, 0],
              [1, 200, 100, 50, 50, 1, 0],
              [1, 500, 300, 50, 50, 1, 1],
              [1, 200, 300, 50, 50, 2, 2],
              [1, 300, 300, 50, 50, 2, 2],
              [1, 400, 300, 50, 50, 2, 2]]
    
# map_data 用于存放游戏地图中各种目标对象的列表
# map_data[i][0] 显示开关,0=隐藏,1=显示
# map_data[i][1] 目标对象的X坐标
# map_data[i][2] 目标对象的Y坐标
# map_data[i][3] 目标对象的宽度
# map_data[i][4] 目标对象的高度
# map_data[i][5] 小鸟与目标对象的属性,0=可穿越,1=限制移动区域,2=可消除(接触后即刻消失)
# map_data[i][6] 子弹对目标对象的属性,0=可穿越,1=抵挡子弹穿越,2=可消除(接触后和子弹一起消失)



class Bullet():
    """ 子弹类 """
    bullet_list1   = []     # P1子弹列表
    bullet_list2   = []     # P2子弹列表
    
    aloop = None
    bloop = None
    gloop = None
    
    def __init__(self, point_x, point_y):
        
        Flying_bird.bullet1_num    += 1                             # 统计屏幕中1P的子弹数量
        Flying_bird.bullet2_num    += 1                             # 统计屏幕中2P的子弹数量
        
        self.tag1           = 'b' + str(Flying_bird.bullet1_num)    # 每颗子弹的标签
        self.tag2           = 'b' + str(Flying_bird.bullet2_num)    # 每颗子弹的标签
        
        self.bullet_img     =  None
        self.bullet_pic     = 'b.png'
        
        self.width          = 20
        self.height         = 20
        self.point_x        = point_x
        self.point_y        = point_y
        self.move_x         = 20
        self.move_y         = 0
        
        
    def move(self):
        if self.point_x > Flying_bird.win_w:
            return False       # 子弹大于屏幕最右边则返回False
        else:
            self.point_x += self.move_x
            self.point_y += self.move_y
    
    
    
    
class Flying_bird():
    
    window        = tk.Tk()
    win_w         = 640
    win_h         = 480
    
    bullet1_num   = 0      # 屏幕里1P子弹的数量
    bullet2_num   = 0      # 屏幕里2P子弹的数量
    
    canvas        = None
    image_bird1   = None
    image_bird2   = None
    
    gif_index     = 0  # GIF文件的帧数
    
    def __init__(self):
        """ """
        self.title            = 'Flying Bird'
        
        self.cross_fly        = False            # 移动模式:True = 十字移动 False = 自由移动
        self.coupe_play       = True             # 是否双人模式
        self.show_lines       = True             # 是否显示线框
        
        self.x_axis1          = 150              # 1P X坐标
        self.y_axis1          = 200              # 1P Y坐标
        self.x_axis2          = 350              # 2P X坐标
        self.y_axis2          = 220              # 2P Y坐标
        
        self.fly_FPS          = 9                # FPS值
        self.move_space       = 2                # 移动间距
        
        self.bird_pic         = 'x.gif'          # 小鸟图片地址
        
        self.max_gif_index    = 7                # 小鸟GIF的总帧数
        self.brid_widch       = 79               # 小鸟身宽
        self.brid_height      = 73               # 小鸟身高
        self.x_adjust         = 6                # X轴偏差调整
        self.y_adjust         = 5                # Y轴偏差调整
        
        self.bullet_FPS       = 500              # 子弹FPS
        
        self.pressed_dict     = {}               # 记录按键情况
        self.key_set = [  'w',   's',   'a',    'd',      # 1P 方向控制键
                         'Up','Down','Left','Right',      # 2P 方向控制键
                         'j' ,'0']                        # 1P,2P 射击按键
        
        self.color_dic = {0:         'pink',
                          1:        'black',
                          2:    'palegreen',
                          3:          'red',
                          4:         'blue' }   
        
        if self.coupe_play == False:
            self.x_axis2          = -300
            self.y_axis2          = -150
        
        self.FPS             = 80                # 翅膀拍打速度(单位毫秒)
        self.canvas_bg       = 'white'           # 游戏背景色
        
        self.run_game()
        
    
    
    def sprite_collide(self,x,y,a,b,x1,y1,f,g):
        """ 
        判断2个矩形是否相交
        x ,y ,a,b = 矩形1的xy坐标,a,b为长宽
        x1,y1,f,g = 矩形2的xy坐标,f,g为长宽
        """
                
        x0 =  x + a    # 矩形1最右端的坐标
        y0 =  y + b    # 矩形1最底端的坐标
        x2 = x1 + f    # 矩形2最右端的坐标
        y2 = y1 + g    # 矩形2最底端的坐标
                
        if x0 > x1 and x < x2 and y0 > y1 and y < y2:
            return True
        else:
            return False
    
    
        
    def draw_block_range(self,a,b,w,h,n):
        """ 绘制目标对象的线框 """
        color = self.color_dic[n]
        c = a + w
        d = b + h
        self.canvas.create_rectangle(a,b,c,d,fill='',outline = color)
        self.canvas.create_line(a,b,c,d,fill = color)
        self.canvas.create_line(c,b,a,d,fill = color)
    
    
    def draw_all_object(self):
        """ 绘制所有对象的线框 """
        n = len(map_data)
        for i in range(0,n):
            if map_data[i][0] == 1:
                self.draw_block_range(map_data[i][1],map_data[i][2],
                                    map_data[i][3],map_data[i][4],
                                    map_data[i][5])
                
    
    def bird_gif(self):
        """ Bird的动画效果 a=gif帧数 """
        try:
            self.gif_index += 1
            if self.gif_index > self.max_gif_index:
                self.gif_index = 0
        
            gif_format = "gif -index " + str(self.gif_index) + ""
            self.image_bird1 = tk.PhotoImage(file = self.bird_pic, format = gif_format)
            self.image_bird2 = tk.PhotoImage(file = self.bird_pic, format = gif_format)
        
            self.canvas.create_image(self.x_axis1 - self.x_adjust, 
                                     self.y_axis1 - self.y_adjust, 
                                     anchor='nw', image = self.image_bird1)
        
            if self.coupe_play == True:
                self.canvas.create_image(self.x_axis2 - self.x_adjust, 
                                         self.y_axis2 - self.y_adjust, 
                                         anchor='nw', image = self.image_bird2)
        except:
            pass
    
    
    def create_bullet_list(self,x):
        """ 生成子弹列表 """
        if x == 1:
            blt1 = Bullet(self.x_axis1 + self.brid_widch, 
                          self.y_axis1 + self.brid_height//2 - 10)
            Bullet.bullet_list1.append(blt1)
        else:
            blt2= Bullet(self.x_axis2 + self.brid_widch, 
                         self.y_axis2 + self.brid_height//2 - 10)
            Bullet.bullet_list2.append(blt2)
        
    
    def bullet_run(self):
        """ 子弹运行 """
        if len(Bullet.bullet_list1) == 0:
            pass
        
        else:
            new_bullet_list1 = []
            
            for k in Bullet.bullet_list1:
                
                try:
                    
                    k.bullet_img = tk.PhotoImage(file = k.bullet_pic)
                    self.canvas.create_image(k.point_x, k.point_y, anchor='nw', 
                                             image = k.bullet_img, tags = k.tag1)
                except:
                    pass
                
                if k.move() == False:
                    self.canvas.delete(k.tag1)
                else:
                    new_bullet_list1.append(k)
                    
            Bullet.bullet_list1 = new_bullet_list1
        
        
        if len(Bullet.bullet_list2) == 0:
            pass
        else:
            new_bullet_list2 = []
            
            for v in Bullet.bullet_list2:
                
                try:
                    v.bullet_img = tk.PhotoImage(file = v.bullet_pic)
                    self.canvas.create_image(v.point_x, v.point_y, anchor='nw', 
                                             image = v.bullet_img, tags = v.tag2)
                except:
                    pass
                
                if v.move() == False:
                    self.canvas.delete(v.tag2)
                else:
                    new_bullet_list2.append(v)
                    
            Bullet.bullet_list2 = new_bullet_list2
    
    
    
    def action_after_bullets_hit_objects(self):
        """ 子弹接触目标后的动作 """
        
        n = len(map_data)
        
        if len(Bullet.bullet_list1) == 0:
            pass
        else:
            for i in range(0,n):
              if map_data[i][0] == 1:
                 for k in Bullet.bullet_list1:
                    x  = k.point_x
                    y  = k.point_y
                    a  = k.width
                    b  = k.height
                    x1 = map_data[i][1] + a
                    y1 = map_data[i][2]
                    f  = map_data[i][3]
                    g  = map_data[i][4]
                    
                    if self.sprite_collide(x,y,a,b,x1,y1,f,g) == True:
                        if map_data[i][6] == 1:
                            k.point_x = self.win_w + 100
                            self.canvas.delete(k.tag1)
                        if map_data[i][6] == 2:
                            self.canvas.delete(k.tag1)
                            k.point_x = self.win_w + 100
                            map_data[i][0] = 0
        
        
        if len(Bullet.bullet_list2) == 0:
            pass
        else:
            for i in range(0,n):
              if map_data[i][0] == 1:
                 for k in Bullet.bullet_list2:
                    x  = k.point_x
                    y  = k.point_y
                    a  = k.width
                    b  = k.height
                    x1 = map_data[i][1] + a
                    y1 = map_data[i][2]
                    f  = map_data[i][3]
                    g  = map_data[i][4]
                    
                    if self.sprite_collide(x,y,a,b,x1,y1,f,g) == True:
                        if map_data[i][6] == 1:
                            k.point_x = self.win_w + 100
                            self.canvas.delete(k.tag2)
                        if map_data[i][6] == 2:
                            k.point_x = self.win_w + 100
                            self.canvas.delete(k.tag2)
                            map_data[i][0] = 0
    
    
    def action_after_bullets_hit_player(self):
        """ 子弹接触目标后的动作 """
        n = len(map_data)
        
        if len(Bullet.bullet_list1) == 0:
            pass
        else:
            for i in range(0,n):
              if map_data[i][0] == 1:
                 for k in Bullet.bullet_list1:
                    x  = k.point_x
                    y  = k.point_y
                    a  = k.width
                    b  = k.height
                    x1 = self.x_axis2  + a
                    y1 = self.y_axis2
                    f  = self.brid_widch
                    g  = self.brid_height
                    
                    if self.sprite_collide(x,y,a,b,x1,y1,f,g) == True:
                          k.point_x = self.win_w + 100
                          self.canvas.delete(k.tag1)
        
        if len(Bullet.bullet_list2) == 0:
            pass
        else:
            for i in range(0,n):
              if map_data[i][0] == 1:
                 for k in Bullet.bullet_list2:
                    x  = k.point_x
                    y  = k.point_y
                    a  = k.width
                    b  = k.height
                    x1 = self.x_axis1  + a
                    y1 = self.y_axis1
                    f  = self.brid_widch
                    g  = self.brid_height
                    
                    if self.sprite_collide(x,y,a,b,x1,y1,f,g) == True:
                          k.point_x = self.win_w + 100
                          self.canvas.delete(k.tag2)
     
    
    def control_key(self):
        """ 按键控制 """
           
        def move_flyer():
            
            move_key = [[1,0,0,0,0,0,0,0],[0,1,0,0,0,0,0,0],[0,0,1,0,0,0,0,0],[0,0,0,1,0,0,0,0],
                        [0,0,0,0,1,0,0,0],[0,0,0,0,0,1,0,0],[0,0,0,0,0,0,1,0],[0,0,0,0,0,0,0,1]]
            
            # move_key = P1和P2的方向键,共八个键。=0 不可移动; =1 可移动
            
            y1 = self.y_axis1 
            x1 = self.x_axis1 
            y2 = self.y_axis2 
            x2 = self.x_axis2 
            
            s = self.move_space
            bw = self.brid_widch  - self.x_adjust
            bh = self.brid_height - self.x_adjust
            
            cc = [[   x1,  y1-s, bw,   s,  x2, y2, bw, bh],
                  [   x1, y1+bh, bw,   s,  x2, y2, bw, bh],
                  [ x1-s,    y1,  s,  bh,  x2, y2, bw, bh],
                  [x1+bw,    y1,  s,  bh,  x2, y2, bw, bh],
                  
                  [    x2,  y2-s, bw,  s,  x1, y1, bw, bh],
                  [    x2, y2+bh, bw,  s,  x1, y1, bw, bh],
                  [  x2-s,    y2,  s, bh,  x1, y1, bw, bh],
                  [ x2+bw,    y2,  s, bh,  x1, y1, bw, bh]]
            

            collide = { 0 : self.sprite_collide(cc[0][0],cc[0][1],cc[0][2],cc[0][3], 
                                                cc[0][4],cc[0][5],cc[0][6],cc[0][7]),
                        1 : self.sprite_collide(cc[1][0],cc[1][1],cc[1][2],cc[1][3], 
                                                cc[1][4],cc[1][5],cc[1][6],cc[1][7]),
                        2 : self.sprite_collide(cc[2][0],cc[2][1],cc[2][2],cc[2][3], 
                                                cc[2][4],cc[2][5],cc[2][6],cc[2][7]),
                        3 : self.sprite_collide(cc[3][0],cc[3][1],cc[3][2],cc[3][3], 
                                                cc[3][4],cc[3][5],cc[3][6],cc[3][7]),
                       
                        4 : self.sprite_collide(cc[4][0],cc[4][1],cc[4][2],cc[4][3], 
                                                cc[4][4],cc[4][5],cc[4][6],cc[4][7]),
                        5 : self.sprite_collide(cc[5][0],cc[5][1],cc[5][2],cc[5][3], 
                                                cc[5][4],cc[5][5],cc[5][6],cc[5][7]),
                        6 : self.sprite_collide(cc[6][0],cc[6][1],cc[6][2],cc[6][3], 
                                                cc[6][4],cc[6][5],cc[6][6],cc[6][7]),
                        7 : self.sprite_collide(cc[7][0],cc[7][1],cc[7][2],cc[7][3], 
                                                cc[7][4],cc[7][5],cc[7][6],cc[7][7])}
            
            coll = {   0 : False,  1 : False,  2 : False,  3 : False,
                       4 : False,  5 : False,  6 : False,  7 : False  }
            
            
            def action_after_touch():
                """ 小鸟接触目标对象后的动作 """
                
                def get_attribute_in_map_data(i,j):
                    """ 获取小鸟接触目标对象的属性 """
                    if map_data[i][0] == 1:
                      if self.sprite_collide( cc[j][0], cc[j][1],
                                              cc[j][2], cc[j][3],
                                    map_data[i][1],map_data[i][2],
                                    map_data[i][3],map_data[i][4]) == True:
                          return map_data[i][5]
                
                
                n = len(map_data)
                for i in range(0,n):
                    for j in range(0,8):
                        if get_attribute_in_map_data(i,j) == 1:
                           coll[j] = True
                        elif get_attribute_in_map_data(i,j) == 2:
                            map_data[i][0] = 0
            
            
            def limit_bird_move():
                """ 1P,2P限制移动 """
                
                def contrast(a,b,c=0):
                    """ 对比a,b两个值的大小。c=0时代表a大于b,否则a大于等于b """
                    if c == 0:
                        if a > b:
                            return True
                        else:
                            return False
                    else:
                        if a >= b:
                            return True
                        else:
                            return False
                
                
                w = self.win_w
                h = self.win_h
                
                con = [[0, y1-s],[y1+bh+s, h],[0, x1-s],[x1+bw+s, w],
                       [0, y2-s],[y2+bh+s, h],[0, x2-s],[x2+bw+s, w]]
                
                
                def move_fly():
                    for i in range(0,8):
                        if contrast(con[i][0],con[i][1]) == True:
                            move_key[i][i] = 0
                        elif collide[i] == True:
                            move_key[i][i] = 0
                        elif coll[i] == True:
                            move_key[i][i] = 0
                        else:
                           move_key[i][i] = 1
                           
                    
                move_fly()
                
            
            def only_cross_fly():
                """ 仅十字路线移动 """
                dic = {   0: [1,2,3],
                          1: [0,2,3],
                          2: [0,1,3],
                          3: [0,1,2],
                          
                          4: [5,6,7],
                          5: [4,6,7],
                          6: [4,5,7],
                          7: [4,5,6] }
                
                def move_dic(x):
                    move_key[dic[x][0]] = [0,0,0,0,0,0,0,0]
                    move_key[dic[x][1]] = [0,0,0,0,0,0,0,0]
                    move_key[dic[x][2]] = [0,0,0,0,0,0,0,0]
                    
                if   self.pressed_dict[self.key_set[0]] == True: 
                    move_dic(0)
                elif self.pressed_dict[self.key_set[1]] == True: 
                    move_dic(1)
                elif self.pressed_dict[self.key_set[2]] == True: 
                    move_dic(2)
                elif self.pressed_dict[self.key_set[3]] == True: 
                    move_dic(3)
                
                if   self.pressed_dict[self.key_set[4]] == True: 
                    move_dic(4)
                elif self.pressed_dict[self.key_set[5]] == True: 
                    move_dic(5)
                elif self.pressed_dict[self.key_set[6]] == True: 
                    move_dic(6)
                elif self.pressed_dict[self.key_set[7]] == True: 
                    move_dic(7)
                    
            
            def move_bird_final():
                
                def move_bird(n,up,down,left,right):
                    """ Bird1 & Bird2 移动 """
                    if n == 1:
                        self.y_axis1 -= up
                        self.y_axis1 += down
                        self.x_axis1 -= left
                        self.x_axis1 += right
                    else:
                        if self.coupe_play == True:
                            self.y_axis2 -= up
                            self.y_axis2 += down
                            self.x_axis2 -= left
                            self.x_axis2 += right
                
                for n in range(1,3):
                  for i in range(0,8):
                    x = self.move_space
                    if n == 1:
                        a = move_key[i][0]
                        b = move_key[i][1]
                        c = move_key[i][2]
                        d = move_key[i][3]
                    else:
                        a = move_key[i][4]
                        b = move_key[i][5]
                        c = move_key[i][6]
                        d = move_key[i][7]
                    
                    if self.pressed_dict[self.key_set[i]] == True:
                        move_bird(n,x*a,x*b,x*c,x*d)
                        
            
            action_after_touch()
            limit_bird_move()
            
            if self.cross_fly == True:
                only_cross_fly()
            
            move_bird_final()
             
        move_flyer()
        self.aloop = self.window.after(self.fly_FPS, self.control_key)

    
    def set_bindings(self):
        
        def pressed_key(event):
            self.pressed_dict[event.keysym] = True
        def released_key(event):
            self.pressed_dict[event.keysym] = False
        
        for x in self.key_set:
            self.window.bind("<KeyPress-"   + str(x) + ">",  pressed_key )
            self.window.bind("<KeyRelease-" + str(x) + ">",  released_key)
            self.pressed_dict[x] = False
            
    
    def bullet_loop(self):
        
        if self.pressed_dict[self.key_set[8]] == True:
            self.create_bullet_list(1)
            
        if self.pressed_dict[self.key_set[9]] == True:
            self.create_bullet_list(2)
            
        self.bloop = self.window.after(self.bullet_FPS, self.bullet_loop)
        
        
    def game_loop(self):
        """ 游戏循环刷新 """
        
        self.canvas.delete('all')
        
        self.draw_in_win()
        self.bird_gif()
        self.draw_all_object()
        self.bullet_run()
        self.action_after_bullets_hit_objects()
        self.action_after_bullets_hit_player()
        self.gloop = self.window.after(self.FPS, self.game_loop)
        
        
    def draw_in_win(self):
        """ 显示小鸟和子弹的线框 """
        def draw_brid_range(n,color):
            """ 显示小鸟的外框 """
            if n == 1:
                a = self.x_axis1 
                b = self.y_axis1 
            else:
                a = self.x_axis2
                b = self.y_axis2
        
            w = self.brid_widch  - self.x_adjust
            h = self.brid_height - self.y_adjust
            c = a + w
            d = b + h
        
            self.canvas.create_rectangle(a,b,c,d,fill='',outline = color)
            self.canvas.create_line(a,b,c,d,fill = color)
            self.canvas.create_line(c,b,a,d,fill = color)
        
        
        def draw_bullet_range(m,n):
            """ 显示子弹的外框 """
            if len(Bullet.bullet_list1) == 0:
                pass
            else:
                for k in Bullet.bullet_list1:
                    a = k.point_x
                    b = k.point_y
                    w = k.width
                    h = k.height
                    self.draw_block_range(a,b,w,h,m)
                
            if len(Bullet.bullet_list2) == 0:
                pass
            else:
                for k in Bullet.bullet_list2:
                    a = k.point_x
                    b = k.point_y
                    w = k.width
                    h = k.height
                    self.draw_block_range(a,b,w,h,n)
        
        if self.show_lines == True:
            draw_brid_range(1,'red')
            draw_brid_range(2,'blue')
            draw_bullet_range(3,4)

        
    def run_game(self):
        """ 开启游戏 """
        def window_center(window,w_size,h_size):
            """ 窗口居中 """
            screenWidth  =  window.winfo_screenwidth()  # 获取显示区域的宽度
            screenHeight = window.winfo_screenheight()  # 获取显示区域的高度
            left =  (screenWidth - w_size) // 2
            top  = (screenHeight - h_size) // 2
            window.geometry("%dx%d+%d+%d" % (w_size, h_size, left, top))
            
            
        def create_canvas():
            """ 创建画布 """
            self.canvas = tk.Canvas(self.window,    bg = self.canvas_bg, 
                                       height = self.win_h,
                                        width = self.win_w,
                           highlightthickness = 0)
        
            self.canvas.place(x=0,y=0)
        
        
        self.window.focus_force() # 主窗口焦点
        self.window.title(self.title)
        window_center(self.window,self.win_w,self.win_h)
        create_canvas()
        self.set_bindings()
        self.game_loop()
        self.control_key()
        self.bullet_loop()
        
        def close_w():
            self.window.after_cancel(self.gloop)
            self.window.after_cancel(self.aloop)
            self.window.after_cancel(self.bloop)
            self.window.destroy()
            
        self.window.protocol('WM_DELETE_WINDOW', close_w)
        
        self.window.mainloop()
        

if __name__ == '__main__':
    
    Flying_bird()
  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值