2017-11-04 20 views
6

को फिर से निकालने के तरीके में असीमित कार्य हो रहा है, मैं एक ऐसा एप्लिकेशन बनाने की कोशिश कर रहा हूं जहां एक फायरबेस डाटाबेस से जानकारी पढ़ने के माध्यम से मंडलियों को मंडलियों पर खींचा जाता है जो एक्स और वाई निर्देशांक संग्रहीत करता है सर्किल हालांकि नीचे दिए गए कोड को निष्पादित करना, सर्कल के किसी भी संकेत के बिना, कुछ भी उत्पन्न नहीं करता है, क्योंकि फ़ंक्शन ड्राक्रिक्स असीमित रूप से चलता है, और इस प्रकार कमांड background(40) सर्किल खींचा जाने से पहले सबकुछ साफ़ कर देता है।फायरबेस जेस्क्रिप्ट + पी 5.जेएस: कैनवास

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(); 
} 
+0

कृपया अपनी समस्या को छोटे टुकड़ों में तोड़ने की कोशिश करें [http://happycoding.io/tutorials/how-to/program) और एक समय में केवल एक टुकड़े पर काम करें। उदाहरण के लिए, क्या आप एक साधारण प्रोग्राम लिख सकते हैं जो फायरबेस से डेटा पुनर्प्राप्त करता है? आगे बढ़ने से पहले इसे पूरी तरह से काम करें। उससे अलग, क्या आप एक प्रोग्राम बना सकते हैं जो कुछ हार्ड-कोड किए गए बिंदु प्रदर्शित करता है? इससे पहले कि आप उन्हें एक कार्यक्रम में गठबंधन करने से पहले पूरी तरह से काम कर लें। यदि आप किसी विशिष्ट चरण पर फंस जाते हैं, तो उस चरण के [mcve] को पोस्ट करें। सौभाग्य। –

+1

@ केविन वर्कमैन मैंने समस्या को इस तथ्य से कम कर दिया है कि पृष्ठभूमि (40) स्क्रीन पर खींची गई सभी मंडलियों को साफ़ कर रही है क्योंकि drawCircles() असीमित रूप से चल रहा है। – Vaporeon

उत्तर

0

ऐसा लगता है आपकी समस्या को केवल प्रति सेकंड 60 फ्रेम है, जो एक पैर रेस स्थिति खड़ी कर रहा है है। फायरबेस .once एसिंक को निष्पादित करने पर पूरा करेगा, और पी 5 इसके लिए इंतजार नहीं करेगा क्योंकि यह इसके फ्रेमरेट टाइमिंग के साथ चिपकेगा।

इस विशिष्ट मामले में मेरे पास कई अनुशंसाएं हैं जो आपको उम्मीद के परिणाम के बहुत करीब आती हैं।

1 - पुनर्गठन अपने कोड

वहाँ अपने कोड की वर्तमान संरचना के साथ दो मुद्दों है।

  • केस 1: आपके वर्तमान कोड मुझे नेतृत्व करेंगे अपनी मंडलियों डेटाबेस में वास्तविक समय में अपडेट किया जाता है सोचने के लिए, और आप तारीख तक रहने की जरूरत है, तो आप अपने नवीनतम स्थिति प्राप्त करने में कठिनाई रहते हैं। यदि ऐसा है, तो आपको .once("value") के बजाय .on("value") का उपयोग करना चाहिए और जब भी सर्कल बदलती है तो फायरबेस आपको अपडेट भेजता है, बजाय राउंडट्रिप अनुरोध समय को बचाने के लिए इसे 60 बार एक सेकंड पूछने के बजाय। यदि यह मामला है: नीचे मेरे समाधान 1 देखें।

  • केस 2: यदि आपकी मंडलियों को डेटाबेस में रीयल-टाइम अपडेट नहीं किया गया है, और आप केवल मंडलियों की पूरी सूची चाहते हैं, तो आप किसी भी कारण से 60 बार दूसरी बार सूची ला रहे हैं। आपको .once का उपयोग करके सूची को draw() में उस सूची के माध्यम से सेट करने और पुन: स्थापित करने के बाद सूची में लाने के लिए चाहिए। नीचे समाधान 2 देखें।

2 - पुनर्गठन अपने डेटाबेस

या तो मामले में, अपने वर्तमान डेटाबेस मॉडल एक पाश में प्राप्त करने में कठिनाई रखने के लिए की आवश्यकता है। जिसका अर्थ है कि आप अपने circleCount के रूप में कई अनुरोध कर रहे हैं। यह आपके उपयोग के लिए बुरा है, बस इसलिए कि प्रत्येक अनुरोध में अतिरिक्त यात्रा का समय लगता है, और हम जो समय लेते हैं उसे कम करने की कोशिश कर रहे हैं, ताकि यह वास्तविक समय के करीब हो। (या फ़्रेमरेट से मेल खाते हैं)

वर्तमान में अपनी मंडलियों प्रतीत होता है circles1 आदि circles2 सभी के रूप में जड़ पर है, क्योंकि आप उन्हें पुनः प्राप्त करने के .ref("circles" + j) का उपयोग कर रहे सहेजे जाते हैं। इसे बनाएं ताकि आप अपनी मंडलियों को इस तरह से सहेज सकें: .ref("circles/" + j) जिसका अर्थ यह होगा कि प्रत्येक circle अब circles में सहेजा गया है। circles/circle1circles/circle2 आदि

इसका लाभ यह है कि अब आपको सभी सर्किलों को फायरबेस के अतिरिक्त अनुरोधों की आवश्यकता नहीं है। फायरबेस में एक ही अनुरोध के साथ सभी बच्चों के माध्यम से forEach अविश्वसनीय रूप से सुविधाजनक चीजें हैं।

3 - अपने firebase कॉलबैक में पृष्ठभूमि साफ

वर्तमान में, आप एक फ्रेम-दर विशेष तरीके से पृष्ठभूमि साफ़ करें। इसका मतलब यह है कि यदि आपकी प्रत्येक फायरबेस कॉल एक सेकंड (16 मिलीसेकंड) के 1/60 वें से अधिक समय लेती है तो आप पृष्ठभूमि को साफ़ कर देंगे और आगे बढ़ेंगे। हमारे डेटाबेस को ढूढ़ने के बाद भी आप इस गति को प्राप्त करने की संभावना बहुत कम हैं। तो इसके बजाय, मैं पहले 30fps का उपयोग करने की अनुशंसा करता हूं, जो प्रति सेकंड 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); 
    }); 
} 

असल में यह फायरबेस से प्राप्त होने वाली अंतिम सर्कल स्थितियों को तब तक खींचा जाएगा जब तक कि हम एक नया प्राप्त न करें। (ताकि पी 5 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..." 
    } 
} 

इन मदद आशा :) यह एक और देखने के लिए अच्छा है प्रोसेसिंग & फायरबेस के साथी प्रशंसक।

0

मैं डॉक्स में देखा है और यहाँ कैसे वे एक प्राप्त किए गए डेटा से निपटने के लिए सुझाव है की एक example है:

यहाँ मेरी कोड है। आपके मामले में, अलग प्राप्त कर रहा है और ड्राइंग करने का प्रयास करें, कुछ वैश्विक चर का उपयोग कर अपने डाटा को कैश:

var circles = []; 
 

 
function fetchData() { 
 
    firebase.database().ref("circles").once("value", 
 
    function(snapshot) { 
 
     var snapshotVal = snapshot.val(); 
 
     var circleCount = snapshotVal.numCircles; 
 
     
 
     circles = []; 
 

 
     for (var j = 0; j < circleCount; j++) { 
 
      firebase.database().ref("circles" + j).once("value",     function(snapshot) { 
 
       circles.push(snapshot.val()); 
 
      }); 
 
     } 
 
    }); 
 
} 
 

 
function setup() { 
 
    createCanvas(windowWidth, windowHeight); 
 
    background(40); 
 
    stroke(80); 
 
    smooth(); 
 
    frameRate(60); 
 
    fetchData(); 
 
} 
 

 
function drawCircles() { 
 
    circles.forEach(function (snapshotValue) { 
 
     var snapshotValue = snapshot.val(); 
 
     fill(143, 2, 2); 
 
     ellipse(snapshotValue.xPos, 50, 50); 
 
    }); 
 
} 
 

 
function draw() { 
 
    stroke(80); 
 
    background(40); 
 

 
    stroke(0); 
 
    drawCircles(); 
 
}

आप हमेशा प्रासंगिक डेटा प्रदर्शित करने के लिए की जरूरत है, setInterval का उपयोग कर fetchData समारोह, जैसे कॉल करने के लिए कोशिश :

function setup() { 
 
     createCanvas(windowWidth, windowHeight); 
 
     background(40); 
 
     stroke(80); 
 
     smooth(); 
 
     frameRate(60); 
 
     setInterval(fetchData, 5000); //will call fetchData every 5000 ms 
 
    }

+0

मैंने आपके कोड की कोशिश की, लेकिन दुर्भाग्यवश मंडल अभी भी दिखाई नहीं दे रहे हैं। – Vaporeon

0
समस्या

कि drawCircles() अतुल्यकालिक है नहीं है - समस्या यह है कि draw()frameRate() पर कहा जाता है, और background() एक दूसरे के प्रत्येक अंश एक ठोस रंग के साथ स्क्रीन को साफ करता है जब ड्रा लूप: देखने draw reference और background। यदि आप draw() से background(40) लाइन को हटाते हैं तो यह प्रत्येक फ्रेम को स्क्रीन साफ़ नहीं करेगा, और खींची गई मंडल वांछित के रूप में जमा हो जाएंगी। यह प्रत्येक फ्रेम के सभी फायरबेस डेटा को दोबारा हटाने से आसान है।

निम्नलिखित स्केच कि अवधारणा को दर्शाता है: background() केवल, setup() दौरान कहा जाता है, draw() दौरान नहीं तो स्क्रीन क्षेत्र एक बार रंग का है, तो धीरे-धीरे हलकों कि जमा के साथ ओवरराइट।

function setup() { 
 
    createCanvas(400, 200); 
 
    frameRate(5) 
 
    background(40); 
 
} 
 
function drawCircles() { 
 
    fill(143, 2, 2); 
 
    ellipse(random(width), 50, 50); 
 
} 
 
function draw() { 
 
    // background(40); 
 
    drawCircles(); 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.16/p5.js"></script> 
 
<html> 
 
    <head> 
 
    </head> 
 
    <body> 
 
    </body> 
 
</html>

आप कुछ चीजें प्रत्येक फ्रेम जमा करने के लिए और दूर दूसरों पोंछ चाहते हैं, तो आप एक createGraphics बफर पर अपनी मंडलियों के जमा करने के लिए की जरूरत है। प्रत्येक फ्रेम फिर से कैनवास पर सर्कल के बफर को फिर से चलाता है, फिर शीर्ष पर क्षणिक तत्व (जैसे माउस सूचक आदि) खींचा जाता है।

यहां एक उदाहरण है: प्रत्येक फ्रेम कैनवास background() के साथ साफ़ किया गया है, तो pg बफर कैनवास पर खींचा जाता है, फिर माउस पर एक सफेद सर्कल खींचा जाता है। चूंकि पृष्ठभूमि स्क्रीन को साफ़ करती है, इसलिए सफेद सर्कल फ्रेम से फ्रेम के पीछे पीछे नहीं निकलता है - लेकिन लाल मंडल को एक गैर-साफ़ ग्राफिक्स बफर पर खींचा जाता है, इसलिए वे बने रहते हैं।

var pg; 
 
function setup() { 
 
    createCanvas(400, 200); 
 
    pg = createGraphics(400, 200); 
 
    background(40); 
 
} 
 
function drawCircles() { 
 
    pg.fill(143, 2, 2); 
 
    pg.ellipse(random(pg.width), 50, 50); 
 
} 
 
function draw() { 
 
    background(40); 
 
    drawCircles(); 
 
    image(pg,0,0); 
 
    fill(255); 
 
    ellipse(mouseX,mouseY,50,50); 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.16/p5.js"></script> 
 
<html> 
 
    <head> 
 
    </head> 
 
    <body> 
 
    </body> 
 
</html>

संबंधित मुद्दे