网络编程
位置:首页>> 网络编程>> Python编程>> python儿童学游戏编程知识点总结

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

作者:laozhang  发布时间:2022-10-23 04:32:42 

标签:儿童,python编程

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) 就是这样,休息,休息一下。
0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com