Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/452.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript类型错误,can’;对象的t访问方法_Javascript_Object_Typeerror_P5.js - Fatal编程技术网

Javascript类型错误,can’;对象的t访问方法

Javascript类型错误,can’;对象的t访问方法,javascript,object,typeerror,p5.js,Javascript,Object,Typeerror,P5.js,我正在使用p5.js、node.js和socket.io在浏览器中制作一个小型多人游戏。一个名为“player”的对象从一个客户端传递到另一个客户端,以同步两个客户端。这对于其他不依赖方法调用的代码来说很好。但是现在我也想访问播放器对象中存储对象的方法,它不再工作了 这将是存储所有变量的对象,以及两个客户端之间包含对象的数组: var player = { structures: [] }; 现在,如果我向其中添加一个名为campfire的对象,如下所示: player.structure

我正在使用p5.js、node.js和socket.io在浏览器中制作一个小型多人游戏。一个名为“player”的对象从一个客户端传递到另一个客户端,以同步两个客户端。这对于其他不依赖方法调用的代码来说很好。但是现在我也想访问播放器对象中存储对象的方法,它不再工作了

这将是存储所有变量的对象,以及两个客户端之间包含对象的数组:

var player = {
  structures: []
};
现在,如果我向其中添加一个名为campfire的对象,如下所示:

player.structures.push(new campfire(mouseX,mouseY));
class campfire {
constructor(x,y){
    this.scale = 40;
    this.x = x;
    this.y = y;
    this.maxLevel = 3;
    this.button = new button(this.x, this.y+50, this.x-50, this.y-70, upgrade, upgrade_hover, this);
    this.show_upgrade_button = true;
}

draw(){
    switch(player.campfire.level){
        case 1: image(fire, this.x, this.y, this.scale, this.scale);break;
        case 2: image(campfire_2, this.x, this.y, this.scale, this.scale);break;
        case 3: image(campfire_3, this.x, this.y, this.scale, this.scale);break;
        default: console.log("cant upgrade, this shouldn't happen.");
    }
    if(this.show_upgrade_button){
        this.button.draw();
    }
}

trigger(){      
    if(player.campfire.level + 1 <= this.maxLevel && this.show_upgrade_button == true){
        this.button.trigger();
    }
}}
并尝试调用对象campfire的draw()方法,如下所示:

player.structures.push(new campfire(mouseX,mouseY));
class campfire {
constructor(x,y){
    this.scale = 40;
    this.x = x;
    this.y = y;
    this.maxLevel = 3;
    this.button = new button(this.x, this.y+50, this.x-50, this.y-70, upgrade, upgrade_hover, this);
    this.show_upgrade_button = true;
}

draw(){
    switch(player.campfire.level){
        case 1: image(fire, this.x, this.y, this.scale, this.scale);break;
        case 2: image(campfire_2, this.x, this.y, this.scale, this.scale);break;
        case 3: image(campfire_3, this.x, this.y, this.scale, this.scale);break;
        default: console.log("cant upgrade, this shouldn't happen.");
    }
    if(this.show_upgrade_button){
        this.button.draw();
    }
}

trigger(){      
    if(player.campfire.level + 1 <= this.maxLevel && this.show_upgrade_button == true){
        this.button.trigger();
    }
}}
控制台(不将对象“campfire”加载到阵列“structures”的客户端)打印以下错误:

gui.js:38 Uncaught TypeError: player.structures[i].draw is not a function
将campfire对象推送到阵列的客户端能够进行draw()调用,并且不会打印错误消息。但是,没有将对象推送到数组的另一个客户端无法使用该方法并输出错误,即使它们共享同一个“player”对象。奇怪的是,打印错误的人仍然能够访问campfire对象的所有变量,因此它似乎只影响方法

关于这一点,我找到的唯一资源就是这篇文章 我试图将函数重命名为draw=function(){}和campfire.prototype.draw=function(){},但这对我来说没有什么区别。我认为函数的声明不对?这将是我目前唯一可能的解释

感谢您花时间阅读我的问题


编辑:这是该项目的链接:

我认为你的问题更多的是在设计层面上。io(或任何其他同步库)并不是真正用来来回推送整个代码段的。对你来说,这就是营火的功能

我建议只来回推
state
。球员有锤子吗?玩家有多少生命?玩家有营火吗?换句话说,只同步不断变化的数据

由于营火的功能(抽签功能)对所有玩家都是一样的,所以没有必要每隔几秒钟就来回推一次代码!效率很低

相反,当同步对象显示播放机有营火时,可以在客户端创建营火实例

在代码中可能看起来像这样(只是一个想法):

正在同步socket.io的对象

var player = {
  structures: {campfire:true}
};
客户端代码

// create campfire instances, tell the campfire which player it belongs to
if(player.structures.campfire) {
    let cf = new Campfire(player)
    cf.draw()
}

注意:很可能是socket.io去掉了可执行代码

你确定你的索引
i
0
player.structures.length-1
的范围内吗?请发布@DacreDenny是的,两个客户端都知道数组的长度,我可以在使用player.structures[0]时访问对象变量例如.x。我用于在数组上迭代的for循环确实有效,但仅适用于将对象推送到数组的客户端。您能否发布更多显示如何填充structures数组的代码,或者提供一个链接,称为github存储库?@Ele此处是指向项目的链接:。我使用'nodemon server.js'在端口3000上启动服务器。您需要同时打开两个选项卡。加载两个后,按h键,单击图像并单击屏幕上的某个位置。hammer图标应该执行升级部分,并在单击时与其他客户端同步该过程。我只包括了Nessery课程。谢谢你的回答,我已经做了一些与进度条类似的事情,它指示了篝火的升级过程,我想知道是否有更好的方法来实现这一点。我不确定这是否是javascript问题,因为错误消息暗示了这一点,所以我在这里询问。正如您已经写过的,socket.io可能会删除所有方法,但我会接受您的建议,只使用状态变量——您的回答对我帮助很大,非常感谢!套接字IO序列化其对象。在JSON序列化过程中,所有方法都将消失,只保留属性。