def renderPlayer(player): glTranslate(*player.position + [0]) glTranslate(-0.5, 0, 1) glRotatef(90, -1, 0, 0) with glMatrix(): Texture("person").bind() with glPrimitive(GL_QUADS): glTexCoord2f(0, 0) glVertex2f(0, 0) glTexCoord2f(1, 0) glVertex2f(1, 0) glTexCoord2f(1, 1) glVertex2f(1, 1) glTexCoord2f(0, 1) glVertex2f(0, 1) tryfind = [c for c in network.clients.values() if c.stateid == player.id and c.remote] if tryfind: if tryfind[0] not in playerflags: txt = Text(tryfind[0].name) playerflags[tryfind[0]] = txt else: txt = playerflags[tryfind[0]] glTranslate(1.5, 0, 0) glScale(0.05, 0.05, 1) txt.draw()
def renderShip(ship): glTranslate(*ship.position + [0]) with glMatrix(): glRotatef(ship.alignment * 360, 0, 0, 1) with glPrimitive(GL_POLYGON): glColor(*ship.color) glVertex2f(1, 0) glVertex2f(-1, 0.5) glVertex2f(-0.5, 0) glVertex2f(-1, -0.5) with glPrimitive(GL_LINE_STRIP): for i in frange(0, ship.hull / 10000., 0.05): glColor(i, 1.0 - i, 0, 0.5) glVertex2f(sin(i * 2 * pi) * 2.2, cos(i * 2 * pi) * 2.2) if ship.shield < ship.maxShield and ship.shield > 0: amount = 1.0 * ship.shield / ship.maxShield with glPrimitive(GL_LINE_LOOP): glColor(1.0 - amount, amount, 0, amount) for i in range(0, 360, 36): glVertex2f(sin(i / 180. * pi) * 2, cos(i / 180. * pi) * 2) tryfind = [c for c in network.clients.values() if c.shipid == ship.id and c.remote] if tryfind: glEnable(GL_TEXTURE_2D) if tryfind[0] not in shipflags: txt = Text(tryfind[0].name) shipflags[tryfind[0]] = txt else: txt = shipflags[tryfind[0]] glTranslate(1.5, 0, 0) glScale(0.05,0.05,1) txt.draw() glDisable(GL_TEXTURE_2D)
def renderGameGrid(player): with glMatrix(): # glTranslatef(player.position[0], player.position[1], 0) Texture("floor").bind() with glPrimitive(GL_QUADS): glTexCoord2f(0, 0) glVertex2f(-100, -100) glTexCoord2f(100, 0) glVertex2f(100, -100) glTexCoord2f(100, 100) glVertex2f(100, 100) glTexCoord2f(0, 100) glVertex2f(-100, 100)
def renderWholeState(state): for obj in state.objects: for cls, met in methodMap.items(): if isinstance(obj, cls): with glMatrix(): met(obj)
def rungame(): global gsh global tickinterval global playerlist global chatitems tickinterval = 50 try: mode = argv[1] if mode == "s": port = argv[2] if len(argv) > 3: tickinterval = int(argv[3]) elif mode == "c": addr = argv[2] port = argv[3] except: print "usage:" print argv[0], "s port [ticksize=50]" print argv[0], "c addr port" print "s is for server mode, c is for client mode." sys.exit() if mode == "c": init() if mode == "s": # in server mode gs = network.initServer(int(port)) elif mode == "c": # in client mode gs = network.initClient(addr,int(port)) else: print "specify either 's' or 'c' as mode." sys.exit() # sets some stuff for the network sockets. network.setupConn() # this is important for the simulation. gs.tickinterval = tickinterval # in order to be reactive, the state history, which is currently server-side # only, has to incorporate input events at the time they actually happened, # rather than when they were received. Thus, a number of old gamestates is # preserved. # # on the client, the history simply deals with python-object changes that # update proxy objects. gsh = StateHistory(gs) # since the server is dedicated and headless now, we don't need a ship for it if mode == "c": # this is used to fix the camera on the ship and display information about # his ship to the player. myshipid = network.clients[None].shipid # a proxy is an object, that will automatically be updated by the gamestate # history object to always reflect the current object. This is accomplished # with black magic. localplayer = gs.getById(myshipid).getProxy(gsh) # yay! play the game! # inits pygame and opengl. running = True timer.wantedFrameTime = tickinterval * 0.001 timer.startTiming() timer.gameSpeed = 1 # this variable is used to determine, when it would be wise to skip # displaying a single gamestate, to catch up with the time the data # from the server is received. catchUpAccum = 0 if mode == "c": playerlist = [] makePlayerList() # used for chat. sentence = "" textthing = Text(sentence) def updateTextThing(): glEnable(GL_TEXTURE_2D) textthing.renderText(sentence) glDisable(GL_TEXTURE_2D) while running: timer.startFrame() if mode == "c": for event in pygame.event.get(): if event.type == QUIT: running = False if event.type == KEYDOWN: if event.key == K_ESCAPE: running = False # chat stuff elif K_a <= event.key <= K_z: sentence += chr(ord('a') + event.key - K_a) updateTextThing() elif event.key == K_SPACE: sentence += " " updateTextThing() elif event.key == K_BACKSPACE: sentence = sentence[:-1] updateTextThing() elif event.key == K_RETURN: if sentence: network.sendChat(sentence) sentence = "" updateTextThing() # end chat stuff # player control stuff kp = pygame.key.get_pressed() if kp[K_LEFT]: sendCmd("l") if kp[K_RIGHT]: sendCmd("r") if kp[K_UP]: sendCmd("t") if kp[K_SPACE]: sendCmd("f") # end player control stuff catchUpAccum += timer.catchUp # only if the catchUp time is below our patience or we run the server, # the gamestate should be rendered and calculated. if catchUpAccum < 2: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) with glIdentityMatrix(): # put the player in the middle of the screen glTranslatef(25 - localplayer.position[0], 18.5 - localplayer.position[1], 0) # render everything renderers.renderGameGrid(localplayer) renderers.renderWholeState(gsh[-1]) with glIdentityMatrix(): glScalef(1./32, 1./32, 1) # do gui stuff here with glMatrix(): glScale(3, 3, 1) for pli in playerlist: pli.draw() glTranslate(0, 16, 0) with glMatrix(): glScale(2, 2, 1) glTranslate(24, 540, 0) for msg in [textthing] + chatitems[::-1]: msg.draw() glTranslate(0, -17, 0) glDisable(GL_TEXTURE_2D) pygame.display.flip() # for the server, this lets new players in, distributes chat messages and # reacts to player inputs. network.pumpEvents() if mode == "c": if catchUpAccum > 2: print "catchUpAccum is", catchUpAccum catchUpAccum = 0 timer.endFrame() # exit pygame if mode == "c": pygame.quit()