Ada*_*Lee 6 html javascript processing firebase p5.js
我正在尝试创建一个应用程序,通过从存储圆圈的x和y坐标的Firebase数据库中读取信息,将圆圈绘制到画布上.然而,执行下面的代码,根本不产生任何东西,没有圆圈的任何迹象,因为函数drawCricles异步运行,因此命令background(40)在绘制圆之前清除所有内容.
这是我的代码:
function setup() {
createCanvas(windowWidth, windowHeight);
background(40);
stroke(80);
smooth();
frameRate(60);
}
function drawCircles() {
firebase.database().ref("circles").once("value", function(snapshot) {
var snapshotVal = snapshot.val();
var circleCount = snapshotVal.numCircles;
for (var j = 0; j < circleCount; j++) {
firebase.database().ref("circles" + j).once("value", function(snapshot) {
var snapshotValue = snapshot.val();
fill(143, 2, 2);
ellipse(snapshotValue.xPos, 50, 50);
});
}
});
}
function draw() {
stroke(80);
background(40);
stroke(0);
drawCircles();
}
Run Code Online (Sandbox Code Playgroud)
看来您的问题只是每秒 60 帧,这导致了竞走情况。Firebase.once在完成获取时将执行异步,P5 不会等待它获取,因为它将坚持其帧速率计时。
在这个具体案例中,我有多个建议,希望能让您非常接近您想要的结果。
1 - 重构你的代码
您的代码的当前结构存在两个问题。
情况 1:您当前的代码会让我认为您的圈子在数据库中实时更新,并且您需要保持最新状态,因此您不断获取他们的最新位置。如果是这种情况,您应该使用.on("value")而不是.once("value")让 firebase 在圈子发生变化时向您发送更新,而不是每秒询问 60 次以节省往返请求时间。如果是这种情况:请参阅下面我的解决方案 1。
情况 2:如果您的圈子没有在数据库中实时更新,而您只想要整个圈子列表,那么您每秒会无缘无故地获取该列表 60 次。您应该在设置时获取列表.once,并在稍后迭代该列表draw()。请参阅下面的解决方案 2。
2 - 重组你的数据库
无论哪种情况,您当前的数据库模型都要求您不断循环获取。这意味着您发出的请求数量与您的circleCount. 这对您的使用不利,因为每个请求都需要额外的行程时间,而我们正在努力减少所需的时间,以便更接近实时。(或匹配帧速率)
目前,您的圈子似乎circles1 circles2全部保存为root,因为您正在使用.ref("circles" + j)它们来检索它们。这样您就可以像这样保存您的圈子:.ref("circles/" + j)这意味着每个圈子circle现在都保存在 circles. 像circles/circle1 circles/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);
});
}
Run Code Online (Sandbox Code Playgroud)
基本上,这将继续绘制我们从 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..."
}
}
Run Code Online (Sandbox Code Playgroud)
希望这些有所帮助:) 很高兴见到另一位 Processing & Firebase 的粉丝。
| 归档时间: |
|
| 查看次数: |
459 次 |
| 最近记录: |