from twisted.internet.protocol import DatagramProtocol from twisted.internet import reactor import pygame import constants import xdrlib import pyui import environment """ Class used by the game when running client mode """ class Client(DatagramProtocol): def __init__(self, ip, world, readPort, writePort): self.ip = ip self.world = world self.readPort = readPort self.writePort = writePort self.lastupdate = 0 self.trans = reactor.listenUDP(readPort, self) print "client loaded" print "client listening at port "+str(readPort) print "client will write from port "+str(writePort) """ Makes sure the package received comes from the wanted IP - the address given on joining a game """ def datagramReceived(self, datagram, address): (ip, port) = address if ip == self.ip: self.parseDatagram(datagram) """ Unpacks data sendt from server and unpacks it in the same order as sent from server """ def parseDatagram(self, datagram): unpacker = xdrlib.Unpacker(datagram) self.unpackSoldier(environment.Env.remotePlayer.avatar, unpacker) self.unpackSoldier(environment.Env.localPlayer.avatar, unpacker) env = environment.Env env.remotePlayer.controller.fire = unpacker.unpack_int() env.remotePlayer.controller.throw = unpacker.unpack_int() remoteFrags = unpacker.unpack_int() localFrags = unpacker.unpack_int() if remoteFrags > env.remotePlayer.fragCount: print 'local player died' env.localPlayer.avatar.alive = 0 env.remotePlayer.fragCount = remoteFrags if localFrags > env.localPlayer.fragCount: print 'remote player died' env.remotePlayer.avatar.alive = 0 env.localPlayer.fragCount = localFrags """ Specifically unpacks all data belonging to the soldier class """ def unpackSoldier(self, soldier, unpacker): soldier.posX = unpacker.unpack_float() soldier.posY = unpacker.unpack_float() soldier.gun.facing = unpacker.unpack_int() soldier.velocityX = unpacker.unpack_float() soldier.velocityY = unpacker.unpack_float() soldier.health = unpacker.unpack_int() if soldier.health < 0: #Dying handled by reading frag counts soldier.health = 1 """ Method is used by the client to send updates to the server. All mouse and keyboard input is packed and finall writen to the server """ def writeUpdate(self): pressed = pygame.key.get_pressed() up = pressed[pyui.locals.K_UP] down = pressed[pyui.locals.K_DOWN] left = pressed[pyui.locals.K_LEFT] right = pressed[pyui.locals.K_RIGHT] (fire, b2, throw) = pygame.mouse.get_pressed() facing = environment.Env.localPlayer.avatar.gun.facing packer = xdrlib.Packer() packer.pack_int(up) packer.pack_int(down) packer.pack_int(left) packer.pack_int(right) packer.pack_int(fire) packer.pack_int(throw) packer.pack_int(facing) self.transport.write(packer.get_buffer(), (self.ip, self.writePort)) """ Polls the UDP network for any received datagrams on each iteration. If the time since last game update sent to the server is trespassed an update will be send. """ def update(self): currentTime = pyui.readTimer() reactor.runUntilCurrent() reactor.doSelect(0) environment.Env.localPlayer.controller.processPeripheralsClient() environment.Env.localPlayer.update() environment.Env.remotePlayer.update() if currentTime - self.lastupdate > 0.05: self.writeUpdate() self.lastupdate = currentTime