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

以上是 python儿童学游戏编程知识点总结 的全部内容, 来源链接: utcz.com/z/351943.html

回到顶部