2017-06-05 3 views
0

私はマルチプレイヤーhtml5ゲームを作っています。パイプコードを実装するとエラーが発生します。p.updateは関数ではありません。以下は私のコードです。私は "パイプ" オブジェクトで、クライアント側でエラーを取得していますp.updateは私のマルチプレイヤーゲームの関数エラーです

server.js

var express = require('express'); 
var http = require('http'); 
var path = require('path'); 
var socketIO = require('socket.io'); 
var app = express(); 
var server = http.Server(app); 
var io = socketIO(server); 
app.set('port', 5000); 
app.use('/static', express.static(__dirname + '/static')); 

// Routing 
app.get('/', function(request, response) { 
    response.sendFile(path.join(__dirname, '/static/index.html')); 
}); 

// Starts the server 
server.listen(5000, function() { 
    console.log('Starting server on port 5000'); 
}); 

// Game vars 
var 
width, 
height, 

frames = 0, 
clients = {}, 
pipes = []; 

// Bird class 
function Bird() { 
    this.x = 64; 
    this.y = height/2; 
    this.r = 32; 
    this.gravity = 0.5; 
    this.velocity = 0; 
    this.lift = 10; 
    this.time = new Date().getTime(); 

    this.up = function() { 
     this.velocity = -this.lift; 
     this.velocity = this.velocity * 0.9; 
    } 

    this.update = function() { 
     this.velocity += this.gravity; 
     this.y += this.velocity; 
     if (this.y > height) { 
      this.y = height; 
      this.velocity = -(this.velocity * 0.8); 
     } 
     if (this.y < 0) { 
      this.y = 0; 
      this.velocity = 0; 
     } 
    } 
} 

function Pipe() { 
    this.x = width; 
    this.y = 0; 
    this.width = 20; 
    this.speed = 1; 
    this.topPipe = Math.random()*height/2; 
    this.bottomPipe = Math.random()*height/2; 
    this.highlight = null; 

    this.update = function() { 
     this.x -= this.speed; 
    } 
} 

// Updating 
function update() { 
    frames++; 

    if(frames % 100 == 0) { 
     pipes.push(new Pipe()); 
    } 

    for(var key in clients) { 
     var b = clients[key]; 
     b.update(); 
    } 

    io.sockets.emit('update', { 
     birds: clients, 
     pipes: pipes 
    }); 
} 

io.on("connection", function(socket) { 
    socket.on('new-client', function(data) { 
     width = data.width; 
     height = data.height; 
     clients[socket.id] = new Bird(); 
    }); 
    socket.on('disconnect', function() { 
     delete clients[socket.id]; 
    }); 
}); 

setInterval(update, 1000/60); 

client.js

// Vars 
var 

socket = io(), 
canvas = document.getElementById('canvas'), 
ctx = canvas.getContext('2d'), 
width = canvas.width = innerWidth, 
height = canvas.height = innerHeight, 
time = new Date().getTime(); 

var birds = { 
    _birds: null, 

    update: function(data) { 
     this._birds = data; 
    }, 

    draw: function() { 
     for(var key in this._birds) { 
      var b = this._birds[key]; 
      var newX = b.x+((b.time-time)*1/(1000/60)); 

      ctx.fillStyle = socket.id == key ? "#fff" : "#f00"; 
      ctx.beginPath(); 
      ctx.arc(newX, b.y, b.r, 0, Math.PI*2); 
      ctx.fill(); 
      ctx.closePath(); 
     } 
    } 
}; 

var pipes = { 
    _pipes: null, 

    update: function(data) { 
     this._pipes = data; 

     for(var key in this._pipes) { 
      var p = this._pipes[key]; 
      p.update(); 

      if(p.x > -p.width) { 
       delete this._pipes[key]; 
      } 
     } 
    }, 

    draw: function() { 
     for(var key in this._pipes) { 
      var p = this._pipes[key]; 

      ctx.fillStyle = "#000"; 
      ctx.fillRect(p.x, p.y, p.width, p.topPipe); 
      ctx.fillRect(p.x, height-p.bottomPipe, p.width, p.bottomPipe); 
     } 
    } 
} 

// New client 
socket.emit("new-client", { 
    width: width, 
    height: height 
}); 

// Draw 
socket.on('update', function(data) { 
    birds.update(data.birds); 
    pipes.update(data.pipes); 

    ctx.fillStyle = "#eee"; 
    ctx.fillRect(0, 0, width, height); 

    birds.draw(); 
    pipes.draw(); 
}); 

答えて

0

もし

socket.on('update', function(data) { 
    birds.update(data.birds); 
    pipes.update(data.pipes); 

data.birdsdata.pipesを行い、その(例えばupdateような)機能特性またはプロトタイプメソッドを保持していない、JSONオブジェクトのシリアライズ配列です。

クライアントとサーバーの両方からPipeクラスにアクセスできるようにし、updateをメソッドにすることをお勧めします。再割り当てが必要な場合を除き、関数をオブジェクトプロパティとして使用することはお勧めできません(たとえば、プロトタイプメソッドを使用するよりも多くの領域が必要です)。

Pipe.prototype.update = function() { 
    this.x -= this.speed; 
} 
// To apply the function 
for(var key in this._pipes) { 
    var p = this._pipes[key]; 
    Pipe.prototype.update.call(p); // Equivalent to p.update() 
    if(p.x > -p.width) { 
     delete this._pipes[key]; 
    } 
} 

次に、適用を使用してシリアル化されたオブジェクトでも更新を呼び出すことができます。もちろん、socket.ioからPipeインスタンスにデータをデシリアライズする機能を持っている方が良いでしょう。

+0

ですが、パイプクラスはサーバー上にあります。クライアント側でprotoを設定するには –

+0

BrowserifyやWebpackのようなものを使うと、クライアントとサーバーの間でコードを共有できます。 –

関連する問題