- 浏览: 114378 次
- 性别:
- 来自: 广州
最新评论
-
my251394667:
请问用你这个函数如何绘制图啊
穿过已知点画平滑曲线(3次贝塞尔曲线) -
nima123321:
网上的人,发发代码就算了,但是最起码标明一个该代码是否能用嘛. ...
C++版socket -
westice:
JiangNanDeXue 写道你说这段代码是再国外网站上挡下 ...
OpenCV笔记: 查找轮廓 -
JiangNanDeXue:
你说这段代码是再国外网站上挡下来的,请问是哪个网站?谢谢。还望 ...
OpenCV笔记: 查找轮廓 -
fg5823820:
C++ 能这样创建数组么
穿过已知点画平滑曲线(3次贝塞尔曲线)
这个游戏很简单,可以操纵的飞机不断发子弹,前面不断有敌机来袭,子弹打中敌机然后敌机和子弹消失,最后实现了网络互联功能,允许两个人在局域网中不同机器上操作各自的飞机,平且两个游戏界面是同步的。
我这样设计的:自己维护一个飞机,子弹队列,敌机队列,将网络来的数据打包成另一个飞机,子弹队列,敌机队列,所以这里面传送的数据有自己飞机数据,子弹队列,敌机队列,这些数据通过TCP在服务器和客户端之间不断更新,传递。
图形用opengl渲染,由于python不能直接访问指针,通过网络只能传递字符串型,所以传送二进制数据有点问题,自己写了对函数,用于字符串和二进制数的转换,每个数由长度为4的字符串组成,索引高的为数据高位,最高位为符号位,所以只能保存-1600万到1600万之间的数,对于视频游戏这个范围足矣,但有个缺陷,不知道怎么传浮点数,所以需要浮点数的地方先*1000,传送后除以1000得到浮点数。
为了更像网络游戏,跟CS一样能自动搜索局域网中的服务器,实现了一个较简单实用的方法,大致是这样的:服务器启动后开放一个udp端口udpport,客户端向局域网中所有机器udpport发送验证信息,建立一个临时TCP端口tcpport0,当服务器端客户验证通过后向刚才的客户机tcpport0发送欢迎信息,这样客户机就得到了服务器的ip地址(还可同时进行一些必要的初始化),到此客户端便开始正式通过tcp与服务器交换游戏信息。
pyOpengl安装方法:http://pyopengl.sourceforge.net/documentation/installation.html
游戏代码:
#-*- coding:utf-8 -*- import sys,struct import random,math,thread,time,socket,string,re try: from OpenGL.GLUT import * from OpenGL.GL import * from OpenGL.GLU import * except: print ''' ERROR: PyOpenGL not installed properly. ''' sys.exit() x_coord=10 y_coord=10 isAserver=False #True为服务端,False为客户端 #数值统统为4个字节,最高位为符号位,1600万足矣,低字节为低位 def westicenumtostring(num): tempnum=abs(num) tempnum=int(tempnum) s='' i=0 while tempnum>0: s=s+chr(tempnum%256) tempnum=int(tempnum/256) i+=1 while len(s)<3:#补齐3位 s=s+chr(0) if num<0: s=s+chr(1) else:#0和正数最高位为0 s=s+chr(0) return s def westicestringtonum(s): if len(s)!=4: print 'len(s) must be 4' return None n0=ord(s[0]) n1=ord(s[1]) n2=ord(s[2]) n3=ord(s[3]) num=n0+256*n1+256*256*n2 if n3==1:#负数 num=(-num) if n3!=0 and n3!=1: return "wrong string when convert ro number" return num def drawenemy(x,y): #画敌人形象 glLoadIdentity() glTranslate(x,y,0.0) glScale(0.2,0.2,0.2) glBegin(GL_POLYGON) glVertex3f(1.0,1.0,0) glVertex3f(1.0,-1.0,0) glColor3f(1.0,0.0,0.0) glVertex3f(-1.0,-1.0,0) glVertex3f(-1.0,1.0,0) glEnd() def drawbullet(x,y):#画子弹形象 glLoadIdentity() glTranslate(x,y,0.0) glScale(0.1,0.1,0.1) glBegin(GL_POLYGON) glColor3f(0.0,1.0,0.0) glVertex3f(0.5,1.0,0) glVertex3f(0.5,-1.0,0) glVertex3f(-0.5,-1.0,0) glVertex3f(-0.5,1.0,0) glEnd() def drawpalne(x,y,rquad):#画玩家飞机形象 glLoadIdentity() glTranslate(x,y,0.0) glRotatef(rquad,0.0,1.0,0.0) # Rotate glScale(0.5,0.5,0.5) glBegin(GL_POLYGON) # Start drawing glColor3f(1.0,0.0,0.0) glVertex3f(1.0,0.0,0.0) glColor3f(0.0,1.0,0.0) glVertex3f(-1.0,0.0,0.0) glColor3f(0.0,0.0,1.0) glVertex3f(0.0,3.0,0.0) glEnd() # We are done with the polygon glBegin(GL_POLYGON) glVertex3f(0.0,0.0,0) glVertex3f(0.0,3.0,0) glColor3f(1.0,0.0,0.0) glVertex3f(0.0,0.5,0.5) glEnd() class Enemy(): #定义敌人 def __init__(self): self.reset() def update(self): if self.live: self.y-=0.01 self.draw() if self.y<0: self.live=False def setxy(self,x,y): self.x=x self.y=y def draw(self): drawenemy(self.x,self.y) def reset(self): self.x=x_coord*random.random() self.y=y_coord self.live=True #活着状态 class Bullet():#定义子弹 def __init__(self,x,y): self.reset(x,y) self.live=False def update(self): if self.live: self.y+=0.05 self.draw() if self.y>y_coord: self.live=False def draw(self): drawbullet(self.x,self.y) def reset(self,x,y): self.x=x self.y=y self.live=True class Plane(): def __init__(self,x,y): self.x=x self.y=y self.rquad=0 def update(self): self.draw() if self.rquad<0: self.rquad+=1.0 if self.rquad>0: self.rquad-=1.0 def draw(self): drawpalne(self.x,self.y,self.rquad) def left(self): self.x-=0.1 if self.rquad>-40:#限制 self.rquad-=3 def right(self): self.x+=0.1 if self.rquad<40: self.rquad+=3 westiceplane=None myenemylist=None bulletlist=None otherplane=None otherenemylist=None otherbulletlist=None frameobj=None #网络用帧 class netframe(): def __init__(self,player,mybulletlist,enemylist): self.player=player self.mybulletlist=mybulletlist self.enemylist=enemylist def senddata(self,conn): global isconnected senddata='' senddata+=westicenumtostring(self.player.x*1000) senddata+=westicenumtostring(self.player.y*1000) senddata+=westicenumtostring(self.player.rquad*1000)#自己的位置 senddata+=westicenumtostring(len(self.mybulletlist))#子弹个数 for bullet in self.mybulletlist: senddata+=westicenumtostring(bullet.x*1000) senddata+=westicenumtostring(bullet.y*1000)#子弹位置 senddata+=westicenumtostring(len(self.enemylist))#敌人个数 for enemy in self.enemylist: senddata+=westicenumtostring(enemy.x*1000) senddata+=westicenumtostring(enemy.y*1000)#敌人位置 if isconnected: try: conn.send(senddata) except socket.error: isconnected=False #conn.sendall(senddata) #接收数据 def recvdata(self,conn): global otherplane global otherenemylist global otherbulletlist global isconnected if isconnected: try: recvdata=conn.recv(4) otherplanex=westicestringtonum(recvdata)/1000.0 recvdata=conn.recv(4) otherplaney=westicestringtonum(recvdata)/1000.0 otherplane=Plane(otherplanex,otherplaney) recvdata=conn.recv(4) otherplane.rquad=westicestringtonum(recvdata)/1000.0 recvdata=conn.recv(4)#接收子弹数据 bulletnum=westicestringtonum(recvdata) otherbulletlist=[] for i in range(bulletnum): recvdata=conn.recv(4) bulletx=westicestringtonum(recvdata)/1000.0 recvdata=conn.recv(4) bullety=westicestringtonum(recvdata)/1000.0 bullet=Bullet(bulletx,bullety) bullet.live=True otherbulletlist.append(bullet) recvdata=conn.recv(4) enemynum=westicestringtonum(recvdata) otherenemylist=[] for i in range(enemynum): recvdata=conn.recv(4) enemyx=westicestringtonum(recvdata)/1000.0 recvdata=conn.recv(4) enemyy=westicestringtonum(recvdata)/1000.0 enemy=Enemy() enemy.setxy(enemyx,enemyy) otherenemylist.append(enemy) except socket.error: isconnected=False #游戏服务器 port=8088 #主数据通道 conn=None#socket连接对象,可能是服务器或客户端 serverUDPport=9090 clientTCPport=9091 isconnected=False class GameServer(): def __init__(self): print '初始化游戏服务器' global conn global otherplane global otherenemylist global otherbulletlist global frameobj global isconnected global serverUDPport global clientTCPport #服务器接收客户UDP报文,如果验证通过向客户发送TCP回应 UDPsock0=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) UDPsock0.bind(("",serverUDPport)) #还需验证客户端,用udp recvstring,clientaddr=UDPsock0.recvfrom(1024) if recvstring=="west": print "服务器收到验证from ",clientaddr[0] UDPsock0.close() #服务器发送tcp回应 tempconn=socket.socket(socket.AF_INET,socket.SOCK_STREAM) tempconn.connect((clientaddr[0],clientTCPport)) tempconn.send("sure") tempconn.close() #创建TCP服务器 TCPsock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) TCPsock.bind(('',port)) TCPsock.listen(5) conn,clientaddr=TCPsock.accept() print "来自客户端:",clientaddr isconnected=True while isconnected: #服务端循环,先发后收 frameobj.senddata(conn) time.sleep(0.02) frameobj.recvdata(conn) conn.close() #游戏客户端 class GameClient(): def __init__(self): print '初始化游戏客户端' global conn global frameobj global isconnected global serverUDPport global clientTCPport self.lanserverip=None #搜索服务器,向局域网内发送udp数据 ip=socket.gethostbyname(socket.gethostname()) match_str="\d+\.\d+\.\d+\." ipheader=re.match(match_str,ip) ipheader=ipheader.group() UDPsock0=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) for i in range(1,256): self.lanserverip=ipheader+str(i) UDPsock0.sendto("west",(self.lanserverip,serverUDPport)) UDPsock0.close() #客户端建立tcp服务器 接收服务器ip和其它信息,之后断开,连接服务器的tcp TCPsock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) TCPsock.bind(('',clientTCPport)) TCPsock.listen(5) tempconn,serveraddr=TCPsock.accept() hellomsg=tempconn.recv(4) tempconn.close() self.lanserverip=serveraddr[0] print "服务器为:",self.lanserverip print "服务器信息:",hellomsg #连接tcp服务器发送数据 conn=socket.socket(socket.AF_INET,socket.SOCK_STREAM) conn.connect((self.lanserverip,port)) isconnected=True while isconnected:#客户端循环,先收后发 frameobj.recvdata(conn) frameobj.senddata(conn) time.sleep(0.02) conn.close() def threadfunc():#线程函数 global isAserver if isAserver: gameserver=GameServer() else: gameclient=GameClient() def GameInit(): global x_coord global y_coord global westiceplane global myenemylist global mybulletlist global frameobj westiceplane=Plane(x_coord/2,1)#加入飞机 myenemylist=[] for i in range(4): #加入敌人 westiceenemy=Enemy() myenemylist.append(westiceenemy) mybulletlist=[] for i in range(20): mywesticebullet=Bullet(westiceplane.x,westiceplane.y) mybulletlist.append(mywesticebullet) #新建一个线程处理网络 thread.start_new_thread(threadfunc,()) frameobj=netframe(westiceplane,mybulletlist,myenemylist) def init(): glClearColor(0.5,0.5,0.5,0.0) glClearDepth(1.0) # Enables Clearing Of The Depth Buffer glDepthFunc(GL_LESS) # The Type Of Depth Test To Do glEnable(GL_DEPTH_TEST) # Enables Depth Testing glShadeModel(GL_SMOOTH) # Enables Smooth Color Shading def calcdistance(object0,object1): return math.sqrt(pow(object0.x-object1.x,2)+pow(object0.y-object1.y,2)) count=0 def display(): #print 'display' glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) westiceplane.update() for enemy in myenemylist: enemy.update() if not enemy.live: enemy.reset() for bullet in mybulletlist: if calcdistance(bullet,enemy)<=0.2:#是否相遇 bullet.live=False enemy.live=False #自动发射子弹 global count if count>=15: count=0 for bullet in mybulletlist: if not bullet.live: bullet.reset(westiceplane.x,westiceplane.y+1)#激活一颗 break for bullet in mybulletlist: bullet.update() count+=1 #显示网络来的数据 global otherplane global otherenemylist global otherbulletlist if isconnected and otherplane: otherplane.draw() if isconnected and otherbulletlist and otherenemylist and otherplane: otherplane.draw() for myenemy in myenemylist: for otherbullet in otherbulletlist: if calcdistance(otherbullet,myenemy)<=0.2:#是否相遇 otherbullet.live=False myenemy.live=False for otherenemy in otherenemylist: if otherenemy.live: otherenemy.draw() for otherbullet in otherbulletlist: if otherbullet.live: otherbullet.draw() glutSwapBuffers() #glFlush() def reshape(w,h): print 'reshape' glViewport(0,0,w,h) glMatrixMode(GL_PROJECTION) glLoadIdentity() print 'w:',w,' h:',h if w!=0 and h!=0: global x_coord global y_coord if(w<=h): gluOrtho2D(0.0,x_coord,0.0,x_coord*h/w) else: gluOrtho2D(0.0,x_coord*w/h,0.0,x_coord) glMatrixMode(GL_MODELVIEW) def keyboard(key,x,y): # if key==chr(27): # sys.exit(0) if key=='a'or key=='A': westiceplane.left() if key=='d'or key=='D': westiceplane.right() GameInit() glutInit(sys.argv) glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH) #使用双缓冲和深度测试 glutInitWindowSize(600,500) glutInitWindowPosition(100,100) if isAserver: glutCreateWindow('Game Server') else: glutCreateWindow('Game Client') init() glutReshapeFunc(reshape) glutKeyboardFunc(keyboard) glutDisplayFunc(display) glutIdleFunc(display) glutMainLoop()
相关推荐
pyopengl 简单教程
wxPython and PyOpengl源码 演示如何在wxPython构建的GUI中使用pyopengl绘制场景
pyopengl & demos pyopengl & demos pyopengl & demos
python pyopengl 64 位的包 64位系统必须使用64位的
PyOpenGL-3.0.1a2.win32.exe, python openGL库 for windows
pyopengl testcode demopyopengl testcode demopyopengl testcode demopyopengl testcode demopyopengl testcode demo
本资源为python环境下编译好的OpenGL whl文件,可直接进行pip安装和使用。
python and opengl 使用介绍PPT
支持Python3.3,PyQt4的PyOpenGL。如果你是使用PyQt4中的OpenGL例子,如果运行出现错误,请将glViewport()函数改成GL.glViewport(0, 0, side, side)形式。
PyOpenGL-3.0.1.win32.exe
PyOpenGL-3.1.2-cp34-cp34m-win_amd64.whlPyOpenGL-3.1.2-cp34-cp34m-win_amd64.whl,python3.4
PyOpenGL——走进3D的世界PyOpenGL介绍功能解析PyOpenGL实例问题处理一、缺少glut文件参考文章 PyOpenGL介绍 功能解析 # 调用PyOpenGL库 import OpenGL # 对,就是这么调用...很奇怪,尽管在pip list中还是PyOpenGL...
python 3.7版本opengl,注意只能在python 3.7版本下使用,其他版本的可以去网站https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyopengl 下载
PyOpenGL-3.1.5-cp38-cp38-win_amd64
Python 语言的openGL相关代码示例。适用于使用Python语言进行图像处理方面开发 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
PyOpenGL-3.1.5-cp38-cp38-win_amd64.whl
PyOpenGL-3.1.5-cp37-cp37m-win_amd64
python 相对应的opengl opengl 做3D 很酷, 你用得着的
PyOpenGL_accelerate-3.1.5-cp38-cp38-win_amd64.whl
学习过程中收集到的和一些自己写的pyopnegl代码资源,提供给初学者下载,里面与一部分代码来自于github,有一部分自己编写的,但是没有进行规范整理,可能有些乱,运行的话资源路径可能需要自己修改一下