首页 > 编程 > Python > 正文

python儿童学游戏编程知识点总结

2019-11-25 12:49:14
字体:
来源:转载
供稿:网友

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

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

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

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

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

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

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

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

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

boxes.py

1 import pygame

import mathfrom PodSixNet.Connection import ConnectionListener,connectionfrom time import sleep# 客户端游戏类class BoxesGame(ConnectionListener):  def initSound(self):    pygame.mixer.music.load("music.wav")    self.winSound=pygame.mixer.Sound('win.wav')    self.loseSound=pygame.mixer.Sound('lose.wav')    self.placeSound=pygame.mixer.Sound('place.wav')    pygame.mixer.music.play()  # 收到来自Server的 action:close指令后调用下面方法  def Network_close(self,data):    exit()  def Network_yourturn(self,data):    self.turn=data['torf']  def Network_startgame(self,data):    self.running=True    self.num=data["player"]    self.gameid=data["gameid"]  def Network_place(self,data):    self.placeSound.play()    x=data["x"]    y=data["y"]    hv=data["is_horizontal"]    if hv:      self.boardh[y][x]=True    else:      self.boardv[y][x]=True  # 设定某个格子为自己的  def Network_win(self,data):    self.owner[data["x"]][data["y"]]="win"    self.boardh[data["y"]][data["x"]]=True    self.boardv[data["y"]][data["x"]]=True    self.boardh[data["y"]+1][data["x"]]=True    self.boardv[data["y"]][data["x"]+1]=True    self.winSound.play()    self.me+=1  def Network_lose(self,data):    self.owner[data["x"]][data["y"]]="lose"    self.boardh[data["y"]][data["x"]]=True    self.boardv[data["y"]][data["x"]]=True    self.boardh[data["y"]+1][data["x"]]=True    self.boardv[data["y"]][data["x"]+1]=True    self.loseSound.play()    self.otherplayer+=1  def __init__(self):    self.justplaced=10    pygame.init()    pygame.font.init()    width, height = 389, 489    self.me = 0    self.otherplayer = 0    self.didwin = False    self.gameid=None    self.num=None    self.num=0    self.screen = pygame.display.set_mode((width, height))    self.owner=[[0 for x in range(6)] for y in range(6)]    self.clock = pygame.time.Clock()    self.turn = True    self.running=False    self.boardh = [[False for x in range(6)] for y in range(7)]    self.boardv = [[False for x in range(7)] for y in range(6)]    print(self.boardh)    print(self.boardv)    self.initGraphics()    self.initSound()    self.drawHUD()    pygame.display.set_caption("Boxes")    # address=raw_input("Host:Port(localhost:8080):")    # try:    #   if not address:    #     host,port="localhost",3721    #   else:    #     host,port=address.split(":")    #   self.Connect((host,port))    # except:    #   print("Error Connecting to Server")    #   print("Usage: host:port")    #   print("eg 127.0.0.1;3721")    #   exit()    self.Connect()    print("Boxes client started")    while not self.running:      self.Pump()      connection.Pump()      self.running=True      sleep(0.01)      print("not running ,connecting...")    if self.num==0:      # self.turn=True      self.marker=self.greenplayer      self.othermarker=self.blueplayer    else:      self.turn=False      self.marker=self.blueplayer      self.othermarker=self.greenplayer  def initGraphics(self):    self.normallinev = pygame.image.load("normalline.png")    self.normallineh = pygame.transform.rotate(self.normallinev, -90)    self.bar_donev = pygame.image.load("bar_done.png")    self.bar_doneh = pygame.transform.rotate(self.bar_donev, -90)    self.hoverlinev = pygame.image.load("hoverline.png")    self.hoverlineh = pygame.transform.rotate(self.hoverlinev, -90)    # self.boardh[5][4]=True    # self.boardv[5][5]=True    self.separators = pygame.image.load("separators.png")    self.score_panel = pygame.image.load("score_panel.png")    self.redindicator = pygame.image.load("redindicator.png")    self.greenindicator = pygame.image.load("greenindicator.png")    self.greenplayer = pygame.image.load("greenplayer.png")    self.blueplayer = pygame.image.load("blueplayer.png")    self.winningscreen = pygame.image.load("youwin.png")    self.gameover = pygame.image.load("gameover.png")  def drawBoard(self):    for x in range(6):      for y in range(7):        if not self.boardh[y][x]:          self.screen.blit(self.normallineh, [(x) * 64 + 5, (y) * 64])        else:          self.screen.blit(self.bar_doneh, [(x) * 64 + 5, (y) * 64])    for x in range(7):      for y in range(6):        if not self.boardv[y][x]:          self.screen.blit(self.normallinev, [(x) * 64, (y) * 64 + 5])        else:          self.screen.blit(self.bar_donev, [(x) * 64, (y) * 64 + 5])  def update(self):    # 判断方格是否已经都有归属    if self.me+self.otherplayer==36:      self.didwin=True if self.me>self.otherplayer else False      return 1    self.justplaced-=1    # print('pump connect info')    connection.Pump()    self.Pump()    # print('pump connect info finish')    self.clock.tick(60)    self.screen.fill(0)    self.drawBoard()    self.drawHUD()    self.drawOwnermap()    for event in pygame.event.get():      if event.type == pygame.QUIT:        exit()    mouse = pygame.mouse.get_pos()    xpos = int(math.ceil((mouse[0] - 32) / 64.0))    ypos = int(math.ceil((mouse[1] - 32) / 64.0))    # 判断鼠标位置更接近与那条线    is_horizontal = abs(mouse[1] - ypos * 64) < abs(mouse[0] - xpos * 64)    ypos = ypos - 1 if mouse[1] - ypos * 64 < 0 and not is_horizontal else ypos    xpos = xpos - 1 if mouse[0] - ypos * 64 < 0 and is_horizontal else xpos    board = self.boardh if is_horizontal else self.boardv    isoutofbounds = False    try:      if not board[ypos][xpos]: self.screen.blit(self.hoverlineh if is_horizontal else self.hoverlinev,                            [xpos * 64 + 5 if is_horizontal else xpos * 64,                            ypos * 64 if is_horizontal else ypos * 64 + 5])    except:      isoutofbounds = True      pass    if not isoutofbounds:      alreadyplaced = board[ypos][xpos]    else:      alreadyplaced = False    # 鼠标点击时,发送place信号给自己划线    if pygame.mouse.get_pressed()[0] and not alreadyplaced and not isoutofbounds and self.turn==True and self.justplaced<=10:      self.justplaced=10      if is_horizontal:        self.boardh[ypos][xpos] = True        self.Send({"action":"place","x":xpos,"y":ypos,"is_horizontal":is_horizontal,"gameid":self.gameid,"num":self.num})      else:        self.boardv[ypos][xpos] = True        self.Send({"action":"place","x":xpos,"y":ypos,"is_horizontal":is_horizontal,"gameid":self.gameid,"num":self.num})    pygame.display.flip()  # 画记分区域  def drawHUD(self):    self.screen.blit(self.score_panel, [0, 389])    myfont = pygame.font.SysFont(None, 32)    label = myfont.render("Your turn", 1, (255, 255, 255))    self.screen.blit(label, (10, 400))    self.screen.blit(self.greenindicator if self.turn else self.redindicator ,(130, 395))    myfont64 = pygame.font.SysFont(None, 64)    myfont20 = pygame.font.SysFont(None, 20)    scoreme = myfont64.render(str(self.me), 1, (255, 255, 255))    scoreother = myfont64.render(str(self.otherplayer), 1, (255, 255, 255))    scoretextme = myfont20.render("You", 1, (255, 255, 255))    scoretextother = myfont20.render("Other Player", 1, (255, 255, 255))    self.screen.blit(scoretextme, (10, 425))    self.screen.blit(scoreme, (10, 435))    self.screen.blit(scoretextother, (280, 425))    self.screen.blit(scoreother, (280, 435))  # 给占领与被占领格子着色  def drawOwnermap(self):         for x in range(6):      for y in range(6):        if self.owner[x][y]!=0:          if self.owner[x][y]=="win":            self.screen.blit(self.marker,(x*64+5,y*64+5))          if self.owner[x][y]=="lose":            self.screen.blit(self.othermarker,(x*64+5,y*64+5))  # 游戏结束后显示gameover或winning的图案  def finished(self):    self.screen.blit(self.gameover if not self.didwin else self.winningscreen,(0,0))    while 1:      for event in pygame.event.get():        if event.type==pygame.QUIT:          exit()      pygame.display.flip()bg = BoxesGame()while 1:  if bg.update()==1:    breakbg.finished()

server.py

1 __author__ = 'Administrator'

import PodSixNet.Channelimport PodSixNet.Serverfrom time import sleep# 定义客户端通道,继承PodSixNet.Channel.Channelclass ClientChannel(PodSixNet.Channel.Channel):  def Network(self,data):    print data  def Network_place(self,data):    hv=data["is_horizontal"]    x=data["x"]    y=data["y"]    # 客户标号    num=data["num"]    # 本游戏id    self.gameid=data["gameid"]    self._server.placeLine(hv,x,y,data,self.gameid,num)  def Close(self):    self._server.close(self.gameid)# 定义游戏服务端class BoxesServer (PodSixNet.Server.Server):  channelClass = ClientChannel  def __init__(self,*args,**kwargs):    PodSixNet.Server.Server.__init__(self,*args,**kwargs)    self.games=[]    self.queue=None    self.currentIndex=0  def Connected(self,channel,addr):    print 'new connection:',channel    # 如果队列为空,则新建一局game    if self.queue==None:      self.currentIndex+=1      channel.gameid=self.currentIndex      self.queue=Game(channel,self.currentIndex)    #如果队列中已有一局game在等待,则将新连进来的channel作为第二名游戏者与等待游戏者配对,加入games[]列表,将queue清空    else:      channel.gameid=self.currentIndex      self.queue.player1=channel      self.queue.player0.Send({"action":"startgame","player":0,"gameid":self.queue.gameid})      self.queue.player1.Send({"action":"startgame","player":1,"gameid":self.queue.gameid})      self.games.append(self.queue)      self.queue=None  # def placeLine(self,is_h,x,y,data,gameid,num):  #   if num==self.turn:  #     self.turn=0 if self.turn else 1  #     self.player1.Send({"action":"yourturn","torf":True if self.turn==1 else False})  #     self.player0.Send({"action":"yourturn","torf":True if self.turn==0 else False})  #     if is_h:  #       self.boardh[y][x]=True  #     else:  #       self.boardv[y][x]=True  #     self.player0.Send(data)  #     self.player1.Send(data)  #通知GameServer哪句游戏要划线,调用游戏placeLine  def placeLine(self,is_h,x,y,data,gameid,num):    game=[a for a in self.games if gameid==a.gameid]    if len(game)==1:      game[0].placeLine(is_h,x,y,data,num)  # 关闭某局game  def close(self,gameid):    try:      game=[a for a in self.games if a.gameid==gameid][0]      game.player0.Send({"action":"close"})      game.player1.Send({"action":"close"})    except:      pass  # 判断方格归属  def tick(self):    index=0    # 状态未改变 code 3    change=3    # 扫描每局游戏    for game in self.games:      change=3      # 扫描2次,因为存在放置一个线条完成两个方格占领的情况      for time in range(2):        for y in range(6):          for x in range(6):            # 判断是否是新围成的方格            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]:              # 是否为己方围成的,围成的一方可以继续走一步              # 此处self.games[index]能否替换为game?              if self.games[index].turn==0:                self.games[index].owner[x][y]=2                game.player1.Send({"action":"win","x":x,"y":y})                game.player0.Send({"action":"lose","x":x,"y":y})                change=1                print("player1 win 1 grid")              else:                self.games[index].owner[x][y]=1                game.player0.Send({"action":"win","x":x,"y":y})                game.player1.Send({"action":"lose","x":x,"y":y})                change=0                print("player0 win 1 grid")      # 如果状态改变了(即有一方完成了方格占领)则下一步仍由该方走棋;否则正常交替走棋      self.games[index].turn=change if change!=3 else self.games[index].turn      game.player1.Send({"action":"yourturn","torf":True if self.games[index].turn==1 else False})      game.player0.Send({"action":"yourturn","torf":True if self.games[index].turn==0 else False})      index+=1    self.Pump()# 单纯一局游戏的控制类class Game:  def __init__(self,player0,currentIndex):    self.turn=0    self.owner=[[False for x in range(6)] for y in range(6)]    self.boardh=[[False for x in range(6)] for y in range(7)]    self.boardv=[[False for x in range(7)] for y in range(6)]    self.player0=player0    self.player1=None    self.gameid=currentIndex    # while not self.running:    #   self.Pump()    #   connection.Pump()    #   sleep(0.01)    # if self.num==0:    #   self.turn=True    #   self.marker=self.greenplayer    #   self.othermarker=self.blueplayer    # else:    #   self.turn=False    #   self.marker=self.blueplayer    #   self.othermarker=self.greenplayer  # 划线  def placeLine(self,is_h,x,y,data,num):    if num==self.turn:      self.turn=0 if self.turn else 1      self.player1.Send({"action":"yourturn","torf":True if self.turn==1 else False})      self.player0.Send({"action":"yourturn","torf":True if self.turn==0 else False})      if is_h:        self.boardh[y][x]=True      else:        self.boardv[y][x]=True      self.player0.Send(data)      self.player1.Send(data)  # def Network_palce(self,data):  #   x=data["x"]  #   y=data["y"]  #   hv=data["is_horizontal"]  #   if hv:  #     self.boardh[y][x]=True  #   else:  #     self.boardv[y][x]=Trueprint "Staring server on localhost"address=raw_input("Host:Port(localhost:8080):")if not address:  host,port="localhost",31425  print("default host and port")  print(host,":",port)else:  host,port=address.split(":")  print(host,":",port)boxesServer=BoxesServer( localaddr=("127.0.0.1", 31425))# boxesServer=BoxesServer()while True:  boxesServer.Pump()  boxesServer.tick()  sleep(0.01) 就是这样,休息,休息一下。

以上就是本次介绍的儿童学习python游戏编程的全部知识点内容,感谢大家对武林网的支持。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表