2012-06-08 35 views
9

Tôi đang cố gắng vẽ một quả bóng vào màn hình của mình bằng 3 lớp. Tôi đã đọc một chút về điều này và tôi đã tìm thấy một đoạn mã hoạt động bằng cách sử dụng 3 lớp trên một trang, Playing with graphics in AndroidAndroid vẽ bằng SurfaceView và Thread

Tôi thay đổi mã để tôi có bóng chuyển động và dịch chuyển hướng khi chạm vào tường như hình ảnh dưới đây (điều này đang sử dụng mã trong liên kết).

moving ball screenshot

Bây giờ tôi muốn tách lớp thành 3 trang khác nhau cho không làm cho mọi thứ nên đông đúc, tất cả mọi thứ được thiết lập cùng một cách.

Dưới đây là 3 lớp tôi có.

  1. BallActivity.java
  2. Ball.java
  3. BallThread.java

package com.brick.breaker; 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.Window; 
import android.view.WindowManager; 


public class BallActivity extends Activity { 

private Ball ball; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 

    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    ball = new Ball(this); 
    setContentView(ball); 
} 

@Override 
protected void onPause() { 

    super.onPause(); 

    setContentView(null); 
    ball = null; 

    finish(); 
} 

} 

package com.brick.breaker; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 

public class Ball extends SurfaceView implements SurfaceHolder.Callback { 

private BallThread ballThread = null; 

private Bitmap bitmap; 

private float x, y; 
private float vx, vy; 

public Ball(Context context) { 
    super(context); 

    bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ball); 

    x = 50.0f; 
    y = 50.0f; 

    vx = 10.0f; 
    vy = 10.0f; 

    getHolder().addCallback(this); 
    ballThread = new BallThread(getHolder(), this); 
} 

protected void onDraw(Canvas canvas) { 

    update(canvas); 

    canvas.drawBitmap(bitmap, x, y, null); 
} 

public void update(Canvas canvas) { 

    checkCollisions(canvas); 

    x += vx; 
    y += vy; 
} 

public void checkCollisions(Canvas canvas) { 

    if(x - vx < 0) { 

     vx = Math.abs(vx); 

    } else if(x + vx > canvas.getWidth() - getBitmapWidth()) { 

     vx = -Math.abs(vx); 
    } 

    if(y - vy < 0) { 

     vy = Math.abs(vy); 

    } else if(y + vy > canvas.getHeight() - getBitmapHeight()) { 

     vy = -Math.abs(vy); 
    } 
} 

public int getBitmapWidth() { 

    if(bitmap != null) { 

     return bitmap.getWidth(); 

    } else { 

     return 0; 
    } 
} 

public int getBitmapHeight() { 

    if(bitmap != null) { 

     return bitmap.getHeight(); 

    } else { 

     return 0; 
    } 
} 

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

} 

public void surfaceCreated(SurfaceHolder holder) { 

    ballThread.setRunnable(true); 
    ballThread.start(); 

} 

public void surfaceDestroyed(SurfaceHolder holder) { 

    boolean retry = true; 
    ballThread.setRunnable(false); 

    while(retry) { 

     try { 

      ballThread.join(); 
      retry = false; 

     } catch(InterruptedException ie) { 

      //Try again and again and again 
     } 

     break; 
    } 

    ballThread = null; 

} 

} 

package com.brick.breaker; 

import android.graphics.Canvas; 
import android.view.SurfaceHolder; 

public class BallThread extends Thread { 

private SurfaceHolder sh; 
private Ball ball; 

private Canvas canvas; 

private boolean run = false; 

public BallThread(SurfaceHolder _holder,Ball _ball) { 

    sh = _holder; 
    ball = _ball; 
} 

public void setRunnable(boolean _run) { 

    run = _run; 
} 

public void run() { 

    while(run) { 

     canvas = null; 

     try { 

      canvas = sh.lockCanvas(null); 

      synchronized(sh) { 

       ball.onDraw(canvas); 
      } 

     } finally { 

      if(canvas != null) { 

       sh.unlockCanvasAndPost(canvas); 
      } 

     } 

    } 
} 

public Canvas getCanvas() { 

    if(canvas != null) { 

     return canvas; 

    } else { 

     return null; 
    } 
} 
} 

Đây là hình ảnh hiển thị kết quả của các lớp này.

enter image description here

Tôi đã cố gắng để con số này ra nhưng kể từ khi tôi là khá mới để phát triển Android Tôi nghĩ tôi có thể yêu cầu giúp đỡ.

Có ai biết điều gì khiến quả bóng bị thu hút như thế không? Mã này khá giống với mã trong liên kết và tôi đã cố thử nghiệm để tìm giải pháp nhưng không may mắn.

Trả lời

14

cũng như bạn có thể thấy trên hình ảnh, bạn chỉ vẽ bóng. thay vào đó, bạn cần phải vẽ lại một nền đen (hoặc bất cứ điều gì bạn muốn) trước khi bạn vẽ bóng.

cách khác, bạn có thể vẽ một vùng màu đen chỉ ở vị trí trước đó, nhưng bạn có thể gặp vấn đề với nó sau này, khi bạn sử dụng nhiều đối tượng hơn.

here's a nice sample, tương tự như những gì bạn làm

+0

Yepp mà cố định vấn đề của tôi, vào phương pháp onDraw tôi thêm vào dòng canvas. drawColor (Color.BLACK); trước khi tôi vẽ bóng để màn hình sẽ được lấp đầy với màu đen loại bỏ các bộ phim bóng màu xanh lá cây không mong muốn. Thx alot =) –

+0

btw, cho hoạt ảnh mượt mà hơn và nhanh hơn, tôi khuyên bạn nên sử dụng opengl. canvas chỉ dành cho các công cụ đơn giản, đặc biệt là hiện tại hầu hết các thiết bị vẫn không có GPU hỗ trợ các công cụ đồ họa, vì hầu hết vẫn còn trên phiên bản Android "cũ" (bánh gừng). –

+0

lời khuyên tuyệt vời =) Tôi sẽ mess xung quanh với các mã trên sau đó tạo ra một dự án mới và làm logic tương tự nhưng bằng cách sử dụng OpenGL. Thx for the tip :) –

1

Nhìn nhanh và tôi sẽ phải nói rằng bạn chỉ vẽ trên cùng một bề mặt và không bao giờ yêu cầu surfaceview của bạn vẽ lại chính nó. ở cuối khối cuối cùng, trong Tuyên bố IF sử dụng: postInvalidate(); Điều đó sẽ làm cho chế độ xem bề mặt vẽ lại chính nó.

1

đặt này

public void onDraw(Canvas canvas){ 
    canvas.drawColor(Color.BLACK); 

..... 

} 
-1

[sửa] Câu trả lời là sai, nhưng những nhận xét là hữu ích vì vậy tôi sẽ để lại câu trả lời này lên:

Không phải là câu hỏi bạn đã hỏi, nhưng có một vấn đề trong mã của bạn. Trong Android, bạn chỉ được phép ghi vào màn hình trong chuỗi giao diện người dùng. Đây là luồng chạy tất cả các cuộc gọi lại hoạt động, v.v. Bằng cách viết vào màn hình từ BallThread, bạn đang mạo hiểm nhiều lần thất bại trong chương trình của mình.

+2

'SurfaceView' có thể được cập nhật từ một chuỗi khác - http://developer.android.com/reference/android/view/SurfaceView.html –

+0

Cảm ơn bạn. Đã học được điều gì đó mới mẻ. –

Các vấn đề liên quan