python图形界面入门_Python入门 —— 2048实战(字符界面和图形界面)

#-*- coding: utf-8 -*-

#Importing libraries to be used

importwximportosimportrandomimportcopy#creating the user interface frame that the user will interact with and perform actions that will have an appropriate response

classFrame(wx.Frame):def __init__(self,title):#created a default toolbar of application with a resizeable option and minimize box

super(Frame,self).__init__(None,-1,title,

style=wx.DEFAULT_FRAME_STYLE^wx.MAXIMIZE_BOX^wx.RESIZE_BORDER)#Setting different colours for each tile in the game

self.colors = {0:(204,192,179),2:(238, 228, 218),4:(237, 224, 200),8:(242, 177, 121),16:(245, 149, 99),32:(246, 124, 95),64:(246, 94, 59),128:(237, 207, 114),256:(237, 207, 114),512:(237, 207, 114),1024:(237, 207, 114),2048:(237, 207, 114),4096:(237, 207, 114),8192:(237, 207, 114),16384:(237, 207, 114),32768:(237, 207, 114),65536:(237, 207, 114),131072:(237, 207, 114),262144:(237, 207, 114),524288:(237, 207, 114),1048576:(237, 207, 114),2097152:(237, 207, 114),4194304:(237, 207, 114),8388608:(237, 207, 114),16777216:(237, 207, 114),33554432:(237, 207, 114),67108864:(237, 207, 114),134217728:(237, 207, 114),268435456:(237, 207, 114),536870912:(237, 207, 114),1073741824:(237, 207, 114),2147483648:(237, 207, 114),4294967296:(237, 207, 114),8589934592:(237, 207, 114),17179869184:(237, 207, 114),34359738368:(237, 207, 114),68719476736:(237, 207, 114),137438953472:(237, 207, 114),274877906944:(237, 207, 114),549755813888:(237, 207, 114),1099511627776:(237, 207, 114),2199023255552:(237, 207, 114),4398046511104:(237, 207, 114),8796093022208:(237, 207, 114),17592186044416:(237, 207, 114),35184372088832:(237, 207, 114),70368744177664:(237, 207, 114),140737488355328:(237, 207, 114),281474976710656:(237, 207, 114),562949953421312:(237, 207, 114),1125899906842624:(237, 207, 114),2251799813685248:(237, 207, 114),4503599627370496:(237, 207, 114),9007199254740992:(237, 207, 114),18014398509481984:(237, 207, 114),36028797018963968:(237, 207, 114),72057594037927936:(237, 207, 114)}#Initalize game

self.setIcon()

self.initGame()#Displays game and provides settings to move the tiles

panel =wx.Panel(self)

panel.Bind(wx.EVT_KEY_DOWN,self.onKeyDown)

panel.SetFocus()

self.initBuffer()

self.Bind(wx.EVT_SIZE,self.onSize)

self.Bind(wx.EVT_PAINT, self.onPaint)

self.Bind(wx.EVT_CLOSE,self.onClose)

self.SetClientSize((505,720))

self.Center()

self.Show()#Puts on board so user can see

defonPaint(self,event):

dc=wx.BufferedPaintDC(self,self.buffer)#Saves score and terminates when closed

defonClose(self,event):

self.saveScore()

self.Destroy()#putting icon on toolbar

defsetIcon(self):

icon= wx.Icon("icon.ico",wx.BITMAP_TYPE_ICO)

self.SetIcon(icon)#Opens previous game and loads and updates score

defloadScore(self):if os.path.exists("bestscore.ini"):

ff= open("bestscore.ini")

self.bstScore=ff.read()

ff.close()#Saves score and writes to file so it may be opened later

defsaveScore(self):

ff= open("bestscore.ini","w")

ff.write(str(self.bstScore))

ff.close()#Initalize game so when it opens it displays text, score and all data needed for the game

definitGame(self):

self.bgFont= wx.Font(50,wx.SWISS,wx.NORMAL,wx.BOLD,face=u"Roboto")

self.scFont= wx.Font(36,wx.SWISS,wx.NORMAL,wx.BOLD,face=u"Roboto")

self.smFont= wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,face=u"Roboto")

self.curScore=0

self.bstScore=0

self.loadScore()#4 rows and 4 coloums for tiles ( using arrays because it easily represents system used )

self.data =[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]

count=0#First 2 tile inialized if 1 tile it must be 2 but if 2 tiles connected then its 4

while count<2:

row= random.randint(0,len(self.data)-1)

col= random.randint(0,len(self.data[0])-1)if self.data[row][col]!=0: continueself.data[row][col]= 2 if random.randint(0,1) else 4count+= 1

#empty bitmap to put pixels in for game

definitBuffer(self):

w,h=self.GetClientSize()

self.buffer=wx.EmptyBitmap(w,h)#Displays all drawings to the screen

defonSize(self,event):

self.initBuffer()

self.drawAll()#Placing tiles on screen and multiplying by 2 if 2 tiles interact with one another(game logic)

defputTile(self):

available=[]for row inrange(len(self.data)):for col inrange(len(self.data[0])):if self.data[row][col]==0: available.append((row,col)) #add tile if empty square

ifavailable:

row,col= available[random.randint(0,len(available)-1)]

self.data[row][col]= 2 if random.randint(0,1) else 4

returnTruereturnFalsedef update(self,vlist,direct): #updates score and game tiles

score =0if direct: #up or left

i = 1

while i

if vlist[i-1]==vlist[i]:delvlist[i]

vlist[i-1] *= 2score+= vlist[i-1] #Adds multiplied value to score

i += 1i+= 1

else:#direction moved downward same thing as above but different direction

i = len(vlist)-1

while i>0:if vlist[i-1]==vlist[i]:delvlist[i]

vlist[i-1] *= 2score+= vlist[i-1]

i-= 1i-= 1

returnscore#The calucation and keeping logs of data for score (upward and downward movements)

defslideUpDown(self,up):

score=0

numCols=len(self.data[0])

numRows=len(self.data)

oldData=copy.deepcopy(self.data)for col inrange(numCols):

cvl= [self.data[row][col] for row in range(numRows) if self.data[row][col]!=0]if len(cvl)>=2:

score+=self.update(cvl,up)for i in range(numRows-len(cvl)):ifup: cvl.append(0)else: cvl.insert(0,0)for row in range(numRows): self.data[row][col] =cvl[row]return oldData!=self.data,score#The calucation and keeping logs of data for score (right and left movements)

defslideLeftRight(self,left):

score=0

numRows=len(self.data)

numCols=len(self.data[0])

oldData=copy.deepcopy(self.data)for row inrange(numRows):

rvl= [self.data[row][col] for col in range(numCols) if self.data[row][col]!=0]if len(rvl)>=2:

score+=self.update(rvl,left)for i in range(numCols-len(rvl)):ifleft: rvl.append(0)else: rvl.insert(0,0)for col in range(numCols): self.data[row][col] =rvl[col]return oldData!=self.data,scoredefisGameOver(self):

copyData=copy.deepcopy(self.data)

flag= False #Tile is not moveable or you have lost if all tiles cant move any pieces up,down, left or right

if not self.slideUpDown(True)[0] and not self.slideUpDown(False)[0] and\not self.slideLeftRight(True)[0] and notself.slideLeftRight(False)[0]:

flag= True #continue playing and copydata

if not flag: self.data =copyDatareturnflag#Game logic to see if you can make a move or end the game

defdoMove(self,move,score):#if you can move put a tile and update change

ifmove:

self.putTile()

self.drawChange(score)#if game is over put a message box and update best score if its the new best score

ifself.isGameOver():if wx.MessageBox(u"游戏结束,是否重新开始?",u"哈哈",

wx.YES_NO|wx.ICON_INFORMATION)==wx.YES:

bstScore=self.bstScore

self.initGame()

self.bstScore=bstScore

self.drawAll()#when you click a directon for the tile to move, it moves in the appropriate direction

defonKeyDown(self,event):

keyCode=event.GetKeyCode()if keyCode==wx.WXK_UP:

self.doMove(*self.slideUpDown(True))elif keyCode==wx.WXK_DOWN:

self.doMove(*self.slideUpDown(False))elif keyCode==wx.WXK_LEFT:

self.doMove(*self.slideLeftRight(True))elif keyCode==wx.WXK_RIGHT:

self.doMove(*self.slideLeftRight(False))#Creates background for the game board

defdrawBg(self,dc):

dc.SetBackground(wx.Brush((250,248,239)))

dc.Clear()

dc.SetBrush(wx.Brush((187,173,160)))

dc.SetPen(wx.Pen((187,173,160)))

dc.DrawRoundedRectangle(15,150,475,475,5)#Creates a 2048 logo

defdrawLogo(self,dc):

dc.SetFont(self.bgFont)

dc.SetTextForeground((119,110,101))

dc.DrawText(u"2048",15,26)#provides text to screen (Chinese text)

defdrawLabel(self,dc):

dc.SetFont(self.smFont)

dc.SetTextForeground((119,110,101))

dc.DrawText(u"合并相同数字,得到2048吧!",15,114)

dc.DrawText(u"怎么玩: \n用->

\n当两个相同数字的方块碰到一起时,会合成一个!",15,639)#Displays score to screen

defdrawScore(self,dc):

dc.SetFont(self.smFont)

scoreLabelSize= dc.GetTextExtent(u"SCORE")

bestLabelSize= dc.GetTextExtent(u"BEST")

curScoreBoardMinW= 15*2+scoreLabelSize[0]

bstScoreBoardMinW= 15*2+bestLabelSize[0]

curScoreSize=dc.GetTextExtent(str(self.curScore))

bstScoreSize=dc.GetTextExtent(str(self.bstScore))

curScoreBoardNedW= 10+curScoreSize[0]

bstScoreBoardNedW= 10+bstScoreSize[0]

curScoreBoardW=max(curScoreBoardMinW,curScoreBoardNedW)

bstScoreBoardW=max(bstScoreBoardMinW,bstScoreBoardNedW)

dc.SetBrush(wx.Brush((187,173,160)))

dc.SetPen(wx.Pen((187,173,160)))

dc.DrawRoundedRectangle(505-15-bstScoreBoardW,40,bstScoreBoardW,50,3)

dc.DrawRoundedRectangle(505-15-bstScoreBoardW-5-curScoreBoardW,40,curScoreBoardW,50,3)

dc.SetTextForeground((238,228,218))

dc.DrawText(u"BEST",505-15-bstScoreBoardW+(bstScoreBoardW-bestLabelSize[0])/2,48)

dc.DrawText(u"SCORE",505-15-bstScoreBoardW-5-curScoreBoardW+(curScoreBoardW-scoreLabelSize[0])/2,48)

dc.SetTextForeground((255,255,255))

dc.DrawText(str(self.bstScore),505-15-bstScoreBoardW+(bstScoreBoardW-bstScoreSize[0])/2,68)

dc.DrawText(str(self.curScore),505-15-bstScoreBoardW-5-curScoreBoardW+(curScoreBoardW-curScoreSize[0])/2,68)#Put rounded rectangular tiles on screen

defdrawTiles(self,dc):

dc.SetFont(self.scFont)for row in range(4):for col in range(4):

value=self.data[row][col]

color=self.colors[value]if value==2 or value==4:

dc.SetTextForeground((119,110,101))else:

dc.SetTextForeground((255,255,255))

dc.SetBrush(wx.Brush(color))

dc.SetPen(wx.Pen(color))

dc.DrawRoundedRectangle(30+col*115,165+row*115,100,100,2)

size=dc.GetTextExtent(str(value))while size[0]>100-15*2: #changes font size based on number within tile

self.scFont = wx.Font(self.scFont.GetPointSize()*4/5,wx.SWISS,wx.NORMAL,wx.BOLD,face=u"Roboto")

dc.SetFont(self.scFont)

size=dc.GetTextExtent(str(value))if value!=0: dc.DrawText(str(value),30+col*115+(100-size[0])/2,165+row*115+(100-size[1])/2)#Draws everything to the screen

defdrawAll(self):

dc=wx.BufferedDC(wx.ClientDC(self),self.buffer)

self.drawBg(dc)

self.drawLogo(dc)

self.drawLabel(dc)

self.drawScore(dc)

self.drawTiles(dc)#Calculates current score and checks if it is the best score and if so updates

defdrawChange(self,score):

dc=wx.BufferedDC(wx.ClientDC(self),self.buffer)ifscore:

self.curScore+=scoreif self.curScore >self.bstScore:

self.bstScore=self.curScore

self.drawScore(dc)

self.drawTiles(dc)#Shows creator info

if __name__ == "__main__":

app=wx.App()

Frame(u"2048 v1.0.1 by Guolz")

app.MainLoop()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值