首页 > 其他 > 详细

连点成图:享受创建图形的乐趣

时间:2014-11-30 06:07:00      阅读:574      评论:0      收藏:0      [点我收藏+]

 

         1.  使用 wxpython 做基本的 GUI ;

         2.  使用 Python 实现策略模式;

         3.  点阵图的算法,使用程序生成, 既有趣也很锻炼算法思维连带激发创造力哦。

 

         改进点: 生成更复杂更美妙的图案; 拖拽功能创作和保存; 关卡设置。你也来试试吧! 如果有兴趣做成移动游戏, 那就更棒了!

 

      bubuko.com,布布扣

 

      源程序:

  linkpointsUI.py 

# -*- coding: utf8 -*-
# -------------------------------------------------------------------------------
# Name:        linkpointsUI.py
# Purpose:     a game which join points to a gragh and enjoy
#
# Author:      qin.shuq
#
# Created:      11/29/2014
# Copyright:   (c) qin.shuq 2014
# Licence:     ONLY BE USED FOR STUDY
#-------------------------------------------------------------------------------


import wx
import time
from LinkPointStrategy import *


class LinkPointsFrame(wx.Frame):
    ‘‘‘
       generate dotSize * dotSize dotted graph and app ui
    ‘‘‘
    def __init__(self, parent, title, dotSize=18, uiSize=(840,560)):
        wx.Frame.__init__(self, parent, title=title, size=uiSize)
        self.mainPanel = None
        self.dc = None
        self.dotSize = dotSize
        self.displayDemoTimer = None

        bottomSpace = 50
        uiWidth = uiSize[0]
        panelHeight = uiSize[1] - bottomSpace

        self.origin = 10
        self.pointRadius = 2
        self.intervalBetweenPoints = (panelHeight-self.origin*2) / (self.dotSize-1)

        self.mainPanelSize = (panelHeight, panelHeight)
        self.ctrlPanelSize = (uiWidth - self.mainPanelSize[0], panelHeight)

        self.initUI()

    def initUI(self):

        ### UI Design follows top-down thinking and down-top building

        bigPanel = wx.Panel(self, name="WhileWindow")
        font = wx.Font(12, wx.ROMAN, wx.NORMAL, wx.NORMAL)

        hboxLayout = wx.BoxSizer(wx.HORIZONTAL)
        self.mainpanel = wx.Panel(bigPanel, name="mainPanel", size=self.mainPanelSize)
        self.mainpanel.SetBackgroundColour(#fffff0)

        ctrlPanel = wx.Panel(bigPanel, name="ctrlPanel", size=self.ctrlPanelSize)

        hboxLayout.Add(self.mainpanel, 0, wx.EXPAND|wx.ALL, 10)
        hboxLayout.Add(ctrlPanel, 0, wx.EXPAND|wx.ALL, 10)
        bigPanel.SetSizer(hboxLayout)

        topPanel = wx.Panel(ctrlPanel, name="topPanel")
        staticText = wx.StaticText(topPanel, label=decodeUTF8("How to Play: \n\nJust link points to build a graph, \nSo Easy And Enjoy Yourself !"))
        staticText.SetFont(font)

        btnBoxSizer = wx.BoxSizer(wx.VERTICAL)

        createNewBtn = wx.Button(ctrlPanel, name="CreateNew", label=decodeUTF8("创作"))
        saveBtn = wx.Button(ctrlPanel, name="SaveWork", label=decodeUTF8("保存"))
        seeDemoBtn = wx.Button(ctrlPanel, name="seeDemo", label=decodeUTF8("欣赏"))

        self.Bind(wx.EVT_BUTTON, self.createNewDottedGraph, createNewBtn)
        self.Bind(wx.EVT_BUTTON, self.createDemoGraph, seeDemoBtn)

        btnBoxSizer.Add(createNewBtn)
        btnBoxSizer.Add(saveBtn)
        btnBoxSizer.Add(seeDemoBtn)

        vboxLayout = wx.BoxSizer(wx.VERTICAL)
        vboxLayout.Add(topPanel, 1, wx.EXPAND|wx.ALL, 5)
        vboxLayout.Add(btnBoxSizer, 1, wx.EXPAND|wx.ALL, 5)
        ctrlPanel.SetSizer(vboxLayout)

        self.Show(True)

        # show demo
        self.createDemoGraph()


    def createNewDottedGraph(self, event=None):
        if self.displayDemoTimer:
            self.displayDemoTimer.Stop()
        if self.dc:
            self.dc.Clear()
        self.dc = wx.ClientDC(self.mainpanel)
        self.dc.SetPen(wx.Pen(GREEN))
        self.dc.SetBrush(wx.Brush(GREEN))
        for xcoord in range(self.origin, self.mainPanelSize[0] + self.intervalBetweenPoints, self.intervalBetweenPoints):
            for ycoord in range(self.origin, self.mainPanelSize[1] + self.intervalBetweenPoints, self.intervalBetweenPoints):
                self.dc.DrawPoint(xcoord, ycoord)
                self.dc.DrawCircle(xcoord,ycoord, self.pointRadius)


    def drawGraph(self, allLines):
        ‘‘‘
           a line is a tuple of ((x1,y1), (x2, y2))
        ‘‘‘
        #print ‘***************************************‘
        for line in allLines:
            #print line[0][0], ‘ ‘, line[0][1], ‘ ‘, line[1][0], ‘ ‘, line[1][1]
            x1 = self.obtainRealCoords(line[0][0])
            y1 = self.obtainRealCoords(line[0][1])
            x2 = self.obtainRealCoords(line[1][0])
            y2 = self.obtainRealCoords(line[1][1])
            self.dc.DrawLine(x1, y1, x2, y2)

    def createDemoGraph(self, event=None):
        self.createNewDottedGraph()
        linkpointsStrategy = LinkPointStrategy(self.dotSize)
        allLines = linkpointsStrategy.obtainAllLinesByLinkPoints()
        self.drawGraph(allLines)

        try:
            anoStrategy = LinkPointStrategy.getStrategy("anoStrategy")
        except Exception, args:
            print args

        def myStrategy(allPoints, size):
            return [(point, (point[0]+1, point[1]+1)) for point in allPoints if (point[0] == point[1] and point[0]<size-1)]

        LinkPointStrategy.registerStrategy("my", myStrategy)
        LinkPointStrategy.setStrategy("my")
        self.createNewDottedGraph()
        self.drawGraph(linkpointsStrategy.obtainAllLinesByLinkPoints())

        def displayDemo(*args, **kwargs):
            allStrategies = linkpointsStrategy.getAllStrategies()
            for strategyName in allStrategies.keys():
                self.createNewDottedGraph()
                linkpointsStrategy.setStrategy(strategyName)
                self.drawGraph(linkpointsStrategy.obtainAllLinesByLinkPoints())
                time.sleep(2)

        self.displayDemoTimer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, displayDemo, self.displayDemoTimer)
        self.displayDemoTimer.Start(3000, oneShot=False)


    def obtainRealCoords(self, localCoord):
        ‘‘‘
            将逻辑坐标 (x,y) 转换为 实际坐标 (real_x, real_y).
            eg. 假设原点坐标是 (15,15), 点间隔为 (30, 30), 则 (1,1) -> (45,45)
            这样在绘图时就可以专注于以逻辑坐标来思考,摒弃实际坐标的细节干扰
        ‘‘‘
        return self.origin+localCoord*self.intervalBetweenPoints


# utils
def decodeUTF8(msg):
    return msg.decode(utf8)

def main():

    app = wx.App(False)
    frame = LinkPointsFrame(None, decodeUTF8(连点成图: 享受创建图形的乐趣))
    app.MainLoop()


if __name__ == __main__:
    main()

 

    LinkPointStrategy.py

 

# -*- coding: utf8 -*-
# -------------------------------------------------------------------------------
# Name:        LinkPointStrategy.py
# Purpose:     varieties of algorithms for linking points
#
# Author:      qin.shuq
#
# Created:     11/29/2014
# Copyright:   (c) qin.shuq 2014
# Licence:     ONLY BE USED FOR STUDY
# -------------------------------------------------------------------------------

def simpleLoopStrategyOfLinkpoints(allPoints, size):
    pairs = []
    for i in range(size):
        if i*2 <= size-1:
            pairs.append((i, size-1-i))
    allLines = []
    for pair in pairs:
        allLines.append( ((pair[0], pair[0]), (pair[0], pair[1])) )
        allLines.append( ((pair[0], pair[0]), (pair[1], pair[0])) )
        allLines.append( ((pair[0], pair[1]), (pair[1], pair[1])) )
        allLines.append( ((pair[1], pair[0]), (pair[1], pair[1])) )
    return allLines


def loopStrategyOfLinkpoints(allPoints, size):
    pairs = []
    for i in range(size):
        if i*2 <= size-1:
            pairs.append((i, size-1-i))
    allLines = []
    for pair in pairs:
        begin = (pair[0], pair[0])
        end = (pair[1], pair[1])
        for localXCoord in range(pair[0], pair[1], 1):
            allLines.append(((pair[0], localXCoord), (pair[0], localXCoord+1)))
            allLines.append(((pair[1], localXCoord), (pair[1], localXCoord+1)))
        for localYCoord in range(pair[0], pair[1], 1):
            allLines.append(((localYCoord, pair[0]), (localYCoord+1, pair[0])))
            allLines.append(((localYCoord, pair[1]), (localYCoord+1, pair[1])))
    return allLines


def defaultStrategyOfLinkpoints(allPoints, size):
    return [( point, (point[0]+1, point[1]+1) )
                for point in allPoints if not isRightOrButtomBoundPoint(point, size)]


def isRightOrButtomBoundPoint(point, size):
    localXCoord = point[0]
    localYCoord = point[1]
    return localXCoord == size-1 or localYCoord == size-1


class StrategyManager(object):

    def __init__(self):
        self.strategiesForlinkPoints = {
            default: defaultStrategyOfLinkpoints,
            loop: loopStrategyOfLinkpoints,
            simpleLoop: simpleLoopStrategyOfLinkpoints
        }
        self.DEFAULT_STRATEGY = self.strategiesForlinkPoints[default]
        self.CURR_STRATEGY = self.DEFAULT_STRATEGY

    def getStrategy(self, strategyName):
        strategyForLinkPoints = self.strategiesForlinkPoints.get(strategyName)
        if strategyForLinkPoints is None:
            raise Exception(No stragegy named "%s". You can write one.  % strategyName)
        return strategyForLinkPoints

    def registerStrategy(self, strategyName, strategyForLinkPoints):
        oldStrategy = self.strategiesForlinkPoints.get(strategyName)
        if oldStrategy:
            self.strategiesForlinkPoints[old_ + strategyName] = oldStrategy
        self.strategiesForlinkPoints[strategyName] = strategyForLinkPoints

    def setCurrStrategy(self, strategyName):
        self.CURR_STRATEGY = self.getStrategy(strategyName)

    def getCurrStratety(self):
        return self.CURR_STRATEGY

    def getAllStrategies(self):
        return self.strategiesForlinkPoints


class LinkPointStrategy(object):
    ‘‘‘
       just think in a dotted graph of  (0,0) - (dotSize-1, dotSize-1) with interval of points = 1
       (0,0), (0,1), ... , (0, dotSize-1)
       (1,0), (1,1), ... , (1, dotSize-1)
        ... ,  ... , ... ,  ...
       (dotSize-1,0), (dotSize-1, 1), ..., (dotSize-1, dotSize-1)
       and output a set of [((x1,y1), (x2,y2)), ..., ((xm,ym), (xn,yn))]
    ‘‘‘

    strategyManager = StrategyManager()

    def __init__(self, dotSize):
        self.dotSize = dotSize
        self.allPoints = []

        for localXCoord in range(dotSize):
            for localYCoord in range(dotSize):
                self.allPoints.append((localXCoord, localYCoord))


    @classmethod
    def setStrategy(cls, strategyName):
        cls.strategyManager.setCurrStrategy(strategyName)

    @classmethod
    def getStrategy(cls, strategyName):
        return cls.strategyManager.getStrategy(strategyName)

    @classmethod
    def registerStrategy(cls, strategyName, strategyFunc):
        cls.strategyManager.registerStrategy(strategyName, strategyFunc)

    @classmethod
    def getAllStrategies(cls):
        return cls.strategyManager.getAllStrategies()

    def obtainAllLinesByLinkPoints(self):
        ‘‘‘
           generate all lines between points according to given strategy which is a algorithm of linking points
           line: a tuple of (x1, y1, x2, y2)
           note: (x1, y1, x2, y2) are local coordinates which will be converted into real coordinates upon drawing
        ‘‘‘
        currStrategy = LinkPointStrategy.strategyManager.getCurrStratety()
        return currStrategy(self.allPoints, self.dotSize)

 

连点成图:享受创建图形的乐趣

原文:http://www.cnblogs.com/lovesqcc/p/4132341.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!