• 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)

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

  • 相关阅读:
    005本周总结报告
    《大道至简》读后感
    004本周总结报告
    003本周总结报告
    002本周总结报告
    001本周总结报告
    【财经】股市是不是零和博弈?
    【Spring】使用Spring的AbstractRoutingDataSource实现多数据源切换
    【Java每日一题】20170217
    【Java每日一题】20170216
  • 原文地址:https://www.cnblogs.com/javajava/p/4988556.html
Copyright © 2020-2023  润新知