我正在嘗試創建一個函式來檢查移動的子彈是否擊中了玩家。
簡化的代碼 -shoot()移動子彈,并 check_if_bullet_hit_player(bulletRef)獲得子彈參考,并檢查子彈是否擊中任何玩家。
這是我的代碼:
function shoot(){
// ... moving bullet code
const bulletRef = firebase.database().ref(`bullets/${bulletKey}`);
if(check_if_bullet_hit_player(bulletRef)){
alert("player got hit");
bulletRef.remove();
}
}
function check_if_bullet_hit_player(bulletRef){
bulletRef.once("value").then(function(snapshot) {
//for simplicity I just return true - player got hit
return true;
}
}
該代碼沒有觸發alert(). 讀完這個問題后,我認為異步的問題,但是如何將引數傳遞給函式,并獲取函式的回傳值。
編輯:
這是完整的check_if_bullet_hit_player()功能,我回圈播放器,并檢查子彈是否是<0.5一個玩家(如果是 - 它算作命中):
function check_if_bullet_hit_player(bulletRef){
//bulletRef.once("value").then(function(snapshot) {
return bulletRef.get().then(snapshot => {
let bulletX = snapshot.val().x;
let bulletY = snapshot.val().y;
let shooterId = snapshot.val().shooterId;
//loop over players
const allPlayersRef = firebase.database().ref(`players`);
allPlayersRef.once("value", (snapshot) => {
players = snapshot.val() || {};
Object.keys(players).forEach((key) => {
if(getDistance(players[key].x, players[key].y, bulletX, bulletY) < 0.5){
if(players[key].id != shooterId){ //not the shooter
return true;
}
// ...
uj5u.com熱心網友回復:
事實上,問題來自于該once()方法是異步的。但是您也忘記了在函式中回傳承諾鏈。check_if_bullet_hit_player()
以下內容,then()正如您在問題中所做的那樣,應該可以解決問題:
function shoot() {
// ... moving bullet code
const bulletRef = firebase.database().ref(`bullets/${bulletKey}`);
check_if_bullet_hit_player(bulletRef)
.then(result => {
if (result)
bulletRef.remove();
})
}
function check_if_bullet_hit_player(bulletRef) {
return bulletRef.get().then(snapshot => { // See return at the beginning, and also that we use get()
return snapshot.exists(); // I think you should check if the snapshot exists
});
}
請注意,該shoot()函式也是異步的。因此,如果將它與其他函式呼叫鏈接起來,則需要使用then()(并回傳承諾鏈)或async/await.
根據您的評論和問題更新進行編輯:
同樣,您沒有回傳承諾鏈。您可以按如下方式對其進行修改,但我建議您使用every()“對陣列中存在的每個元素執行一次提供的回呼函式,直到找到回呼回傳虛假值的那個”的方法
function check_if_bullet_hit_player(bulletRef) {
let bulletX;
let bulletY;
let shooterId;
return bulletRef.get().then(snapshot => {
bulletX = snapshot.val().x;
bulletY = snapshot.val().y;
shooterId = snapshot.val().shooterId;
//loop over players
const allPlayersRef = firebase.database().ref(`players`);
return allPlayersRef.get(); // HERE we chain the promise
})
.then(allPlayersSnap => {
players = allPlayersSnap.val() || {};
let result = false;
Object.keys(players).forEach((key) => {
if (getDistance(players[key].x, players[key].y, bulletX, bulletY) < 0.5 && players[key].id != shooterId) {
result = true;
}
});
return result;
});
}
額外說明
似乎這些函式是在前端執行的(您使用firebase.database()...)您可能應該在后端進行計算,例如通過云函式,以避免惡意用戶偽造結果的可能性。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/442713.html
標籤:javascript 火力基地 异步 firebase-实时数据库
上一篇:如何從CompletableFuture.whenComplete例外塊中拋出RuntimeExcpetions?
