pygame学习教程(五)用exec优化上一个例子

前一篇
在C,C++代码重复工作用宏表示。举例。我用Msp430编程写的宏。
宏可以理解为文本替换。它的好处在于可以灵活地替换变量,举个例子。

#define        SETOUT(IONAME,IONUMBER) \
  P##IONAME##DIR|=BIT##IONUMBER;

这个解释##,##之间就是变量文本链接 具体SETOUT(1,3) 展开宏就是IONAME=1,
IONUMBER=3
P##IONAME##DIR|=BIT##IONUMBER;
相当于 “P”+IONAME+“DIR|=BIT”+IONUMBER+";"
结果是P1DIR|=BIT3
这样写的好处可以自己体会,至少每次置位不用费脑计算,也不用特意写一个函数,几个Msp430系列底层很实用的宏,其它单片机可以依据这个思路修改。

#define    DIM(a,b) \
  int  a,b;      
#define        SETOUT(IONAME,IONUMBER) \
  P##IONAME##DIR|=BIT##IONUMBER;

#define        SETB(IONAME,IONUMBER) \
  P##IONAME##OUT|=BIT##IONUMBER;

#define        SETIN(IONAME,IONUMBER) \
  P##IONAME##DIR&=~BIT##IONUMBER;

#define        CLRB(IONAME,IONUMBER) \
  P##IONAME##OUT&=~BIT##IONUMBER;

#define   SET_XOR(IONAME,IONUMBER) \
  P##IONAME##OUT ^= (1<<IONUMBER);

#define   SETONEBITH(NAME,NUMER)\
  NAME|=(128>>NUMER)
#define   SETONEBITL(NAME,NUMER)\
  NAME &=~(128>>NUMER)

#define   CHECK_IO(IONAME,IONUMBER) \
  (P##IONAME##IN & (1<<IONUMBER))

#define   CHECK_IOOUT(IONAME,IONUMBER) \
  (P##IONAME##OUT & (1<<IONUMBER))

在python里使用exec可以达到宏的效果,上一个例子。设想一下,我们放置两个按钮可以butto1.SetPo(); butto2.SetPo()。如果多个,多个实例化,就会显得很臃肿。所以这里我们需要编辑一个添加,简化程序。这里希望吧所有的按钮作为Dict保存起来。这样设置:

ButtonDict["butto1"] = [(12, 13), 'feid1.png']  #全局变量,判定
ButtonDict["butto2"] = [(52, 73), 'feid1.png']
ButtonDict["butto3"] = [(102, 203), 'feid1.png']

在这里为了让自己省心,第一段需要优化。可以编写一个添加函数(这是因为我精力不行,容易出错。不过程序员应该根据自己的习惯调整代码)很简单,自己按照自己的习惯编写吧。

  butto1 = Jbutton((12, 13), 'feid1.png')
  butto2 = Jbutton((52, 73), 'feid1.png')
  butto3 = Jbutton((102, 203), 'feid1.png')
  #这里的意思是初始化完成根据字典判断按钮的位置,实际上可以用按钮的属性高判断
  ButtonDict["butto1"] = [ButtonDict["butto1"][0], (butto1.BoPo[0], butto1.BoPo[1])]
  ButtonDict["butto2"] = [ButtonDict["butto2"][0], (butto2.BoPo[0], butto2.BoPo[1])]
  ButtonDict["butto3"] = [ButtonDict["butto3"][0], (butto3.BoPo[0], butto3.BoPo[1])]
  

注意到共性,除了文本有变化,其它变化不大,正是使用exec的时机
这段代码也是一样

   butto1.SetPo()
   butto2.SetPo()
   butto3.SetPo()

思路就是把这些变成有规律的指令用exec循环执行,如果你添加或删除一个按钮就不需要改动太多了。修改这两个函数,就是把 ButtonDict所有与按钮有关的代码抽象出来自动处理(format一下)

def CreateButton():
   # global ButtonDict
    mylist=[]
    for exi in ButtonDict.keys():
        mylist.append("{}=Jbutton({},'{}')".format(exi,ButtonDict[exi][0],ButtonDict[exi][1]))
    for exi in ButtonDict.keys():
        mylist.append('ButtonDict["{0}"] = [ButtonDict["{0}"][0],({0}.BoPo[0],{0}.BoPo[1])]'.format(exi))
    return mylist

def showButton():
    mylist = [] #butto1.SetPo()
    for exi in ButtonDict.keys():
        mylist.append ("{}.SetPo()".format(exi))
    return mylist

修正后的代码,下一节准备添加鼠标移动事件

# coding: utf8
import pygame
#导入pygame库
from pygame.locals import *
#导入一些常用的函数和常量
from sys import exit
import  pickle
from PIL import Image
import DVerctor
# coding: utf8
import pygame
#导入pygame库
from pygame.locals import *
#导入一些常用的函数和常量
from sys import exit
import  pickle
import DVerctor

ButtonDict={}
class JCon():
    def __init__(self,vertex,mouse_image_filename):
        self.vertex=vertex                         #设置按钮顶点 set button vertex (left,top)格式
        self.mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()
        self.count=0                                #用于计数
        self.BoPo =DVerctor.Vec2d(vertex)+DVerctor.Vec2d(self.mouse_cursor.get_width(),self.mouse_cursor.get_height())
        #获得范围left+width,top+height (x,y)+(x1,y1)
    def SetPo(self):  #设置位置 set position  #
        screen.blit(self.mouse_cursor,self.vertex)
    def Mouse_Click(self):
        pass

class Jbutton(JCon):
    pass
def TextPygame():  #测试模块是否存在和版本号
    print(pygame.ver)
    pgname = ['pygame.cdrom', 'pygame.cursors', 'pygame.display', 'pygame.draw',
              'pygame.event', 'pygame.font', 'pygame.image', 'pygame.joystick',
              'pygame.key', 'pygame.mixer', 'pygame.mouse', 'pygame.movie', 'pygame.music',
              'pygame.overlay', 'pygame', 'pygame.rect', 'pygame.sndarray', 'pygame.sprite',
              'pygame.surface', 'pygame.surfarray', 'pygame.time']
    for i in pgname:
        if i is None:
            print(i+" is None")
        else:
            print(i + " at this computer")

def storeTree(filename,*args):
    with open(filename,'wb') as fw:  #打开需要用'wb'
        for i in args:
            pickle.dump(i, fw,-1) #为了保护数据protocol=-1,设为0可以看到数据

def grabTree(filename):
    Mylist=[]   #返回变量的列表
    with open(filename,'rb') as fr:
        while True:        #这里用try最简单,不用定义循环次数
            try:
                Mylist.append(pickle.load(fr))
            except:
                break
    return Mylist

def CreateButton():
   # global ButtonDict
    mylist=[]
    for exi in ButtonDict.keys():
        mylist.append("{}=Jbutton({},'{}')".format(exi,ButtonDict[exi][0],ButtonDict[exi][1]))
    for exi in ButtonDict.keys():
        mylist.append('ButtonDict["{0}"] = [ButtonDict["{0}"][0],({0}.BoPo[0],{0}.BoPo[1])]'.format(exi))
    return mylist

def showButton():
    mylist = [] #butto1.SetPo()
    for exi in ButtonDict.keys():
        mylist.append ("{}.SetPo()".format(exi))
    return mylist



if __name__ == "__main__":
    background_image_filename = 'sushiplate.jpg'
    # 指定图像文件名称
    pygame.init()
    # 初始化pygame,为使用硬件做准备
    screen = pygame.display.set_mode((640, 480), 0, 32)
    # 创建了一个窗口
    pygame.display.set_caption("Hello, World!")    # 设置窗口标题
    background = pygame.image.load(background_image_filename).convert()
    #在这里添加按钮
    ButtonDict["butto1"] = [(12, 13), 'feid1.png']  #全局变量,判定
    ButtonDict["butto2"] = [(52, 73), 'feid1.png']
    ButtonDict["butto3"] = [(102, 203), 'feid1.png']
#    ButtonDict = {"butto1": [(12, 13), 'feid1.png'], "butto2": [(52, 73), 'feid1.png'], "butto3": [(102, 203), 'feid1.png']}
    s=CreateButton()
  #  RunStr(s) 这里不能调用函数
    for i in s:
        exec(i)

    print("ButtonDict=",ButtonDict)
    #修改ButtonDict
    while True:
        # 游戏主循环
        for event in pygame.event.get():
            if event.type == QUIT:
                # 接收到退出事件后退出程序
                exit()

        screen.blit(background, (0, 0))
        # 将背景图画上去
        x, y = pygame.mouse.get_pos()
        # 获得鼠标位置
        # 计算光标的左上角位置

        #screen.blit(mouse_cursor, (x, y))
        # 把光标画上去
        # butto1.SetPo()
        # butto2.SetPo()
        # butto3.SetPo()
        for i in showButton():
            exec(i)

        #screen.blit(mouse_cursor, butto1.vertex)
        pygame.display.update()
        # 刷新一下画面


猜你喜欢

转载自blog.csdn.net/weixin_39462002/article/details/85047533
今日推荐