Android:多次启动活动时出现奇怪的多线程行为

时间:2014-07-27 10:28:20

标签: java android multithreading android-activity

我想为Android编写一个简单的游戏。因此我想使用一个线程用于draw-loop和一个线程用于update-loop。我有两个活动:一个菜单活动(启动器)和一个游戏活动(循环在其中)。当我多次开始游戏活动时,尽管每次活动开始时它都被重置,但每个活动开始时测试对象的移动速度会更快。我不知道如何解决这个问题

Launchactivity :(播放方法由xml文件中的按钮调用)

public class ThrustActivity extends Activity {

static Bitmap player;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_thrust);

    player = BitmapFactory.decodeResource(getResources(), R.drawable.test);
}

public void play(View v)
{
    Intent intent = new Intent(getApplicationContext(), GameActivity.class);
    startActivity(intent);
}}

Gameactivity:

public class GameActivity extends Activity
{
Screen screen;
private Loop loop;
private Tick tick;
boolean pause;
float tilt;
double ticks;
Paint paint;

Administration admin;;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    screen = new Screen(getApplicationContext());
    setContentView(screen);

    paint = new Paint();

    loop = new Loop();
    tick = new Tick();

    admin = new Administration();
}



private class Loop extends Thread
{
    public void run()
    {
        while(!pause)
        {
            screen.draw();
        }
    }
}

private class Tick extends Thread
{
    public void run() 
    {
        while(!pause)
        {
            long TimeFrameLasts;        
            long TimeStartFrame;
            TimeFrameLasts = 1;
            ticks = 64; 
            final int origticks = 64;  //Norm: 64
            double wantedticks = origticks;
            while(true)
            {
                ticks = 1000/TimeFrameLasts;
                TimeStartFrame = System.currentTimeMillis();

                admin.update(0);

                try {
                    Thread.sleep((long)(1000/wantedticks));
                } catch (InterruptedException e) {
                    e.printStackTrace();    
                }
                TimeFrameLasts = System.currentTimeMillis()-TimeStartFrame;
                if(ticks>origticks)
                {
                    if(ticks>origticks+100)wantedticks-=2;
                    else wantedticks--;                 
                }
                else if(ticks<origticks&&!(wantedticks>500))
                {
                    if(ticks<origticks-100)wantedticks+=2;
                    else wantedticks++;
                }
            }
        }
        return;
    }
}

protected void onResume() 
{
    super.onResume();
    admin = new Administration();
    pause = false;
    loop.start();
    tick.start();
}

protected void onPause()
{
    super.onPause();
    pause = true;
    finish();
}


private class Screen extends SurfaceView implements Callback
{
    SurfaceHolder surfaceHolder;

    public Screen(Context context) 
    {
        super(context);
        surfaceHolder = getHolder();
        surfaceHolder.addCallback(this);
        setOnTouchListener(new onToucListener());
    }

    public void draw()
    {
        if(surfaceHolder.getSurface().isValid())
        {
            Canvas c = surfaceHolder.lockCanvas();

            int x = c.getWidth();
            int y = c.getHeight();

            paint.setColor(Color.WHITE); 
            paint.setStyle(Style.FILL); 
            c.drawPaint(paint); 

            paint.setColor(Color.BLACK);
            paint.setTextSize(30);
            c.drawText("Ticks: " + (int)ticks, 50, 50, paint);

            for(int i = 0; i < 10; i++)
            {
                for(int j = 0; j < 20; j++)
                {
                    //c.drawText(""+i*10+","+j*10, i*100, j*100, paint);
                    c.drawRect(i*100, j*100, i*100+4, j*100+4, paint);
                }
            }

            for(Entity e :Administration.entities)c.drawBitmap(e.getTexture(), (int)e.getX(), (int)e.getY(), null);

            surfaceHolder.unlockCanvasAndPost(c);
        }
    }

    public void surfaceCreated(SurfaceHolder holder) {}

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

    }

    public void surfaceDestroyed(SurfaceHolder holder) {}
}

private class onToucListener implements OnTouchListener
{

    public boolean onTouch(View v, MotionEvent event) 
    {
        Player.setToJump(true);
        return false;
    }

}}

实体管理

public class Administration 
{
public static ArrayList<Entity> entities;
public static ArrayList<Entity> toAdd;
public static ArrayList<Entity> toRemove;
Player p;

public Administration()
{
    entities = new ArrayList<Entity>();
    toAdd = new ArrayList<Entity>();
    toRemove = new ArrayList<Entity>();
    p = new Player();
}

public void update(float tilt)
{
    try
    {
        for(Entity e:entities)e.updateEntity(tilt);
    }
    catch(Exception e){e.printStackTrace();}
    //Wird ~30 mal in der Sekunde aufgerufen

    try
    {
        for(Entity e:toAdd)entities.add(e);
    }
    catch(Exception e){e.printStackTrace();}
    try
    {
        for(Entity e:toRemove)entities.remove(e);
    }
    catch(Exception e){e.printStackTrace();}
    toAdd = new ArrayList<Entity>();
    toRemove = new ArrayList<Entity>();
}

public void reset()
{
    entities = new ArrayList<Entity>();
    toAdd = new ArrayList<Entity>();
    toRemove = new ArrayList<Entity>();

    p = new Player();
}

}

玩家

public class Player extends Entity
{
double difX, difY;
boolean canJump;
static boolean toJump;

public Player()
{
    super(ThrustActivity.player, 300, 300, null, 0);
    difX = 0;
    difY = 0;
    canJump = true;
}

public void update(float tilt)
{
    difX = -tilt;

    if(toJump && canJump)difY -= 2;

    difY += 0.025;

    setPosX(getX()+difX);
    setPosY(getY()+difY);

    toJump = false;
}

public void setDifX(double difX)
{
    this.difX = difX;
}

public void setDifY(double difY)
{
    this.difY = difY;
}

public static void setToJump(boolean toJump)
{
    Player.toJump = toJump;
}

}

对不起任何语法错误(我不是母语人士)

0 个答案:

没有答案