PyQt挖地雷游戏学习笔记(3)

这个程序使用了Python有特色的语法套路。先看第一个。

main.py里的class MainWindow的函数init()中,有这样的语句:

self.scene.setMap((conf.w, conf.h), conf.mines)

这里的变量conf,定义在config.py中,由以下语句引入的:

from config import *

这里的conf.w和conf.h是什么呢?由此,转入config.py,一探究竟。

#module: config

import json

DEFAULTS = {
    'splash':False,
    'w': 10,
    'h': 10,
    'mines': 1,
    'scores': [],
    }

DEFAULT_SAVE_FILE = "config.cfg"

class _Conf:
    def __getattr__(self,name):
        return DEFAULTS[name]

    def __setattr__(self,name,value):
        if type(value) != type(DEFAULTS[name]):
            raise Exception("%s %s is not %s:" %
                            (value, type(value), type(DEFAULTS[name])))
        DEFAULTS[name] = value

    def save(self,fileName=DEFAULT_SAVE_FILE):
        with open(fileName, 'w+') as fp:
            json.dump(DEFAULTS, fp, indent=True)

    def load(self,fileName=DEFAULT_SAVE_FILE):
        with open(fileName, 'r') as fp:
            global DEFAULTS
            DEFAULTS = json.load(fp)

conf = _Conf()
try:
    conf.load()
except:
    pass

由此可见,main.py导入该模块,会发生以下事情:

建立并初始化模块级变量,词典DEFAULTS;

建立并初始化模块级变量,DEFAULT_SAVE_FILE = "config.cfg"

建立模块级变量conf,并以此实例化 _Conf;

以conf引用 _Conf中的函数load(),把config.cfg文件中的数据,读入DEFAULTS。

遍观 _Conf,并没有成员变量w和h,但为何使用conf.w和conf.h呢?

奥妙在于 _Conf中的特别函数 __getattr__(name)

当以conf.w读数据时,__getattr__ 的参数name的值,就是“w”,

而它返回的值,是DEFAULTS[“w”]。这个值等于10。

Python的这一语法套路,读取词典DEFAULTS的操作,表现形式成了访问class的成员。

时间: 2024-10-15 22:16:51

PyQt挖地雷游戏学习笔记(3)的相关文章

PyQt挖地雷游戏学习笔记(2)

分析多个文件组成的源代码,最好使用辅助工具. 我试过Source Navigator 和 Source Insight,感觉后者功能多些,比较好用. 一.程序的组成模块等文件 这个挖地雷游戏,主要由2种文件组成: 1.程序模块 主程序main.py:负责主窗口物件,按钮和菜单的设置.事件处理.程序初始化.结束等等. 游戏逻辑模块game_scene.py:负责游戏规则.棋盘显示.胜负裁判.记录得分等等. "导入"文件lib.py:导入一些通用的模块,其他文件只需导入lib.py. 游戏

PyQt挖地雷游戏学习笔记(7)

1.游戏规则 地雷随机埋设在"棋盘"方格里,挖到地雷为败,挖光全部无雷方格为胜. 2.游戏的空间表示 游戏发生在棋盘上,游戏的场景.规则,都体现在棋盘上. 棋盘,由"场景盘"和"逻辑盘"共同组成. "场景盘"是玩家挖雷面对的棋盘. "逻辑盘"是实现游戏规则所需的"雷区盘"."空区盘"和"提示盘". "逻辑盘"由数组表示. 棋盘.

PyQt挖地雷游戏学习笔记(6)

学习别人的作品,有一大好处,可以反观自己的不足. 自己的不足,往往是基础知识有欠缺,基本功不扎实. 今天,再补一课:星号表达式(*expression). 挖地雷程序中,有2处用到星号表达式.一是在main.py,另一处在game_scene.py. 先看第一处的情况: @pyqtSlot() def on_action_Setup_triggered(self): result = setup.getSetup() if not result: return self.scene.setMap

PyQt挖地雷游戏学习笔记(1)

想学会PyQt.按习惯做法,从分析学习编程实例着手. 从网上找了个"挖地雷"的源码,大卸八块,仔细解剖,力图学到些东西. 原程序中有bug,如:"棋盘"没有下边界线:挖出全部地雷后,程序没反应,不认定获胜. 我已将其铲掉,可以正常运行了. 程序源码可在此下载 所做修改,都在game_scene.py.共有2处: 一是在函数checkWin()中,原文是: if ((self.mine_map == self.flag_map).all() and (self.min

PyQt挖地雷游戏学习笔记(4)

又遇到一个有意思的问题,它提醒了查阅文档和相关源码,与测试的重要性. 直接上代码,setup.py """ module: setup """ from lib import * from config import * form, base = loadUiType("setup.ui") class SetupDlg(QDialog, form): def __init__(self): super(SetupDlg, s

组合游戏学习笔记 [补档]

基础 满足以下条件的游戏是组合游戏: 有两人参与游戏, 轮流作出决策 无法作出决策的人失败, 然后游戏结束 游戏总能在有限次决策后结束 游戏的同一个状态不会多次到达 任意一个参与者在某一确定状态下可以作出的决策集合只与当前状态有关 定义先手必败状态为必败态, 先手必胜状态为必胜态, 则我们有 无法进行任何移动的状态是必败态. 可以移动到必败态的状态的是必胜态. 所有移动都只能得到必胜态的状态是必败态. 考虑如何判断一个游戏中, 先手是否必胜: 根据定义, 由于游戏中任意状态都不可能重复出现, 因

关于扫雷游戏学习笔记(二)

用户控件与窗体之间的传值:要实现当MineField中扫雷成功或失败,笑脸图标做出相应的改变. 1.通过构造函数传参 //MineField类中 public PictureBox smile; public MineField(PictureBox pb) { smile=pb; InitializeComponent(); } //在Form.Designer中的InitializeComponent里加入 this.mineField1 = new Mine.MineField(pictu

Unity3D学习笔记之七创建自己的游戏场景

到现在为止我们已经拥有了比较完备的Prefab,已经可以创建宏大的游戏场景,并以第一人称视角在场景中漫游了.这里给大家做个小的示范,建一个小场景大家在创建场景的时候需要自由发挥,做个尽量大的场景出来. 这一系列教程以及素材均参考自人人素材翻译组出品的翻译教程<Unity游戏引擎的基础入门视频教程>,下载链接附在第二篇学习笔记中. 我们以最初的添加了First Person Controller的PFB_Straight为整个场景的中心点来展开.我们先从Project中Prefabs文件夹拖出来

【Unity 3D】学习笔记三十五:游戏实例——摄像机切换镜头

摄像机切换镜头 在游戏中常常会切换摄像机来观察某一个游戏对象,能够说.在3D游戏开发中,摄像头的切换是不可或缺的. 这次我们学习总结下摄像机怎么切换镜头. 代码: private var Camera0: GameObject; private var Camera1: GameObject; private var Camera2: GameObject; private var Camera: GameObject; function Start() { //获取摄像机对象 Camera =