wxPython扫雷

运行效果图
在这里插入图片描述

mport wx
from random import randint

class MineFrame(wx.Frame):
    def __init__(self):
        # 设置窗口为固定大小
        wx.Frame.__init__(self,None,-1,'扫雷',size=(515,503),
                          style=wx.SYSTEM_MENU | wx.MINIMIZE_BOX | wx.CLOSE_BOX | wx.CAPTION)
        self.time_count = 0  # 初始化计时为0
        self.mine_last = 100  # 初始化雷数为100
        self.get_mine_set()# 获取雷的索引集合
        self.get_info_set()# 获取提示信息(索引和雷数)集合
        self.del_index_set = set()  # 存储被删除的按钮索引
        self.get_bmp_list()  # 获取位图对象列表
        self.SetIcon(wx.Icon(self.bmp_list[9]))# 设置标题图标
        self.create_menu()  # 生成菜单栏
        self.create_panel()# 生成画板
        self.create_timer()# 生成计时器
        self.create_text_info()# 生成提示信息(雷数和时间)
        self.create_state_btn()# 生成状态按钮
        self.create_btn_list()# 生成所有按钮

    # 菜单栏事件
    def e_menu_new(self, e):
        pass
    def e_menu_level1(self, e):
        pass
    def e_menu_level2(self, e):
        pass
    def e_menu_level3(self, e):
        pass
    def e_menu_custom(self, e):
        pass
    def e_menu_mark(self, e):
        pass
    def e_menu_color(self, e):
        pass
    def e_menu_sound(self, e):
        pass
    def e_menu_list(self, e):
        pass
    def e_menu_exit(self, e):
        pass
    def e_menu_catalogue(self, e):
        pass
    def e_menu_search(self, e):
        pass
    def e_menu_help(self, e):
        pass
    def e_menu_about(self, e):
        pass

    def create_menu(self):
        menu_bar = wx.MenuBar()# 创建菜单栏
        # 游戏菜单
        gm_menu = wx.Menu()# 创建一个菜单对象
        new = gm_menu.Append(-1,"开局(N)\tF2")# 将子菜单加入到菜单对象中
        gm_menu.AppendSeparator()  # 插入一条分割线
        level1 = gm_menu.Append(-1,"初级(B)")
        level2 = gm_menu.Append(-1,"中级(I)")
        level3 = gm_menu.Append(-1,"高级(E)")
        custom = gm_menu.Append(-1, "自定义(C)...")
        gm_menu.AppendSeparator()# 插入一条分割线
        mark = gm_menu.Append(-1,"标记(?)(M)")
        color = gm_menu.Append(-1,"颜色(L)")
        sound = gm_menu.Append(-1,"声音(S)")
        gm_menu.AppendSeparator()
        rs_list = gm_menu.Append(-1, "扫雷英雄榜(T)...")
        exit_gm = gm_menu.Append(-1, "退出(X)")
        menu_bar.Append(gm_menu,"游戏(&G)")# 将File菜单添加到菜单栏
        # 帮助菜单
        self.help_menu = wx.Menu()
        catalogue = self.help_menu.Append(2,"目录(C)\tF1")
        self.help_menu.AppendSeparator()
        search_help = self.help_menu.Append(3,"查找帮助主题(S)...")
        use_help = self.help_menu.Append(4,"使用帮助(H)")
        self.help_menu.AppendSeparator()
        about = self.help_menu.Append(9,"关于扫雷(A)...")
        menu_bar.Append(self.help_menu,"&帮助(H)")
        #设置菜单条
        self.SetMenuBar(menu_bar)
        # 绑定菜单事件
        self.Bind(wx.EVT_MENU, self.e_menu_new, new)
        self.Bind(wx.EVT_MENU, self.e_menu_level1, level1)
        self.Bind(wx.EVT_MENU, self.e_menu_level2, level2)
        self.Bind(wx.EVT_MENU, self.e_menu_level3, level3)
        self.Bind(wx.EVT_MENU, self.e_menu_custom, custom)
        self.Bind(wx.EVT_MENU, self.e_menu_mark, mark)
        self.Bind(wx.EVT_MENU, self.e_menu_color, color)
        self.Bind(wx.EVT_MENU, self.e_menu_sound, sound)
        self.Bind(wx.EVT_MENU, self.e_menu_list, rs_list)
        self.Bind(wx.EVT_MENU, self.e_menu_exit, exit_gm)
        self.Bind(wx.EVT_MENU, self.e_menu_catalogue, catalogue)
        self.Bind(wx.EVT_MENU, self.e_menu_search, search_help)
        self.Bind(wx.EVT_MENU, self.e_menu_help, use_help)
        self.Bind(wx.EVT_MENU, self.e_menu_about, about)

    def create_panel(self):
        self.panel = wx.Panel(self)
        self.panel.Bind(wx.EVT_PAINT, self.e_paint)

    def get_mine_set(self):
        self.mine_set = set()
        while(len(self.mine_set)<100):
            self.mine_set.add(randint(0,719))

    def get_info_set(self):
        self.info_set = set()
        info_set = set()
        for i in self.mine_set:
            info_set.update({i-31,i-30,i-29,i-1,i+1,i+29,i+30,i+31})
        for i in info_set:
            if i not in self.mine_set and i in range(0,720):
                count = 0
                for j in [i-31,i-30,i-29,i-1,i+1,i+29,i+30,i+31]:
                    if j in self.mine_set:
                        count += 1
                self.info_set.add((i,count))

    def get_bmp_list(self):
        image_list = ['smile.png', 'oh.png', 'cry.png', 'com.png', 'flag.png', 'ques.png',
                      'mine.png', 'emine.png', 'redmine.png','icon.png']
        self.bmp_list = [wx.Image(i, wx.BITMAP_TYPE_PNG).ConvertToBitmap() for i in image_list]

    def create_state_btn(self):
        self.state_btn = wx.BitmapButton(self.panel, -1, self.bmp_list[0], (240, 10), (25, 25))
        self.state_btn.Bind(wx.EVT_BUTTON, self.e_restart)

    def create_text_info(self):
        self.mine_text = wx.StaticText(self.panel, -1, '100', (25, 10))
        self.mine_text.SetFont(wx.Font(20, wx.DEFAULT, wx.FONTSTYLE_NORMAL, wx.NORMAL, faceName="黑体"))
        self.mine_text.SetForegroundColour(wx.RED)
        self.time_text = wx.StaticText(self.panel, -1, '000', (440, 10))
        self.time_text.SetFont(wx.Font(20, wx.DEFAULT, wx.FONTSTYLE_NORMAL, wx.NORMAL, faceName="黑体"))
        self.time_text.SetForegroundColour(wx.RED)

    def create_timer(self):
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.e_time, self.timer)

    def draw_panel(self):
        self.dc = wx.ClientDC(self.panel)
        self.dc.SetBrush(wx.Brush(wx.Colour(192, 192, 192)))  # 设置填充颜色
        self.dc.SetPen(wx.GREY_PEN)  # 设置线条颜色
        self.dc.DrawRectangle(9, 50, 480, 384)  # 画方框
        for i in range(1, 24):
            self.dc.DrawLine(9, 16 * i + 50, 480 + 9, 16 * i + 50)  # 画横线
        for i in range(1, 30):
            self.dc.DrawLine(16 * i + 9, 50, 16 * i + 9, 384 + 50)  # 画竖线
        for i in self.mine_set:
            self.dc.DrawBitmap(self.bmp_list[6],i % 30 * 16 + 10, i // 30 * 16 + 1 + 50)# 画地雷
        text_color_dict = {1: '#0000ff', 2: '#008000', 3: '#ff0000', 4: '#000080', 5: '#800000',
                           6: '#e4007f', 7: '#6a3906', 8: '#000000'}  # 数量和颜色字典
        for i in self.info_set:
            self.dc.SetTextForeground(text_color_dict[i[1]])  # 查找相应的颜色
            self.dc.DrawText(str(i[1]), i[0] % 30 * 16 + 5 + 9, i[0] // 30 * 16 + 1 + 50)  # 显示雷数

    def create_btn_list(self):
        self.btn_list = []
        index = 0
        for i in range(0, 24):
            for j in range(0, 30):
                btn = wx.BitmapButton(self.panel,-1,self.bmp_list[3],(j * 16+9, i * 16+50),(17, 17))
                btn.index = index
                btn.state = 0
                self.btn_list.append(btn)
                index += 1
        for i in self.btn_list:
            i.Bind(wx.EVT_LEFT_DOWN,self.e_left_down)
            i.Bind(wx.EVT_LEFT_UP,self.e_left_up)
            i.Bind(wx.EVT_RIGHT_DOWN,self.e_right_down)

    def stop_game(self,index):
        self.state_btn.SetBitmap(self.bmp_list[2])
        self.timer.Stop()
        error_marked_set = set()
        for i, j in enumerate(self.btn_list):
            if i not in self.del_index_set:
                if i in self.mine_set:
                    if j.state != 1:
                        j.Destroy()
                        self.del_index_set.add(i)
                else:
                    if j.state == 1:
                        j.Destroy()
                        self.del_index_set.add(i)
                        error_marked_set.add(i)
            if i not in self.del_index_set:
                j.Unbind(wx.EVT_LEFT_UP, handler=self.e_left_up)  # 剩余的按钮解绑所有事件
                j.Unbind(wx.EVT_LEFT_DOWN, handler=self.e_left_down)
                j.Unbind(wx.EVT_RIGHT_DOWN, handler=self.e_right_down)
        self.panel.Unbind(wx.EVT_PAINT, handler=self.e_paint)  # 解绑绘图事件
        self.draw_panel()  # 重新生成面板
        self.dc.DrawBitmap(self.bmp_list[8],index % 30 * 16 + 10, index // 30 * 16 + 1 + 50)# 画红色炸雷
        self.dc.SetBrush(wx.TRANSPARENT_BRUSH)
        self.dc.DrawRectangle(index % 30 * 16 + 9, index // 30 * 16 + 50, 16, 16)
        for i in error_marked_set:
            self.dc.DrawBitmap(self.bmp_list[7], i % 30 * 16 + 10, i // 30 * 16 + 1 + 50)  # 画地雷

    def del_btn(self,btn,index):
        self.state_btn.SetBitmap(self.bmp_list[0])
        if index not in self.del_index_set and btn.state != 1:
            if index in [i[0] for i in self.info_set]:
                btn.Destroy()
                self.del_index_set.add(index)
            else:
                if index not in self.mine_set:
                    btn.Destroy()
                    self.del_index_set.add(index)
                for j in [index - 31, index - 30, index - 29, index - 1, index + 1, index + 29, index + 30,
                          index + 31]:
                    if j in range(0, 720) and j not in self.mine_set \
                            and j not in self.del_index_set \
                            and self.btn_list[j].state != 1:
                        self.btn_list[j].Destroy()
                        self.del_index_set.add(j)

    def e_paint(self,e):
        self.draw_panel()

    def e_time(self,e):
        self.time_count += 1
        self.time_text.SetLabel('%03d'%self.time_count)

    def e_left_up(self,e):
        if not self.timer.IsRunning():
            self.timer.Start(1000)
        btn = e.GetEventObject()
        index = btn.index
        if btn.state == 1:
            self.state_btn.SetBitmap(self.bmp_list[0])
        else:
            if index in self.mine_set:
                self.stop_game(index)
            else:
                self.del_btn(btn,index)

    def e_left_down(self,e):
        self.state_btn.SetBitmap(self.bmp_list[1])

    def e_right_down(self,e):
        btn = e.GetEventObject()
        index = btn.index
        label = btn.state
        if label == 0:
            btn.SetBitmap(self.bmp_list[4])
            btn.state = 1
            self.mine_last -= 1
            self.mine_text.SetLabel('%03d' %self.mine_last)
        elif label == 1:
            btn.SetBitmap(self.bmp_list[5])
            btn.state = 2
            self.mine_last += 1
            self.mine_text.SetLabel('%03d' % self.mine_last)
        else:
            btn.SetBitmap(self.bmp_list[3])
            btn.state = 0

    def e_restart(self,e):
        # 结束
        if self.timer.IsRunning():
            self.timer.Stop()# 计时器清零
        for i,j in enumerate(self.btn_list):
            if i not in self.del_index_set:
                j.Destroy()# 删掉所有按钮
        # 重启
        self.get_mine_set()
        self.get_info_set()
        self.panel.Bind(wx.EVT_PAINT, self.e_paint)
        self.time_count = 0
        self.mine_last = 100
        self.del_index_set = set()
        self.state_btn.SetBitmap(self.bmp_list[0])
        self.mine_text.SetLabel('100')
        self.time_text.SetLabel('000')
        self.create_btn_list()

if __name__=='__main__':
    app = wx.App()
    frame = MineFrame()
    frame.Show()
    app.MainLoop()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值