1

我是 Android 编程的初学者,我正在开发一款小型泡泡射击游戏。但是,我面临一个我无法弄清楚的奇怪问题。我有一段处理应用程序启动器的代码,如果我在课堂上编写整个代码,应用程序运行顺利。但是,如果我将代码“切割”成不同的类,那么启动器的移动就会出现明显的滞后。

我的主要问题是:什么会导致这种滞后,以及避免这种滞后的最佳方法是什么(现在和将来)。

提前致谢,

亲切的问候,

这是我在一个类中编写所有内容时的代码。

package com.example.bubbleshootergame;
// imports are delete to shorten the post
public class GameThree extends Activity implements OnTouchListener {
OurView v;
Bitmap launcher;
float x, y, rotationAngle;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    v = new OurView(this);
    v.setOnTouchListener(this);
    launcher = BitmapFactory.decodeResource(getResources(),
            R.drawable.launcher);

    setContentView(v);
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    v.pause();
}

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    v.resume();
}

public class OurView extends SurfaceView implements Runnable {

    Thread t = null;
    SurfaceHolder holder;
    boolean bool = false;

    public OurView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        holder = getHolder();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        View content = getWindow().findViewById(Window.ID_ANDROID_CONTENT);
        // x & y are the width and height of the usable screen size
        x = content.getWidth();
        y = content.getHeight();
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (bool == true) {
            if (!holder.getSurface().isValid()) {
                continue;
            }

            Canvas c = holder.lockCanvas();
            Paint Blackline = new Paint();
            Blackline.setColor(Color.rgb(0, 0, 0));
            Blackline.setStrokeWidth(10);

            // background color of canvas
            c.drawARGB(255, 255, 255, 255);
            c.drawRect(0, (float) 0.85*y, x, (float) 0.84*y, Blackline);
            // rotate by angle 'rotationAngle' around point x/2 and y
            // this corresponds the middle of the launcher
            c.rotate(rotationAngle, x / 2, y - (launcher.getHeight() / 2));
            // draw the bitmap (this case the launcher) around the center of
            // the width of the launcher and bottom of the launcher
            c.drawBitmap(launcher, x / 2 - (launcher.getWidth() / 2), y
                    - (launcher.getHeight()), null);            
            holder.unlockCanvasAndPost(c);

        }
    }

    public void pause() {
        // TODO Auto-generated method stub
        bool = false;
        while (true) {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            break;
        }
        t = null;
    }

    public void resume() {
        // TODO Auto-generated method stub
        bool = true;
        t = new Thread(this);
        t.start();
    }
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    // TODO Auto-generated method stub
    float currentX = event.getX();
    float currentY = event.getY();

    if (currentY >= 0.85*y ){

    }       
    else    
    switch (event.getAction()) {
    case MotionEvent.ACTION_MOVE: {
        double rotationAngleRadians = Math.atan2(currentX - x / 2, y
                - currentY);

        rotationAngle = (int) Math.toDegrees(rotationAngleRadians);
        return true;
    }
    }
    return true;

}

}

以下是使用不同类时的代码块: MainActivity

package com.gabrudar.conquestappgame;
public class MainActivity extends Activity implements OnTouchListener {

GameView view;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

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

    view = new GameView(this);
    view.setOnTouchListener(this);
    setContentView(view);
}

@Override
protected void onPause() {
    super.onPause();
    view.pause();
}

@Override
protected void onResume() {
    super.onResume();
    view.resume();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    // TODO Auto-generated method stub
    try {
        Thread.sleep(50);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    view.processTouch(event);

    return true;
}

}

游戏视图:

package com.gabrudar.conquestappgame;

public class GameView extends SurfaceView implements Runnable {

Thread gameThread = null;
SurfaceHolder holder;
boolean continueRunning = false;

    Bitmap blob;
Bitmap background;
Sprite sprite;
Rect screenRect;

Bitmap Launcher;
LauncherC launcher;

long startTime;
float deltaTime;

public GameView(Context context) {
    super(context);
    holder = getHolder();
    screenRect = new Rect();

    background = BitmapFactory.decodeResource(getResources(), R.drawable.androidbg);
    blob = BitmapFactory.decodeResource(getResources(), R.drawable.spritesheet);

    Launcher = BitmapFactory.decodeResource(getResources(),
            R.drawable.launcher);
    launcher = new LauncherC(Launcher);

}

@Override
public void run() {

    startTime = System.nanoTime();
    while (continueRunning == true){
        if (!holder.getSurface().isValid()){
            continue;
        }

        deltaTime = (System.nanoTime() - startTime)/1000000;
        startTime = System.nanoTime();

        Canvas c = holder.lockCanvas();
        onDraw(c);
        holder.unlockCanvasAndPost(c);

    }
}

public void pause() {
    continueRunning = false;
    while(true){
        try{
            gameThread.join();
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        break;
    }
    gameThread = null;
}

public void resume() {
    continueRunning = true;
    gameThread = new Thread(this);
    gameThread.start();
}
protected void update(float dt) {
}

protected void onDraw(Canvas canvas) {
    this.getDrawingRect(screenRect);
    canvas.drawBitmap(background, null, screenRect, null);
    launcher.onDraw(canvas);
}

public void processTouch(MotionEvent me) {
    launcher.Toucher(me);
}

}

启动器:

package com.gabrudar.conquestappgame;
public class LauncherC {
float rotationAngle,x1,y1;
Bitmap L1;


public LauncherC(Bitmap Launcher){
    L1 = Launcher;
}

public void onDraw(Canvas c) {
    // TODO Auto-generated method stub
    Paint Blackline = new Paint();
    Blackline.setColor(Color.rgb(0, 0, 0));
    Blackline.setStrokeWidth(10);

    x1 = c.getWidth();
    y1 = c.getHeight();

    c.drawRect(0, (float) 0.85 * y1, x1, (float) 0.84 * y1, Blackline);
    c.rotate(rotationAngle, x1 / 2, y1 - (L1.getHeight() / 2));
    c.drawBitmap(L1, x1 / 2 - (L1.getWidth() / 2), y1
            - (L1.getHeight()), null);

}

public void Toucher(MotionEvent event){
    // TODO Auto-generated method stub
    float currentX = event.getX();
    float currentY = event.getY();

    if (currentY >= 0.85 * y1) {
    } else
        switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE: {
            double rotationAngleRadians = Math.atan2(currentX - x1 / 2, y1
                    - currentY);
            rotationAngle = (int) Math.toDegrees(rotationAngleRadians);
        break;
        }
        }
}


}
4

1 回答 1

1

好吧,我看到的一个明显区别是在您的“分离”代码中。我在原始代码中没有看到它,它肯定会导致延迟,因为每次收到触摸事件时你都会休眠 50 毫秒。这可以通过拖动式运动每秒发生多次。

public boolean onTouch(View v, MotionEvent event) {
    // TODO Auto-generated method stub
    try {
        Thread.sleep(50);
        ....
于 2013-11-04T20:01:14.363 回答