Archive:Communication en UDP entre un script python et Blender Game Engine
Ce wiki a été archivé en 2018.
Le nouveau wiki se trouve à: ressources.labomedia.org Les fonctionnalités sont désactivées: vous pouvez faire une recherche sur Google site:https://wiki.labomedia.org et découvrir La Labomedia. |
Sommaire
Ressources
- http://www.blender.org/documentation/blender_python_api_2_60_6/#game-engine-modules Blender 2.60
- http://docs.python.org/py3k/genindex-P.html Python3
Exemple 1 : Entre 2 fichiers Blender
Cet exemple permet de copier la position et l'orientation d'un cube du fichier server au fichier client: le cube pourrait être une voiture dans un jeu en réseau.
Blender 2.49 et python 2.6
Script python 2.6 Server
import socket
import cPickle # serializing and de-serializing
# Get owner
controller = GameLogic.getCurrentController()
owner = controller.owner
# Set server
Host = 'localhost'
ServerPort = 10000
# Set socket server only one time at the first frame
if not owner['OneTime']:
# Set UDP socket
GameLogic.sServer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Bind the socket to host
GameLogic.sServer.bind((Host, ServerPort))
# If no data are found, pass
GameLogic.sServer.setblocking(0)
# Set prop to pass test
owner['OneTime'] = True
# Get Position and Orientation
PosCar = owner.worldPosition
OriCar = owner.worldOrientation
# Serialize data
Data = cPickle.dumps((PosCar,OriCar))
# Send Data to client
GameLogic.sServer.sendto(Data, (Host, 10001))
Script python 2.6 Client
import socket
import cPickle # serializing and de-serializing
# Get owner
controller = GameLogic.getCurrentController()
owner = controller.owner
# Set Client
host = "localhost"
ClientPort = 10001
# Set socket client only one time at the first frame
if not owner['OneTime'] :
# Set UDP socket
GameLogic.socketClient = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# Bind the socket to host
GameLogic.socketClient.bind((host, ClientPort))
# Set Buffer size
GameLogic.socketClient.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1024)
# If no data are found, pass
GameLogic.socketClient.setblocking(0)
# Set prop to pass test
owner['OneTime'] = True
#------------if RECEIVE UDP --------------#
try:
# Get data in buffer
UpData, SRIP = GameLogic.socketClient.recvfrom(1024)
# De-serialize, return tuples
msg = cPickle.loads(UpData)
# Set Position and orientation
owner.worldPosition = (msg[0][0], msg[0][1], msg[0][2])
owner.worldOrientation = ( (msg[1][0], msg[1][1], msg[1][2]) )
except :
pass
Blender 2.6 et python 3
Script python 3 Server
# python 3
import GameLogic
import socket
import pickle # serializing and de-serializing
# Get owner
controller = GameLogic.getCurrentController()
owner = controller.owner
Host = 'localhost'
ServerPort = 10000
# Set socket server only one time at the first frame
if not owner['OneTime']:
# Set UDP socket
GameLogic.sServer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Bind the socket to host
GameLogic.sServer.bind((Host, ServerPort))
# If no data are found, pass
GameLogic.sServer.setblocking(0)
# Set prop to pass test
owner['OneTime'] = True
# Get Position and Orientation
PosCar = owner.worldPosition
OriCar = owner.worldOrientation
# New in python 3
stupid = (PosCar[0], PosCar[1], PosCar[2], OriCar[0][0], OriCar[0][1], OriCar[0][2], OriCar[1][0], OriCar[1][1], OriCar[1][2], OriCar[2][0], OriCar[2][1], OriCar[2][2])
# Serialize data
Data = pickle.dumps(stupid)
# Send Data to client
GameLogic.sServer.sendto(Data, (Host, 10001))
Script python 3 Client
# python 3
import GameLogic
import mathutils
import socket
import pickle # serializing and de-serializing
# Get owner
controller = GameLogic.getCurrentController()
owner = controller.owner
host = "localhost"
ClientPort = 10001
# Set socket client only one time at the first frame
if not owner['OneTime'] :
# Set UDP socket
GameLogic.socketClient = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# Bind the socket to host
GameLogic.socketClient.bind((host, ClientPort))
# Set Buffer size
GameLogic.socketClient.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1024)
# If no data are found, pass
GameLogic.socketClient.setblocking(0)
# Set prop to pass test
owner['OneTime'] = True
#------------if RECEIVE UDP --------------#
try:
# Get data in buffer
UpData, SRIP = GameLogic.socketClient.recvfrom(1024)
# De-serialize, return tuples
test = pickle.loads(UpData)
# Set Position and orientation
owner.worldPosition = (test[0], test[1], test[2])
# Orientation must be a matrix
owner_ori = mathutils.Matrix(((test[3], test[4], test[5]) , (test[6], test[7], test[8]) , (test[9], test[10], test[11])))
owner.worldOrientation = owner_ori
except :
pass
Problème du buffer UDP
Dans les fichiers ci-dessus, les scripts sont lancés avec un actuator qui pulse à 0. Si le client pulse moins vite que le server, le buffer se rempli. La latence est expliquée plus en détail. Si le client pulse à 2, soit 15 fps, le mouvement est haché: pour qu'un jeu soit fluide, il doit tourner à beaucoup plus que 30 fps.
Dans les scripts, le buffer est limité, il n'y a pas de retard sur le client, mais cela correspond à des valeurs qui sont perdues et un mouvement haché du client.
Exemple 2: entre un script et Blender
Le jeu Land_Of_Love lie un script et Blender: Blender 2.49 et python 2.6.