2012-10-15 9 views
6

मैं एक साधारण गेम इंजन बनाने के लिए थ्रेड का उपयोग करके कैनवास पर ड्राइंग के साथ प्रयोग कर रहा हूं लेकिन मुझे कुछ अजीब समस्याएं हैं जिन्हें मैं समझा नहीं सकता। इस "गेम" का उद्देश्य कैनवास पर हर सेकेंड में एक सर्कल खींचना है। यह काम करता है, लेकिन जिस तरह से मैं इसे काम करना चाहता हूं, ऐसा लगता है कि ऐप दो कैनवासों के बीच स्विच कर रहा है और प्रत्येक कैनवास में एक सर्कल जोड़ रहा है ताकि आपको दो कैनवासों के बीच एक ही संख्या में सर्किलों के साथ एक स्विच मिल जाए लेकिन एक अलग कैनवास पर रखें।एंड्रॉइड सर्फेस व्यू कैनवास ड्राइंग

मुझे नहीं पता कि मैं क्या गलत कर रहा हूं, लेकिन मैं ट्रेडडिंग से परिचित नहीं हूं, क्या मेरे एंड्रॉइड डिवाइस के कितने कोर हैं या ऐसा कुछ है?

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

परियोजना एक मुख्य launchthread से बाहर मौजूद है:

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
    } 
} 

जो इस लेआउट फ़ाइल का उपयोग करता है:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent">  
     <com.androidtesting.AnimationView 
      android:id="@+id/aview" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent"/> 
</FrameLayout> 

और एक आंतरिक थ्रेड वर्ग के साथ मेरी SurfaceView वर्ग:

class AnimationView extends SurfaceView implements SurfaceHolder.Callback { 
    private boolean touched = false; 
    private float touched_x, touched_y = 0; 
    private Paint paint; 
    private Canvas c; 
    private Random random; 
    private AnimationThread thread; 

    public AnimationView(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     SurfaceHolder holder = getHolder(); 
     holder.addCallback(this); 

     thread = new AnimationThread(holder); 
    } 

    class AnimationThread extends Thread { 
     private boolean mRun;  
     private SurfaceHolder mSurfaceHolder;   

     public AnimationThread(SurfaceHolder surfaceHolder) { 
      mSurfaceHolder = surfaceHolder; 
      paint = new Paint(); 
      paint.setARGB(255,255,255,255); 
      paint.setTextSize(32); 
     } 

     @Override 
     public void run() { 
      while (mRun) { 
       c = null; 
       try { 
        c = mSurfaceHolder.lockCanvas(null); 
        synchronized (mSurfaceHolder) {     
         doDraw(c); 
         sleep(1000); 
        } 
       } catch (Exception e) {     
        e.printStackTrace(); 
       }finally { 
        if (c != null) { 
         mSurfaceHolder.unlockCanvasAndPost(c); 
        } 
       } 
      } 
     } 

     private void doDraw(Canvas canvas) { 
      //clear the canvas 
      //canvas.drawColor(Color.BLACK);       

      random = new Random(); 
      int w = canvas.getWidth(); 
      int h = canvas.getHeight(); 
      int x = random.nextInt(w-50); 
      int y = random.nextInt(h-50); 
      int r = random.nextInt(255); 
      int g = random.nextInt(255); 
      int b = random.nextInt(255); 
      int size = 20; 
      canvas.drawCircle(x,y,size,paint);    
      canvas.restore(); 
     } 
     public void setRunning(boolean b) { 
      mRun = b; 
     } 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 

    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
      touched_x = event.getX(); 
      touched_y = event.getY(); 

      int action = event.getAction(); 

      switch(action){ 
       case MotionEvent.ACTION_DOWN:   
        touched = true; 
        break; 
       case MotionEvent.ACTION_MOVE: 
        touched = true; 
        break;   
       default: 
        touched = false; 
        break; 
      } 

      return true; 
    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     thread.setRunning(true); 
     thread.start(); 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     boolean retry = true; 
     thread.setRunning(false); 
     while (retry) { 
      try { 
       thread.join(); 
       retry = false; 
      } catch (InterruptedException e) { 
      } 
     } 
    } 
} 
+0

क्या यह आपके कोड में AnimationView2 होना चाहिए? एक सही संस्करण की सराहना की जाएगी। – RichieHH

+0

(पीएस जब आप नमूने उदाहरण से कोड कॉपी करते हैं (यह हल्के ढंग से संशोधित चंद्र लैंडर है) यह हमेशा यह बताने के लिए सबसे अच्छा है क्योंकि यह बग शिकार को आसान बनाता है))। – RichieHH

उत्तर

4

ऐसा लगता है कि ऐप दो सीए के बीच स्विच कर रहा है nvasses

हां, यह इस तरह काम करता है। यह कहा जाता है डबल बफरिंग और आप सभी फ्रेम each time पुनः बनाने की जरूरत है:

सतह की सामग्री unlockCanvas() और lockCanvas() के बीच संरक्षित कभी नहीं किया जाता है, इस कारण के लिए, सतह क्षेत्र के भीतर हर पिक्सेल होना चाहिए लिखा हुआ।

तो आपको अपने कोड में असम्बद्ध होने के लिए canvas.drawColor(Color.BLACK) इस लाइन की आवश्यकता है।

और आपको Thread.sleep(1000) पर कॉल नहीं करना चाहिए जबकि कैनवास लॉक है, यह starvation समस्या का कारण बन जाएगा।

+0

ठीक है, आपके उत्तर के लिए धन्यवाद, इसलिए मुझे किसी प्रकार की आइरेस्टिस्ट कहने की ज़रूरत है, जहां मैं अपनी सभी सर्कल ऑब्जेक्ट्स रखता हूं और फिर सर्कल को आकर्षित करने के लिए ड्रॉ विधि में ArrayList को लूप करता हूं? – randomizer

+0

यदि आप प्रत्येक सेकेंड में एक सर्कल जोड़ना चाहते हैं और एक समय में उन सभी को आकर्षित करना चाहते हैं तो हाँ, आपको सूची में उन सभी के बारे में जानकारी स्टोर करने की आवश्यकता है, प्रत्येक फ्रेम को इस सूची को पार करें और सभी मंडलियों को आकर्षित करें। –

+0

ठीक थाक्स, अब यह सब चल रहा है :) – randomizer

0

ऐसा लगता है कि आपके पास यह काम है, लेकिन मैंने अभी एक छोटी सी त्रुटि देखी है जिसे मुझे इंगित करना चाहिए।

आपने पहले कैनवास.save() को कॉल किए बिना canvas.restore() कहा है। कैनवास के लिए एंड्रॉइड डेवलपर संदर्भ से: "सहेजने() को कॉल करने से अधिक बार पुनर्स्थापित() कॉल करने में त्रुटि होती है।"

मुझे आपके मामले में canvas.save() को कॉल करने का कोई कारण नहीं दिख रहा है, इसलिए आपको canvas.restore() पर कॉल को हटा देना चाहिए।

+0

क्या आप कृपया इसके साथ मेरी सहायता कर सकते हैं? http://stackoverflow.com/questions/33909257/canvas-draw-functions-not-working-after-screen-locked-and-unlocked – Jas

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