在Android中创建GameLoop

时间:2012-09-03 10:05:33

标签: android multithreading surfaceview game-loop surfaceholder

我正在创建一个与此应用程序中的GameLoop相关的应用程序,如果用户点击屏幕在屏幕上绘制图像并且它在随机速度和随机方向上在屏幕上移动..在代码中有没有错误,但是当我尝试运行该应用程序时,我最终得到了一个关闭erroe的力量。

这是我的源代码:

源代码:GameLoop.java

public class GameLoop extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new Sview(this));
}
}

源代码:Sview.java

public class Sview extends SurfaceView implements Callback{

Bitmap bmp;
public static float mHeight;
public static float mWidth;
ViewThread mThread;
private ArrayList<elements> mElements=new ArrayList <elements>();
Paint p1;

public Sview(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
    mThread = new ViewThread();
    getHolder().addCallback(this);
}

@Override
public boolean onTouchEvent(MotionEvent event)
{
    synchronized (mElements) {
        mElements.add(new elements(getResources(), (int)event.getX(), (int)event.getY()));
    }
    return super.onTouchEvent(event);
}

public void update(long elapsed)
{
    synchronized (mElements)
    {
        for(elements el : mElements)
        {
            el.animate_ele(elapsed);
        }
    }
}

public void mydraw(long elapsed, Canvas c)
{
    c.drawColor(Color.BLACK);
    synchronized (mElements)
    {
        for(elements el : mElements)
        {
            el.draw_ele(c);
        }
    }
    c.drawText("FPS: "+Math.round(1000f/elapsed), 40, 40, p1);
}

public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    // TODO Auto-generated method stub
    mHeight = height;
    mWidth = width;
}

public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    if(!mThread.isAlive())
    {
        mThread.setRun(true);
        mThread.start();
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    if(mThread.isAlive())
    {
        mThread.setRun(false);
        mThread.stop();
    }
}
}

源代码:ViewThread.java

public class ViewThread extends Thread{

private Sview myView;
private SurfaceHolder mHolder;
private boolean mRun = false;
private long StartTime, elapsed;

public View Thread (Sview sv)
{
    myView = sv;
    mHolder = myView.getHolder();
    return sv;
}

public void setRun(boolean b)
{
    mRun = b;
}

@Override
public void run()
{
    Canvas can = null;
    StartTime = System.currentTimeMillis();
    while(mRun)
    {
        can = mHolder.lockCanvas();
        if(can!=null)
        {
            myView.update(elapsed);
            myView.mydraw(elapsed, can);
            elapsed = System.currentTimeMillis() - StartTime;
            mHolder.unlockCanvasAndPost(can);
        }
        StartTime = System.currentTimeMillis();
    }

}
}

源代码:elements.java

public class elements {

private int mx, my, mspeedx, mspeedy;
Bitmap bmp1;

public elements(Resources res, int x, int y)
{
    bmp1 = BitmapFactory.decodeResource(res, R.drawable.ic_launcher);
    mx = x;
    my = y;
    Random r1 = new Random();
    mspeedx = r1.nextInt(7)-3;
    mspeedy = r1.nextInt(7)-3;
}

public void draw_ele(Canvas c)
{
    c.drawBitmap(bmp1, mx, mx, null);
}

public void animate_ele(long elapsed)
{
    mx+=mspeedx*(elapsed/50f);
    my+=mspeedy*(elapsed/50f);
    checkborder();
}

private void checkborder()
{
    if(mx<=0)
    {
        mspeedx=-mspeedx;
        mx=0;
    }
    else if(mx>=Sview.mWidth)
    {
        mspeedx=-mspeedx;
        mx=(int)Sview.mWidth;
    }
    if(my<=0)
    {
        mspeedy=-mspeedy;
        my=0;
    }
    else if(my>=Sview.mHeight)
    {
        mspeedy=-mspeedy;
        my=(int)Sview.mHeight;
    }
}
}

我得到的错误是:

08-29 00:05:55.982: E/AndroidRuntime(2295): FATAL EXCEPTION: Thread-8
08-29 00:05:55.982: E/AndroidRuntime(2295): java.lang.NullPointerException
08-29 00:05:55.982: E/AndroidRuntime(2295):     at com.pnf.game.ViewThread.run(ViewThread.java:31)
08-29 00:05:56.292: E/global(2295): Deprecated Thread methods are not supported.
08-29 00:05:56.292: E/global(2295): java.lang.UnsupportedOperationException
08-29 00:05:56.292: E/global(2295):     at java.lang.VMThread.stop(VMThread.java:85)
08-29 00:05:56.292: E/global(2295):     at java.lang.Thread.stop(Thread.java:1379)
08-29 00:05:56.292: E/global(2295):     at java.lang.Thread.stop(Thread.java:1344)
08-29 00:05:56.292: E/global(2295):     at com.pnf.game.Sview.surfaceDestroyed(Sview.java:85)
08-29 00:05:56.292: E/global(2295):     at android.view.SurfaceView.reportSurfaceDestroyed(SurfaceView.java:568)
08-29 00:05:56.292: E/global(2295):     at android.view.SurfaceView.updateWindow(SurfaceView.java:472)
08-29 00:05:56.292: E/global(2295):     at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:206)
08-29 00:05:56.292: E/global(2295):     at android.view.View.dispatchWindowVisibilityChanged(View.java:3891)
08-29 00:05:56.292: E/global(2295):     at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:719)
08-29 00:05:56.292: E/global(2295):     at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:719)
08-29 00:05:56.292: E/global(2295):     at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:719)
08-29 00:05:56.292: E/global(2295):     at android.view.ViewRoot.performTraversals(ViewRoot.java:744)
08-29 00:05:56.292: E/global(2295):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
08-29 00:05:56.292: E/global(2295):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-29 00:05:56.292: E/global(2295):     at android.os.Looper.loop(Looper.java:123)
08-29 00:05:56.292: E/global(2295):     at android.app.ActivityThread.main(ActivityThread.java:4627)
08-29 00:05:56.292: E/global(2295):     at java.lang.reflect.Method.invokeNative(Native Method)
08-29 00:05:56.292: E/global(2295):     at java.lang.reflect.Method.invoke(Method.java:521)
08-29 00:05:56.292: E/global(2295):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-29 00:05:56.292: E/global(2295):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-29 00:05:56.292: E/global(2295):     at dalvik.system.NativeStart.main(Native Method)

提前致谢...

1 个答案:

答案 0 :(得分:0)

java.lang.Thread的android java doc提到stop是弃用的(参见http://developer.android.com/reference/java/lang/Thread.html#stop())。你真正需要做的是将ViewThread的mRun设置为false并在ViewThread上调用join以确保它已停止运行。