您的问题似乎只是每秒 60 帧,这导致了赛跑状况。 Firebase .once 将在完成获取时执行异步,并且 P5 不会等待它获取,因为它会坚持其帧速率计时。
在这种特定情况下,我有多个建议,希望它们能让您非常接近您想要的结果。
1 - 重构您的代码
您的代码的当前结构存在两个问题。
案例 1:您当前的代码会让我认为您的圈子在数据库中是实时更新的,您需要保持最新状态,因此您不断获取他们的最新位置。如果是这种情况,您应该使用.on("value") 而不是.once("value") 并让firebase 在圈子发生变化时向您发送更新,而不是每秒询问60 次以节省往返请求时间。如果是这种情况:请参阅下面的解决方案 1。
案例 2:如果您的圈子没有在数据库中实时更新,而您只需要整个圈子列表,那么您将无缘无故地每秒获取 60 次列表。您应该在设置时使用.once 获取列表,并稍后在draw() 中迭代该列表。请参阅下面的解决方案 2。
2 - 重组您的数据库
在任何一种情况下,您当前的数据库模型都要求您循环获取数据。这意味着您发出的请求与您的circleCount 一样多。这对您的使用不利,因为每个请求都需要额外的行程时间,而我们正在努力减少它所花费的时间,以便更接近实时。 (或匹配帧率)
目前,您的圈子似乎都在 root 中保存为 circles1 circles2 等,因为您正在使用 .ref("circles" + j) 来检索它们。使您可以像这样保存您的圈子:.ref("circles/" + j),这意味着每个circle 现在都保存在in circles。比如circles/circle1circles/circle2等等。
这样做的好处是,现在您不需要额外的请求来让 firebase 获取所有圈子。 Firebase 具有非常方便的功能,例如 forEach 可以通过单个请求遍历所有子节点。
3 - 在您的 Firebase 回调中清除背景
目前,您以特定帧速率的方式清除背景。这意味着,如果您的每个 firebase 调用花费的时间超过 1/60 秒(16 毫秒),您将清除背景并继续前进。即使在我们构建了数据库之后,您达到这种速度的机会也非常低。因此,我建议首先使用 30fps,这也可以将您对 firebase 的调用次数减少到每秒 30 次调用。
解决方案 1
如果您的圈子在数据库中已更新(例如由其他游戏玩家或其他人更新,并且您希望您的代码始终显示最新的 xPos)
var latestCirclePositionsSnapshot;
function setup() {
createCanvas(windowWidth, windowHeight);
background(40);
stroke(80);
smooth();
frameRate(60);
firebase.database().ref("circles").on("value", function(snapshot) {
// got a new value from database, so let's save this in a global variable.
latestCirclePositionsSnapshot = snapshot;
// we will keep drawing this update until we get a new one from the database.
});
}
function draw() {
drawCircles();
}
function clearBackground () {
stroke(80);
background(40);
}
function drawCircles() {
clearBackground();
stroke(0);
latestCirclePositionsSnapshot.forEach(function(circleSnapshot) {
// circleData will be the actual contents of each circle
var circleData = circleSnapshot.val();
fill(143, 2, 2);
ellipse(circleData.xPos, 50, 50);
});
}
基本上,这将继续绘制我们从 firebase 获得的最后一个圆圈位置,直到我们得到一个新的位置。 (所以 P5 将以 60fps 的速度保持刷新,但您的 firebase 更新将与 firebase 可以运行并从 firebase 等获取一样实时)
解决方案 2
如果您的数据库中没有实时更新,而您只想通过一次从 firebase 获取数据来绘制圆圈(例如根据某些数据绘制一些点)
var circlePositions;
var gotPositions = false;
function setup() {
createCanvas(windowWidth, windowHeight);
background(40);
stroke(80);
smooth();
frameRate(60);
firebase.database().ref("circles").once("value", function(snapshot) {
// got the circle values from the database
// let's store them and we'll keep drawing them forever.
circlePositions = snapshot;
gotPositions = true;
});
}
function draw() {
drawCircles();
}
function clearBackground () {
stroke(80);
background(40);
}
function drawCircles() {
clearBackground();
stroke(0);
if (gotPositions) {
circlePositions.forEach(function(circleSnapshot) {
// circleData will be the actual contents of each circle
var circleData = circleSnapshot.val();
fill(143, 2, 2);
ellipse(circleData.xPos, 50, 50);
});
} else {
// Display some text here like "LOADING DATA FROM SERVERS..."
}
}
希望这些帮助 :) 很高兴见到 Processing 和 Firebase 的另一位粉丝。