我一直在制作游戏已经有一段时间了,只是意识到我一直都做错了,但仍然没有真正了解更多。
我有一个控制类,我的MainActivity
,它几乎只做以下事情:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
operator=new Operator(getBaseContext());
setContentView(R.layout.activity_main); //<- framelayout with the view and two buttons on top
}
//Buttons:
public void shoot(View view) {
operator.shoot(view.getId());
}
public void pause(View view) {
AndronXView.running=!AndronXView.running;
}
然后有我的View
,它绘制Actors并使我的workerthread计算所有内容:
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
animHandler = new Handler();
animHandler.postDelayed(loadLvl1, 5000);
arrayOfActors = operator.getActors(); //simplyfied to one array
if(arrayOfActors==null)
arrayOfActors=new Actor[0]; //if op hasn't loaded yet, prevent NPE in onDraw
//stripped of unimportant color and size computing stuff
}
protected void onDraw(final Canvas canvas){
//Should I copy player before doing this? Never got problems here so far.
canvas.drawBitmap(operator.player.getCurrentGraphic(), operator.player.getX(), operator.player.getY(), null);
for(Actor actor:arrayOfActors) {
canvas.drawBitmap(actor.getCurrentGraphic(), actor.getX(), actor.getY(), null);
}
if (running) {
operator.run(); //Compute. Realized my mistake here and changed the inside, wait for it.
animHandler.postDelayed(r, Operator.FRAME_RATE); //r=invalidate();
animHandler.post(loadActors); //get Arrays from op
}else animHandler.post(wait);
}
Runnable wait = new Runnable() {
@Override
public void run() {
if (running)
animHandler.post(r);
else animHandler.postDelayed(this, Operator.FRAME_RATE);
}
};
@Override
public boolean onTouchEvent(@NonNull MotionEvent event){
int action = event.getAction();
if(action==MotionEvent.ACTION_DOWN || action==MotionEvent.ACTION_MOVE){
operator.player.setSpeed((event.getX()-operator.player.getHorizontalMid())
/AndronX.PLAYER_MOVE_LAG,
(event.getY()-operator.player.getVerticalMid())/AndronX.PLAYER_MOVE_LAG);
}
return true;
}
然后我的Operator
延伸Thread
,它会计算背景中演员的动作和互动:
public Operator(Context baseContext) {
this.player = new Player(baseContext); //context to load drawable from ressource
arrayListOfActors=new ArrayList<>();
//Looper.prepare(); //it crashed and said only one Looper/Thread
//Looper.loop(); //so I removed it
opHandler = new Handler();
}
@Override
public void run() {
opHandler.post(gameStep); //before, I had the whole processing inside this run().
}
private Runnable gameStep = new Runnable(){
player.move();
computeEveryMemberOf(arrayListOfActors); //much computing happens here, usually
//contains 1-30 Actors that get cross-referenced
arrayOfActors = arrayListOfActors.toArray(new Actor[arrayListOfActors.size()]);
}
public Actor[] getActors(){
return arrayOfActors;
}
之前,我直接在我的运算符run()方法中进行了计算,我意识到后台线程无用。我不确定如果这是正确的方法,我应该让操作员自己循环,这两个线程是否会保持同步?它甚至重要吗?
或者我应该去run(){ sleep(FRAME_RATE); compute();}
?
编辑:出现了一个大问题,我不确定是不是因为这个问题,所以我真的需要一个答案,如何以正确的方式做到这一点。
每走一步,我都会向一些演员稍微向上或向下移动,像一个像速度一样的余弦波(就像它投射到一个轴上一样),而且目前,实际的动作并没有通过视图,他们只是从最大值跳到最小值并返回,尽管它们以所需的速度运行(看起来像极端滞后)。
实际上,您可以亲眼看看这个问题是什么:https://dl.dropboxusercontent.com/u/28278772/AndronX.apk