def drawMap(self): loc=self.locator self.frame=Rectangle(loc.netToPoint(0,0),loc.netToPoint(loc._m,loc._n)) self.frame.setOutline("black") #self.frame.setFill(color_rgb(0,255,255)) self.frame.draw(self.win) w=self.locator._width*1.0/self.locator._n #画flag self.flaglist=[] for net in self.flag: pos=loc.netToPoint(net["i"],net["j"]) g=Assembly(w,w,pos) g.load("bin/flag.dat") g.draw(self.win) self.flaglist.append(g) #画图形 self.actor=self.matrix(self.m,self.n,None) for i in range(0,self.m): for j in range(0,self.n): pos=loc.netToPoint(i,j) g=Assembly(w,w,pos) if self.state[i][j]==1: #载入man g.load("bin/man.dat") elif self.state[i][j]==2: #载入block g.load("bin/block.dat") elif self.state[i][j]==3: #载入box g.load("bin/box2.dat") g.draw(self.win) self.actor[i][j]=g #装入控件
class Game: def __init__(self): w=50 self.win=GraphWin('Game',14*w,12*w) self.win.setBackground('white') self.interval=w self.map="map/level_1.dat" self.locator=None #网格定位器 self.state=[] self.flag=[] self.actor=[] #主管map上的对象 #地图是m*n的 self.m=0 self.n=0 def start(self): w=self.interval self.restart=Assembly(w,w,Point(13*w,11*w)) self.restart.load("bin/restart.dat") self.restart.draw(self.win) while True: self._start() #一个周期 for list in self.actor: for g in list: g.undraw() for g in self.flaglist: g.undraw() self.frame.undraw() def _start(self): self.load() self.drawMap() loc=self.locator while True: p=self.win.getMouse() if loc.inside(p): #鼠标分析 self.dealMove(p) elif self.restart.inside(p): break if self.victory(): #胜利条件分析 tail=self.map.split('_')[1] digit=int(tail.split('.')[0])+1 self.map="map/level_"+str(digit)+".dat" break def victory(self): v=True for f in self.flag: if self.state[f["i"]][f["j"]]!=3: v=False break return v def _manPos(self): #man的位置 for i in range(0,self.m): for j in range(0,self.n): if self.state[i][j]==1: return {"i":i, "j":j} print "坑爹,有你这么制作地图的嘛" def dealMove(self,p): loc=self.locator state=self.state flag=self.flag actor=self.actor man=self._manPos() #man的网格位置 net=loc.pointToNet(p) #p的网格位置 if state[net["i"]][net["j"]]==0: #移动man if self._canMoveMan(man,net): #移动man g=actor[man["i"]][man["j"]] actor[man["i"]][man["j"]]=actor[net["i"]][net["j"]] actor[net["i"]][net["j"]]=g g.moveTo(loc.netToPoint(net["i"],net["j"])) #修改状态 state[man["i"]][man["j"]]=0 state[net["i"]][net["j"]]=1 elif state[net["i"]][net["j"]]==3: #移动box if self._canMoveBox(man,net): dir=self._boxDir(man,net) #移动box g1=actor[net["i"]][net["j"]] actor[net["i"]][net["j"]]=actor[dir["i"]][dir["j"]] actor[dir["i"]][dir["j"]]=g1 g1.moveTo(loc.netToPoint(dir["i"],dir["j"])) #移动man g2=actor[man["i"]][man["j"]] actor[man["i"]][man["j"]]=actor[net["i"]][net["j"]] actor[net["i"]][net["j"]]=g2 g2.moveTo(loc.netToPoint(net["i"],net["j"])) #修改状态 state[dir["i"]][dir["j"]]=3 state[man["i"]][man["j"]]=0 state[net["i"]][net["j"]]=1 def _boxDir(self,man,net): di=net["i"]-man["i"] dj=net["j"]-man["j"] if di==0: if dj<0: return {"i":net["i"], "j":net["j"]-1} elif dj>0: return {"i":net["i"], "j":net["j"]+1} if dj==0: if di>0: return {"i":net["i"]+1, "j":net["j"]} elif di<0: return {"i":net["i"]-1, "j":net["j"]} return None def _canMoveBox(self,man,net): dir=self._boxDir(man,net) if not dir: return False if not dir["i"] in range(0,self.m): return False if not dir["j"] in range(0,self.n): return False if self.state[dir["i"]][dir["j"]]!=0: return False return True def matrix(self,m,n,val): #生成m*n的二维数组 a=[] for i in range(0,m): tmp=[] for j in range(0,n): tmp.append(val) a.append(tmp) return a def _flood(self,judge,i,j): judge[i][j]=True for di in [-1,1]: if i+di>=0 and i+di<self.m: if (not judge[i+di][j]) and self.state[i+di][j]==0: self._flood(judge,i+di,j) for dj in [-1,1]: if j+dj>=0 and j+dj<self.n: if (not judge[i][j+dj]) and self.state[i][j+dj]==0: self._flood(judge,i,j+dj) def _canMoveMan(self,man,net): judge=self.matrix(self.m,self.n,False) #m*n的judge map self._flood(judge,man["i"],man["j"]) return judge[net["i"]][net["j"]] @tryload #若没有地图就用第一张地图 def load(self): f=file(self.map) str_dct=f.read() dct=eval(str_dct,{"__builtins__":None},{}) #主要是不想做地图编辑器了,这里是便于手动写入地图 f.close() self.m=dct["size"]["i"] self.n=dct["size"]["j"] self.state=dct["state"] self.flag=dct["flag"] #确定画布比例 w=self.interval m,n=self.m,self.n if n>=m: width=10*w*1.0 height=width*m/n pos=Point(w,w+(10*w-height)/2.0) else: height=10*w*1.0 width=height*n/m pos=Point(w+(10*w-width)/2.0,w) self.locator=Locator(m,n,width,height,pos) #装载定位器 def drawMap(self): loc=self.locator self.frame=Rectangle(loc.netToPoint(0,0),loc.netToPoint(loc._m,loc._n)) self.frame.setOutline("black") #self.frame.setFill(color_rgb(0,255,255)) self.frame.draw(self.win) w=self.locator._width*1.0/self.locator._n #画flag self.flaglist=[] for net in self.flag: pos=loc.netToPoint(net["i"],net["j"]) g=Assembly(w,w,pos) g.load("bin/flag.dat") g.draw(self.win) self.flaglist.append(g) #画图形 self.actor=self.matrix(self.m,self.n,None) for i in range(0,self.m): for j in range(0,self.n): pos=loc.netToPoint(i,j) g=Assembly(w,w,pos) if self.state[i][j]==1: #载入man g.load("bin/man.dat") elif self.state[i][j]==2: #载入block g.load("bin/block.dat") elif self.state[i][j]==3: #载入box g.load("bin/box2.dat") g.draw(self.win) self.actor[i][j]=g #装入控件
class GraphEditor: def __init__(self): self._buff={"type":"line","fill":"","outline":"black"} self._w=40 self._state="start" self._record=Assembly() self._filename=self.getFilename() self._exit=Assembly(1*self._w,1*self._w,Point(14*self._w,7*self._w)) self._save=Assembly(1*self._w,1*self._w,Point(15*self._w,7*self._w)) self._remove=Assembly(1*self._w,1*self._w,Point(13*self._w,7*self._w)) self._circle=Assembly(1*self._w,1*self._w,Point(14*self._w,1*self._w)) self._line=Assembly(1*self._w,1*self._w,Point(15*self._w,1*self._w)) self._rect=Assembly(1*self._w,1*self._w,Point(16*self._w,1*self._w)) self._fill=NetAss(8,1,8*self._w,1*self._w,Point(9*self._w,2*self._w)) self._outline=NetAss(8,1,8*self._w,1*self._w,Point(9*self._w,3*self._w)) #状态机 self._stateGraph={ "start":{"boardclick":"ready","endclick":"end","default":"idle"}, "idle":{"boardclick":"ready","endclick":"end","default":"idle"} , "ready":{"boardclick":"idle","endclick":"end","default":"ready"}, "end":{"default":"end"}} #确定画布比例 m,n=input("m , n?") if m>=n: width=7*self._w*1.0 if n==0: height=width else: height=width*n/m pos=Point(self._w,self._w+(7*self._w-height)/2.0) else: height=7*self._w*1.0 if m==0: width=height else: width=height*m/n pos=Point(self._w+(7*self._w-width)/2.0,self._w) #画网格 self._win=GraphWin(self._filename[4:].split(".")[0],17*self._w,9*self._w) self._win.setBackground('white') self._board=NetAss(m,n,width,height,pos) frame=Rectangle(pos,Point(pos.getX()+width,pos.getY()+height)) frame.setOutline("grey") self._board.appendGraphs(frame) for i in range(1,m): for j in range(1,n): p=self._board.netToPoint(i,j) p.setOutline("grey") self._board.appendGraphs(p) self._board.draw(self._win) self._record.setState(self._board.pos(),self._board.width(),self._board.height()) #置控件按钮 self._remove.load("bin/remove.dat") self._save.load("bin/save.dat") self._exit.load("bin/exit.dat") self._rect.load("bin/rectangle.dat") self._circle.load("bin/circle.dat") self._line.load("bin/line.dat") self._fill.load("bin/fill.dat") self._outline.load("bin/outline.dat") self._remove.draw(self._win) self._save.draw(self._win) self._exit.draw(self._win) self._rect.draw(self._win) self._circle.draw(self._win) self._line.draw(self._win) self._fill.draw(self._win) self._outline.draw(self._win) def getFilename(self): name=raw_input("name?") name=name.split('.')[0] if name[0:4]=="bin/": self._filename=name+".dat" else: self._filename="bin/"+name+".dat" return self._filename def load(self): if self._record.load(self._filename): self._record.draw(self._win) def changeState(self,event): if event in self._stateGraph[self._state]: self._state=self._stateGraph[self._state][event] else: self._state=self._stateGraph[self._state]["default"] def deal(self,mouse): """根据状态机响应鼠标点击""" if self._board.inside(mouse): self.boarddeal(mouse) self.changeState("boardclick") elif self._exit.inside(mouse): self.exitdeal() self.changeState("endclick") elif self._save.inside(mouse): self.savedeal() self.changeState("endclick") elif self._remove.inside(mouse): self.removedeal() self.changeState("default") elif self._line.inside(mouse): self.linedeal() self.changeState("default") elif self._circle.inside(mouse): self.circledeal() self.changeState("default") elif self._rect.inside(mouse): self.rectdeal() self.changeState("default") elif self._fill.inside(mouse): self.filldeal(mouse) self.changeState("default") elif self._outline.inside(mouse): self.outlinedeal(mouse) self.changeState("default") else: self.blankdeal() self.changeState("blankclick") def blankdeal(self): pass def exitdeal(self): pass def outlinedeal(self,p): axis=self._fill.pointToNet(p) color=["red","blue","yellow","green","black","grey","white",""] self._buff["outline"]=color[axis["i"]] def filldeal(self,p): axis=self._fill.pointToNet(p) color=["red","blue","yellow","green","black","grey","white",""] self._buff["fill"]=color[axis["i"]] def linedeal(self): self._buff["type"]="line" def circledeal(self): self._buff["type"]="circle" def rectdeal(self): self._buff["type"]="rectangle" def removedeal(self): tail=len(self._record._graphList)-1 if tail>=0: self._record._graphList[tail].undraw() del self._record._graphList[tail] def savedeal(self): self._record.save(self._filename) def boarddeal(self,p): if self._state in ["idle","start"]: self._buff["p1"]=self._board.nearNetPoint(p) self._buff["p1"].draw(self._win) elif self._state=="ready": self._buff["p1"].undraw() fill=self._buff["fill"] outline=self._buff["outline"] if self._buff["type"]=="line": line=Line(self._buff["p1"],self._board.nearNetPoint(p)) line.setFill(fill) line.draw(self._win) self._record.appendGraphs(line) elif self._buff["type"]=="circle": oval=Oval(self._buff["p1"],self._board.nearNetPoint(p)) oval.setFill(fill) oval.setOutline(outline) oval.draw(self._win) self._record.appendGraphs(oval) elif self._buff["type"]=="rectangle": rect=Rectangle(self._buff["p1"],self._board.nearNetPoint(p)) rect.setFill(fill) rect.setOutline(outline) rect.draw(self._win) self._record.appendGraphs(rect) def editor(self): self.load() while self._state!="end": self.deal(self._win.getMouse())