1. Andrew
  2. pyShipCommand

Commits

Andrew  committed ae93d8d

Add more client initialization data and dead-reckoning ship interpolation.

  • Participants
  • Parent commits 9e01e2f
  • Branches web

Comments (0)

Files changed (2)

File web/game.js

View file
  • Ignore whitespace
 
 // Ship Class and Data are defined by reqdata.js
 // and loaded by pyship.html
+// Keep method definitions here for now
+Ship.prototype.draw = function(c, asset) {
+  c.save();
+
+  // Position and rotate ship
+  c.translate(scroll.x, scroll.y);
+  c.translate(this.pos.x, this.pos.y);
+  c.rotate(this.rot);
+
+  // Draw centered on image
+  c.drawImage(asset.img, -asset.img.width/2, -asset.img.height/2);
+  c.restore();
+};
+
+Ship.prototype.update = function(lerp) {
+  this.pos.x = this.startpos.x + this.vel.x * lerp;
+  this.pos.y = this.startpos.y + this.vel.y * lerp;
+};
 
 // Create the canvas
 var canvas = document.getElementById("viewer");
 
 // Handle keyboard controls
 var keysDown = {};
-var scrollX = -mship.x + canvas.width/2;
-var scrollY = -mship.y + canvas.height/2;
+var scroll = new Vector(-mship.pos.x + canvas.width/2,
+                        -mship.pos.y + canvas.height/2);
 var SCROLL_SPEED = 256;
 
 addEventListener("keydown", function (e) {
 // Update game objects
 var update = function (dt) {
   if (38 in keysDown) { // Player holding up
-    scrollY += SCROLL_SPEED * dt;
+    scroll.y += SCROLL_SPEED * dt;
   }
   if (40 in keysDown) { // Player holding down
-    scrollY -= SCROLL_SPEED * dt;
+    scroll.y -= SCROLL_SPEED * dt;
   }
   if (37 in keysDown) { // Player holding left
-    scrollX += SCROLL_SPEED * dt;
+    scroll.x += SCROLL_SPEED * dt;
+    //mship.rot -= SCROLL_SPEED * dt;
   }
   if (39 in keysDown) { // Player holding right
-    scrollX -= SCROLL_SPEED * dt;
+    scroll.x -= SCROLL_SPEED * dt;
+    //mship.rot += SCROLL_SPEED * dt;
+  }
+
+    // Calculate lerp
+  lerpTime = lerpTime + dt;
+
+  for (var ship in ships) {
+    ships[ship].update(lerpTime);
   }
 };
 
   ctx.fillStyle = "#000000";
   ctx.fillRect(0, 0, canvas.width, canvas.height);
 
-  // Save Context and apply scroll translation
   ctx.save();
-  ctx.translate(scrollX, scrollY);
-
-  if (mshipImg.ready) {
-    mship.draw(ctx, mshipImg);
-  }
+  // Why can't I do this here without messing up 
+  // the rotation?
+  //c.setTransform(1, 0, 0, 1, scrollX, scrollY);
 
-  if (shipImg.ready) {
+  if (mshipImg.ready && shipImg.ready) {
     for (var s in ships) {
-      ships[s].draw(ctx, shipImg);
+      if (ships[s] == mship)
+        ships[s].draw(ctx, mshipImg);
+      else
+        ships[s].draw(ctx, shipImg);
     }
   }
 
   ctx.textAlign = "left";
   ctx.textBaseline = "top";
   ctx.fillText("FPS: " + fps, 32, 32);
+  ctx.fillText("Lerp: " + lerpTime, 32, 64);
 };
 
 // The main game loop
   frameCount = frameCount + 1;
 
   // Update Game
-  update(delta / 1000);
+  update(dt);
   render();
 
   then = now;
 var w = window;
 requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
 
+setInterval(function(){window.location.reload(true);}, updateInterval * 1000);
+
 // Let's play this game!
 var then = Date.now();
 var fps = 0;
 var frameCount = 0;
 var frameRun = 0.0;
+var lerpTime = 0.0;
 main();

File web/site.py

View file
  • Ignore whitespace
 class GameDataRes(resource.Resource):
     isLeaf = True
 
+    # Javascript Class Definitions
     CLASS_DEFS = """
+// Vector class
+function Vector(x, y) {
+    this.x = x;
+    this.y = y;
+}
+        
 // Ship class
-function Ship(startx, starty, rot) {
-    this.x = startx;
-    this.y = starty;
-    this.rot = 0;
-    this.speed = 0;
+function Ship(pos, vel, rot) {
+    this.startpos = pos;
+    this.pos = new Vector(pos.x, pos.y);
+    this.vel = vel;
+    this.rot = rot;
 }
-Ship.prototype.draw = function(c, asset) {
-    c.drawImage(asset.img, this.x, this.y);
-};
 """
 
     def render_GET(self, request):
+        from pyshipcommand.server import SERVER_UPDATE_INT
+        from math import atan2, pi
         log.info("GET: %s", str(request))
 
-        # Retrieve ships from ship manager
-        # For now, only retrieve 'web' player ships
-        sm = getUtility(IManager, "Ship")
-        ships = sm.getPlayerShips('web')
+        # Set Client Init data
+        init_data = []
+
+        # For now, only retrieve 'web' player data
+        pm = getUtility(IManager, "Player")
+        player = pm.getPlayer("web")
+
+        init_data.append("var playerId = %d;" % (player.id))
+        init_data.append("var playerName = '%s';" % (player.name))
+
+        init_data.append("var updateInterval = %f;" % (SERVER_UPDATE_INT))
+        #init_data.append("setInterval(function(){window.location.reload(true);},%d);" % (SERVER_UPDATE_INT * 1000))
+
+        # create init definitions
+        init_defs = '\n'.join(init_data)
+
+        # Send Universe
+        #univ = getUtility(IManager, "Universe")
+        #bodies = univ.getAllStatic()
+        #cinit.universe = [NetCelestialBody(b) for b in bodies]
 
         # Generate static ship data
         # First ship is always the mothership
+        sm = getUtility(IManager, "Ship")
+        ships = sm.getPlayerShips("web")
         mship = ships[0]
-        mship_def = "var mship = new Ship(%i, %i);" % (int(mship.pos.x), int(mship.pos.y))
 
         ship_defs = "var ships = {\n"
         for ship in ships:
-            if ship is mship:
-                continue
-            ship_defs += "%d : new Ship(%i, %i),\n" % (ship.id, int(ship.pos.x), int(ship.pos.y))
+            rot = atan2(ship.heading.y, ship.heading.x) + pi/4.0 if not ship is mship else 0.0
+            ship_defs += "%d : new Ship(new Vector(%f, %f), new Vector(%f, %f), %f),\n" % (ship.id, ship.pos.x, ship.pos.y, ship.vel.x, ship.vel.y, rot)
         ship_defs += "};"
 
-        return '\n'.join([self.CLASS_DEFS, mship_def, ship_defs])
+        mship_def = "var mship = ships[%d];" % (mship.id)
+
+        return '\n'.join([self.CLASS_DEFS, init_defs, ship_defs, mship_def])
 
 #end GameData