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 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 renderBullet(bul): glTranslate(*bul.position + [0]) glScale(0.2, 0.2, 0.2) with glPrimitive(GL_POLYGON): glColor(0, 0, 1) for posi in [0, 0.4, 0.8, 0.2, 0.6]: glVertex2f(sin(posi * 2 * pi), cos(posi * 2 * pi))
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 quad(): with glPrimitive(GL_QUADS): glTexCoord2f(0, 1) glVertex2i(0, 1) glTexCoord2f(0, 0) glVertex2i(0, 0) glTexCoord2f(1, 0) glVertex2i(1, 0) glTexCoord2f(1, 1) glVertex2i(1, 1)
def draw(self): glEnable(GL_TEXTURE_2D) self.bind() texw = self.w / float(self.texw) texh = self.h / float(self.texh) glColor4fv(self.rgba) with glPrimitive(GL_QUADS): glTexCoord2f(0, 0) glVertex2f(0, 0) glTexCoord2f(0, texh) glVertex2f(0, self.h) glTexCoord2f(texw, texh) glVertex2f(self.w, self.h) glTexCoord2f(texw, 0) glVertex2f(self.w, 0)
def renderGameGrid(player): with glPrimitive(GL_LINES): for x in range(int(player.position[0] - 30), int(player.position[0] + 30), 1): if x % 10 == 0: glColor(0.3, 0.3, 0, 1) elif x % 10 == 5: glColor(0.15, 0.15, 0, 1) else: glColor(0.05, 0.05, 0, 1) glVertex2f(x, player.position[1] - 30) glVertex2f(x, player.position[1] + 30) for y in range(int(player.position[1] - 30), int(player.position[1] + 30), 1): if y % 10 == 0: glColor(0.3, 0.3, 0) elif y % 10 == 5: glColor(0.15, 0.15, 0) else: glColor(0.05, 0.05, 0) glVertex2f(player.position[0] - 30, y) glVertex2f(player.position[0] + 30, y)
def renderPlanet(pla): glTranslate(*pla.position + [0]) with glPrimitive(GL_POLYGON): glColor(*pla.color) for i in range(0, 360, 36): glVertex2f(sin(i / 180. * pi) * pla.size, cos(i / 180. * pi) * pla.size)
def rungame(): global gsh global tickinterval global playerlist global chatitems global scene_matrix 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() loadImagery() 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. mystateid = network.clients[None].stateid # 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(mystateid).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 cam_h = 10 cam_v = 10 if mode == "c": playerlist = [] makePlayerList() # used for chat. sentence = "" textthing = Text(sentence) def updateTextThing(): textthing.renderText(sentence) pick = [0, 0] while running: timer.startFrame() if mode == "c": for event in pygame.event.get(): if event.type == QUIT: running = False elif event.type == MOUSEMOTION: try: pick = pickFloor(*event.pos) except: pass elif event.type == MOUSEBUTTONDOWN: sendCmd("t" + pack("!dd", *pick)) elif 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]: cam_h -= 1 if kp[K_RIGHT]: cam_h += 1 if kp[K_UP]: cam_v += 1 if kp[K_DOWN]: cam_v -= 1 # 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 gluLookAt(cam_h, cam_v, 10, localplayer.position[0], localplayer.position[1], 0, 0, 0, 1) scene_matrix = glGetDoublev(GL_MODELVIEW_MATRIX) # render everything with glMatrix(): renderGameGrid(localplayer) renderWholeState(gsh[-1]) with glMatrix(): glDisable(GL_TEXTURE_2D) with glPrimitive(GL_LINES): glVertex(pick[0], pick[1], 4) glVertex(pick[0], pick[1], -4) glEnable(GL_TEXTURE_2D) 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) 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()