Java Android:多次启动活动时奇怪的多线程行为
我想为Android编写一个简单的游戏。因此,我想使用一个线程来绘制循环,使用一个线程来更新循环。我有两个活动:一个菜单活动(启动程序)和一个游戏活动(循环在其中)。当我多次启动游戏活动时,testobject在每次activitystart时都会移动得更快,尽管每次活动启动时都会重置它。我不知道如何解决这个问题 Launchactivity:(播放方法由xml文件中的按钮调用) 游戏活动:Java Android:多次启动活动时奇怪的多线程行为,java,android,multithreading,android-activity,Java,Android,Multithreading,Android Activity,我想为Android编写一个简单的游戏。因此,我想使用一个线程来绘制循环,使用一个线程来更新循环。我有两个活动:一个菜单活动(启动程序)和一个游戏活动(循环在其中)。当我多次启动游戏活动时,testobject在每次activitystart时都会移动得更快,尽管每次活动启动时都会重置它。我不知道如何解决这个问题 Launchactivity:(播放方法由xml文件中的按钮调用) 游戏活动: public class GameActivity extends Activity { Screen
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;
}
}}
}
顺便说一句,对于任何语法错误(我不是母语人士)是
testobject
播放器吗?如果是这样的话,我注意到你每次更新都会无条件地给玩家的速度增加0.025。如果没有更多细节,就无法确定这是否是有意的,但这肯定会导致加速。是的,但在每次活动开始时,玩家都会加速,尽管加速度应始终为0.025/滴答(这只是一个测试,因为我想做一个基于跳跃的游戏->物体以0.025/tick的加速度下落,如果你点击屏幕,加速度中会加上-2)此外,每次活动开始时,玩家都会被重置。这只是另一个澄清,你的目标是恒定加速度还是恒定速度?因为你的代码确实显示0.025/滴答加速度,但这不会导致速度不受控制地增加吗?你可能会混淆加速度增加和速度增加吗?放弃请告诉我,如果这些对你来说似乎微不足道,我只想确保在你发送给我们搜索不存在的bug之前,这不是一个术语问题。你是对的,这是在增加速度而不是增加加速度,但这不是我的问题。第一次启动游戏活动时,一切正常。问题是在多次启动之后玩家似乎更新得更频繁
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;
}