python游戏编程——跟13岁儿童学编程

python爬虫基本告一段落,琢磨搞点其他的,正好在网上看到一个帖子,一个外国13岁小朋友用python写的下棋程序,内容详细,也有意思,拿来练手。

13岁啊。。 我这年纪还在敲 dir啥的吧

想到原先玩跑跑卡丁车时看到欧酷有个4岁熊孩子玩的完美漂移录像,深受打击,从此退出车坛。。。

废话不多说,记录一下这几天的游戏编程折腾史

原帖: http://blog.jobbole.com/80379/    《13岁Python开发者写给青少年的Python入门教程》

 

游戏规则:6*6的方格棋盘,两个人轮流点击棋盘画横线或竖线,谁成功围成一个格子,这个格子算作此人的积分。

游戏架构:客户端和服务端。

先来看下游戏准备工作,需要用到pygame这个python包。

下载小朋友准备的Resource文件,游戏用到的图片、声音啥的。 

一下为BoxGame(客户端)和Server代码,已添加注释。 

 boxes.py

   1 import pygame

  2  import math
  3  from PodSixNet.Connection  import ConnectionListener,connection
  4  from time  import sleep
  5 
  6  #  客户端游戏类
  7  class BoxesGame(ConnectionListener):
  8      def initSound(self):
  9         pygame.mixer.music.load( " music.wav ")
 10         self.winSound=pygame.mixer.Sound( ' win.wav ')
 11         self.loseSound=pygame.mixer.Sound( ' lose.wav ')
 12         self.placeSound=pygame.mixer.Sound( ' place.wav ')
 13         pygame.mixer.music.play()
 14      #  收到来自Server的 action:close指令后调用下面方法
 15       def Network_close(self,data):
 16         exit()
 17      def Network_yourturn(self,data):
 18         self.turn=data[ ' torf ']
 19      def Network_startgame(self,data):
 20         self.running=True
 21         self.num=data[ " player "]
 22         self.gameid=data[ " gameid "]
 23      def Network_place(self,data):
 24         self.placeSound.play()
 25         x=data[ " x "]
 26         y=data[ " y "]
 27         hv=data[ " is_horizontal "]
 28          if hv:
 29             self.boardh[y][x]=True
 30          else:
 31             self.boardv[y][x]=True
 32      #  设定某个格子为自己的
 33       def Network_win(self,data):
 34         self.owner[data[ " x "]][data[ " y "]]= " win "
 35         self.boardh[data[ " y "]][data[ " x "]]=True
 36         self.boardv[data[ " y "]][data[ " x "]]=True
 37         self.boardh[data[ " y "]+1][data[ " x "]]=True
 38         self.boardv[data[ " y "]][data[ " x "]+1]=True
 39         self.winSound.play()
 40         self.me+=1
 41      def Network_lose(self,data):
 42         self.owner[data[ " x "]][data[ " y "]]= " lose "
 43         self.boardh[data[ " y "]][data[ " x "]]=True
 44         self.boardv[data[ " y "]][data[ " x "]]=True
 45         self.boardh[data[ " y "]+1][data[ " x "]]=True
 46         self.boardv[data[ " y "]][data[ " x "]+1]=True
 47         self.loseSound.play()
 48         self.otherplayer+=1
 49 
 50      def  __init__(self):
 51         self.justplaced=10
 52         pygame.init()
 53         pygame.font.init()
 54         width, height = 389, 489
 55         self.me = 0
 56         self.otherplayer = 0
 57         self.didwin = False
 58         self.gameid=None
 59         self.num=None
 60         self.num=0
 61         self.screen = pygame.display.set_mode((width, height))
 62         self.owner=[[0  for x  in range(6)]  for y  in range(6)]
 63         self.clock = pygame.time.Clock()
 64         self.turn = True
 65         self.running=False
 66         self.boardh = [[False  for x  in range(6)]  for y  in range(7)]
 67         self.boardv = [[False  for x  in range(7)]  for y  in range(6)]
 68          print(self.boardh)
 69          print(self.boardv)
 70         self.initGraphics()
 71         self.initSound()
 72         self.drawHUD()
 73         pygame.display.set_caption( " Boxes ")
 74 
 75          #  address=raw_input("Host:Port(localhost:8080):")
 76           #  try:
 77           #      if not address:
 78           #          host,port="localhost",3721
 79           #      else:
 80           #          host,port=address.split(":")
 81           #      self.Connect((host,port))
 82           #  except:
 83           #      print("Error Connecting to Server")
 84           #      print("Usage: host:port")
 85           #      print("eg 127.0.0.1;3721")
 86           #      exit()
 87          self.Connect()
 88          print( " Boxes client started ")
 89          while  not self.running:
 90             self.Pump()
 91             connection.Pump()
 92             self.running=True
 93             sleep(0.01)
 94              print( " not running ,connecting... ")
 95          if self.num==0:
 96              #  self.turn=True
 97              self.marker=self.greenplayer
 98             self.othermarker=self.blueplayer
 99          else:
100             self.turn=False
101             self.marker=self.blueplayer
102             self.othermarker=self.greenplayer
103 
104 
105      def initGraphics(self):
106         self.normallinev = pygame.image.load( " normalline.png ")
107         self.normallineh = pygame.transform.rotate(self.normallinev, -90)
108         self.bar_donev = pygame.image.load( " bar_done.png ")
109         self.bar_doneh = pygame.transform.rotate(self.bar_donev, -90)
110         self.hoverlinev = pygame.image.load( " hoverline.png ")
111         self.hoverlineh = pygame.transform.rotate(self.hoverlinev, -90)
112          #  self.boardh[5][4]=True
113           #  self.boardv[5][5]=True
114          self.separators = pygame.image.load( " separators.png ")
115         self.score_panel = pygame.image.load( " score_panel.png ")
116         self.redindicator = pygame.image.load( " redindicator.png ")
117         self.greenindicator = pygame.image.load( " greenindicator.png ")
118         self.greenplayer = pygame.image.load( " greenplayer.png ")
119         self.blueplayer = pygame.image.load( " blueplayer.png ")
120         self.winningscreen = pygame.image.load( " youwin.png ")
121         self.gameover = pygame.image.load( " gameover.png ")
122 
123      def drawBoard(self):
124          for x  in range(6):
125              for y  in range(7):
126                  if  not self.boardh[y][x]:
127                     self.screen.blit(self.normallineh, [(x) * 64 + 5, (y) * 64])
128                  else:
129                     self.screen.blit(self.bar_doneh, [(x) * 64 + 5, (y) * 64])
130          for x  in range(7):
131              for y  in range(6):
132                  if  not self.boardv[y][x]:
133                     self.screen.blit(self.normallinev, [(x) * 64, (y) * 64 + 5])
134                  else:
135                     self.screen.blit(self.bar_donev, [(x) * 64, (y) * 64 + 5])
136 
137      def update(self):
138          #  判断方格是否已经都有归属
139           if self.me+self.otherplayer==36:
140             self.didwin=True  if self.me>self.otherplayer  else False
141              return 1
142         self.justplaced-=1
143          #  print('pump connect info')
144          connection.Pump()
145         self.Pump()
146          #  print('pump connect info finish')
147          self.clock.tick(60)
148         self.screen.fill(0)
149         self.drawBoard()
150         self.drawHUD()
151         self.drawOwnermap()
152          for event  in pygame.event.get():
153              if event.type == pygame.QUIT:
154                 exit()
155 
156         mouse = pygame.mouse.get_pos()
157         xpos = int(math.ceil((mouse[0] - 32) / 64.0))
158         ypos = int(math.ceil((mouse[1] - 32) / 64.0))
159          #  判断鼠标位置更接近与那条线
160          is_horizontal = abs(mouse[1] - ypos * 64) < abs(mouse[0] - xpos * 64)
161         ypos = ypos - 1  if mouse[1] - ypos * 64 < 0  and  not is_horizontal  else ypos
162         xpos = xpos - 1  if mouse[0] - ypos * 64 < 0  and is_horizontal  else xpos
163 
164         board = self.boardh  if is_horizontal  else self.boardv
165         isoutofbounds = False
166 
167          try:
168              if  not board[ypos][xpos]: self.screen.blit(self.hoverlineh  if is_horizontal  else self.hoverlinev,
169                                                        [xpos * 64 + 5  if is_horizontal  else xpos * 64,
170                                                         ypos * 64  if is_horizontal  else ypos * 64 + 5])
171          except:
172             isoutofbounds = True
173              pass
174          if  not isoutofbounds:
175             alreadyplaced = board[ypos][xpos]
176          else:
177             alreadyplaced = False
178          #  鼠标点击时,发送place信号给自己划线
179           if pygame.mouse.get_pressed()[0]  and  not alreadyplaced  and  not isoutofbounds  and self.turn==True  and self.justplaced<=10:
180             self.justplaced=10
181              if is_horizontal:
182                 self.boardh[ypos][xpos] = True
183                 self.Send({ " action ": " place ", " x ":xpos, " y ":ypos, " is_horizontal ":is_horizontal, " gameid ":self.gameid, " num ":self.num})
184              else:
185                 self.boardv[ypos][xpos] = True
186                 self.Send({ " action ": " place ", " x ":xpos, " y ":ypos, " is_horizontal ":is_horizontal, " gameid ":self.gameid, " num ":self.num})
187         pygame.display.flip()
188      #  画记分区域
189       def drawHUD(self):
190         self.screen.blit(self.score_panel, [0, 389])
191         myfont = pygame.font.SysFont(None, 32)
192         label = myfont.render( " Your turn ", 1, (255, 255, 255))
193         self.screen.blit(label, (10, 400))
194         self.screen.blit(self.greenindicator  if self.turn  else self.redindicator ,(130, 395))
195         myfont64 = pygame.font.SysFont(None, 64)
196         myfont20 = pygame.font.SysFont(None, 20)
197 
198         scoreme = myfont64.render(str(self.me), 1, (255, 255, 255))
199         scoreother = myfont64.render(str(self.otherplayer), 1, (255, 255, 255))
200         scoretextme = myfont20.render( " You ", 1, (255, 255, 255))
201         scoretextother = myfont20.render( " Other Player ", 1, (255, 255, 255))
202 
203         self.screen.blit(scoretextme, (10, 425))
204         self.screen.blit(scoreme, (10, 435))
205         self.screen.blit(scoretextother, (280, 425))
206         self.screen.blit(scoreother, (280, 435))
207      #  给占领与被占领格子着色
208       def drawOwnermap(self):         
209          for x  in range(6):
210              for y  in range(6):
211                  if self.owner[x][y]!=0:
212                      if self.owner[x][y]== " win ":
213                         self.screen.blit(self.marker,(x*64+5,y*64+5))
214                      if self.owner[x][y]== " lose ":
215                         self.screen.blit(self.othermarker,(x*64+5,y*64+5))
216      #  游戏结束后显示gameover或winning的图案
217       def finished(self):
218         self.screen.blit(self.gameover  if  not self.didwin  else self.winningscreen,(0,0))
219          while 1:
220              for event  in pygame.event.get():
221                  if event.type==pygame.QUIT:
222                     exit()
223             pygame.display.flip()
224 
225 
226 bg = BoxesGame()
227  while 1:
228      if bg.update()==1:
229          break
230 bg.finished()

server.py

   1 __author__ = 'Administrator'

  2  import PodSixNet.Channel
  3  import PodSixNet.Server
  4  from time  import sleep
  5 
  6  #  定义客户端通道,继承PodSixNet.Channel.Channel
  7  class ClientChannel(PodSixNet.Channel.Channel):
  8      def Network(self,data):
  9          print data
 10      def Network_place(self,data):
 11         hv=data[ " is_horizontal "]
 12         x=data[ " x "]
 13         y=data[ " y "]
 14          #  客户标号
 15          num=data[ " num "]
 16          #  本游戏id
 17          self.gameid=data[ " gameid "]
 18         self._server.placeLine(hv,x,y,data,self.gameid,num)
 19      def Close(self):
 20         self._server.close(self.gameid)
 21 
 22  #  定义游戏服务端
 23  class BoxesServer (PodSixNet.Server.Server):
 24     channelClass = ClientChannel
 25      def  __init__(self,*args,**kwargs):
 26         PodSixNet.Server.Server. __init__(self,*args,**kwargs)
 27         self.games=[]
 28         self.queue=None
 29         self.currentIndex=0
 30      def Connected(self,channel,addr):
 31          print  ' new connection: ',channel
 32          #  如果队列为空,则新建一局game
 33           if self.queue==None:
 34             self.currentIndex+=1
 35             channel.gameid=self.currentIndex
 36             self.queue=Game(channel,self.currentIndex)
 37          # 如果队列中已有一局game在等待,则将新连进来的channel作为第二名游戏者与等待游戏者配对,加入games[]列表,将queue清空
 38           else:
 39             channel.gameid=self.currentIndex
 40             self.queue.player1=channel
 41             self.queue.player0.Send({ " action ": " startgame ", " player ":0, " gameid ":self.queue.gameid})
 42             self.queue.player1.Send({ " action ": " startgame ", " player ":1, " gameid ":self.queue.gameid})
 43             self.games.append(self.queue)
 44             self.queue=None
 45      #  def placeLine(self,is_h,x,y,data,gameid,num):
 46       #      if num==self.turn:
 47       #          self.turn=0 if self.turn else 1
 48       #          self.player1.Send({"action":"yourturn","torf":True if self.turn==1 else False})
 49       #          self.player0.Send({"action":"yourturn","torf":True if self.turn==0 else False})
 50       #          if is_h:
 51       #              self.boardh[y][x]=True
 52       #          else:
 53       #              self.boardv[y][x]=True
 54       #          self.player0.Send(data)
 55       #          self.player1.Send(data)
 56 
 57      # 通知GameServer哪句游戏要划线,调用游戏placeLine
 58       def placeLine(self,is_h,x,y,data,gameid,num):
 59         game=[a  for a  in self.games  if gameid==a.gameid]
 60          if len(game)==1:
 61             game[0].placeLine(is_h,x,y,data,num)
 62      #  关闭某局game
 63       def close(self,gameid):
 64          try:
 65             game=[a  for a  in self.games  if a.gameid==gameid][0]
 66             game.player0.Send({ " action ": " close "})
 67             game.player1.Send({ " action ": " close "})
 68          except:
 69              pass
 70      #  判断方格归属
 71       def tick(self):
 72         index=0
 73          #  状态未改变 code 3
 74          change=3
 75          #  扫描每局游戏
 76           for game  in self.games:
 77             change=3
 78              #  扫描2次,因为存在放置一个线条完成两个方格占领的情况
 79               for time  in range(2):
 80                  for y  in range(6):
 81                      for x  in range(6):
 82                          #  判断是否是新围成的方格
 83                           if game.boardh[y][x]  and game.boardv[y][x]  and game.boardh[y+1][x]   and game.boardv[y][x+1]  and  not game.owner[x][y]:
 84                              #  是否为己方围成的,围成的一方可以继续走一步
 85                               #  此处self.games[index]能否替换为game?
 86                               if self.games[index].turn==0:
 87                                 self.games[index].owner[x][y]=2
 88                                 game.player1.Send({ " action ": " win ", " x ":x, " y ":y})
 89                                 game.player0.Send({ " action ": " lose ", " x ":x, " y ":y})
 90                                 change=1
 91                                  print( " player1 win 1 grid ")
 92                              else:
 93                                 self.games[index].owner[x][y]=1
 94                                 game.player0.Send({ " action ": " win ", " x ":x, " y ":y})
 95                                 game.player1.Send({ " action ": " lose ", " x ":x, " y ":y})
 96                                 change=0
 97                                  print( " player0 win 1 grid ")
 98              #  如果状态改变了(即有一方完成了方格占领)则下一步仍由该方走棋;否则正常交替走棋
 99              self.games[index].turn=change  if change!=3  else self.games[index].turn
100             game.player1.Send({ " action ": " yourturn ", " torf ":True  if self.games[index].turn==1  else False})
101             game.player0.Send({ " action ": " yourturn ", " torf ":True  if self.games[index].turn==0  else False})
102             index+=1
103         self.Pump()
104 
105  #  单纯一局游戏的控制类
106  class Game:
107      def  __init__(self,player0,currentIndex):
108         self.turn=0
109         self.owner=[[False  for x  in range(6)]  for y  in range(6)]
110         self.boardh=[[False  for x  in range(6)]  for y  in range(7)]
111         self.boardv=[[False  for x  in range(7)]  for y  in range(6)]
112         self.player0=player0
113         self.player1=None
114         self.gameid=currentIndex
115 
116 
117          #  while not self.running:
118           #      self.Pump()
119           #      connection.Pump()
120           #      sleep(0.01)
121           #  if self.num==0:
122           #      self.turn=True
123           #      self.marker=self.greenplayer
124           #      self.othermarker=self.blueplayer
125           #  else:
126           #      self.turn=False
127           #      self.marker=self.blueplayer
128           #      self.othermarker=self.greenplayer
129       #  划线
130       def placeLine(self,is_h,x,y,data,num):
131          if num==self.turn:
132             self.turn=0  if self.turn  else 1
133             self.player1.Send({ " action ": " yourturn ", " torf ":True  if self.turn==1  else False})
134             self.player0.Send({ " action ": " yourturn ", " torf ":True  if self.turn==0  else False})
135              if is_h:
136                 self.boardh[y][x]=True
137              else:
138                 self.boardv[y][x]=True
139             self.player0.Send(data)
140             self.player1.Send(data)
141      #  def Network_palce(self,data):
142       #      x=data["x"]
143       #      y=data["y"]
144       #      hv=data["is_horizontal"]
145       #      if hv:
146       #          self.boardh[y][x]=True
147       #      else:
148       #          self.boardv[y][x]=True
149 
150 
151  print  " Staring server on localhost "
152 address=raw_input( " Host:Port(localhost:8080): ")
153  if  not address:
154     host,port= " localhost ",31425
155      print( " default host and port ")
156      print(host, " : ",port)
157  else:
158     host,port=address.split( " : ")
159      print(host, " : ",port)
160 
161 boxesServer=BoxesServer( localaddr=( " 127.0.0.1 ", 31425))
162  #  boxesServer=BoxesServer()
163  while True:
164     boxesServer.Pump()
165     boxesServer.tick()
166     sleep(0.01)

 

就是这样,休息,休息一下。 

 

转载于:https://www.cnblogs.com/javajava/p/4988556.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值