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


Posted in Python onJune 03, 2019

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

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

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

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

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

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

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

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

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

boxes.py

1 import pygame

import math
from PodSixNet.Connection import ConnectionListener,connection
from 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:
    break
bg.finished()

server.py

1 __author__ = 'Administrator'

import PodSixNet.Channel
import PodSixNet.Server
from time import sleep

# 定义客户端通道,继承PodSixNet.Channel.Channel
class 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]=True


print "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游戏编程的全部知识点内容,感谢大家对三水点靠木的支持。

Python 相关文章推荐
Python创建日历实例
Aug 21 Python
使用Django的模版来配合字符串翻译工作
Jul 27 Python
sublime text 3配置使用python操作方法
Jun 11 Python
pandas数据处理基础之筛选指定行或者指定列的数据
May 03 Python
Linux(Redhat)安装python3.6虚拟环境(推荐)
May 05 Python
利用ctypes获取numpy数组的指针方法
Feb 12 Python
Python实现堡垒机模式下远程命令执行操作示例
May 09 Python
Python3进制之间的转换代码实例
Aug 24 Python
python 如何区分return和yield
Sep 22 Python
python 下划线的不同用法
Oct 24 Python
pyqt5实现井字棋的示例代码
Dec 07 Python
Python urlopen()参数代码示例解析
Dec 10 Python
Python控制Firefox方法总结
Jun 03 #Python
python+webdriver自动化环境搭建步骤详解
Jun 03 #Python
selenium+python自动化测试环境搭建步骤
Jun 03 #Python
python+selenium实现自动化百度搜索关键词
Jun 03 #Python
用Q-learning算法实现自动走迷宫机器人的方法示例
Jun 03 #Python
Python多进程方式抓取基金网站内容的方法分析
Jun 03 #Python
Python多进程入门、分布式进程数据共享实例详解
Jun 03 #Python
You might like
声音就能俘获人心,蕾姆,是哪个漂亮小姐姐配音呢?
2020/03/03 日漫
使用array_map简单搞定PHP删除文件、删除目录
2014/10/29 PHP
php实现指定字符串中查找子字符串的方法
2015/03/17 PHP
PHP YII框架开发小技巧之模型(models)中rules自定义验证规则
2015/11/16 PHP
symfony2.4的twig中date用法分析
2016/03/18 PHP
使用PHP访问RabbitMQ消息队列的方法示例
2018/06/06 PHP
PHP用swoole+websocket和redis实现web一对一聊天
2019/11/05 PHP
Jquery实现搜索框提示功能示例代码
2013/08/13 Javascript
原生JavaScript实现滚动条效果
2020/03/24 Javascript
在页面中输出当前客户端时间javascript实例代码
2016/03/02 Javascript
javascript弹出窗口中增加确定取消按钮
2016/06/24 Javascript
Servlet实现文件上传,可多文件上传示例
2016/12/05 Javascript
原生JS实现小小的音乐播放器
2017/10/16 Javascript
如何在vue中使用ts的示例代码
2018/02/28 Javascript
vue2.0 循环遍历加载不同图片的方法
2018/03/06 Javascript
优雅的使用javascript递归画一棵结构树示例代码
2019/09/22 Javascript
[06:06]2018DOTA2亚洲邀请赛主赛事第四日战况回顾 全明星赛欢乐上演
2018/04/07 DOTA
python 正则表达式 概述及常用字符
2009/05/04 Python
跟老齐学Python之编写类之四再论继承
2014/10/11 Python
python使用装饰器和线程限制函数执行时间的方法
2015/04/18 Python
Python随手笔记第一篇(2)之初识列表和元组
2016/01/23 Python
Python画图实现同一结点多个柱状图的示例
2019/07/07 Python
Pytorch 保存模型生成图片方式
2020/01/10 Python
查看已安装tensorflow版本的方法示例
2020/04/19 Python
Python实现简单的猜单词小游戏
2020/10/28 Python
python des,aes,rsa加解密的实现
2021/01/16 Python
实现strstr功能,即在父串中寻找子串首次出现的位置
2016/08/05 面试题
实习求职信
2013/12/01 职场文书
作弊检讨书1000字
2014/02/01 职场文书
娱乐节目策划方案
2014/06/10 职场文书
2014党员学习《反腐倡廉警示教育读本》思想汇报
2014/09/13 职场文书
师德师风培训感言
2015/08/03 职场文书
幼儿园教师心得体会范文
2016/01/21 职场文书
成功的商业计划书这样写才最靠谱
2019/07/12 职场文书
mysql事务隔离级别详情
2021/10/24 MySQL
解决vue中provide inject的响应式监听
2022/04/19 Vue.js