我还没能在网上找到类似的问题,所以我想我会提交问题。在大多数情况下,似乎人们有相反的问题,在触摸事件期间可能发生滞后,但我看到的恰恰相反。我正在创建一个空气曲棍球游戏,每个框架根据他们当前的参数移动棋子,并且在背景中重绘游戏,覆盖的ontouch听众正在寻找运动事件。当没有手指触摸屏幕并且只是观看动画片段时,存在明显的滞后,但是只要发生任何形式的运动事件,如果正在调用触摸,则动画是平滑的。我真的无法理解为什么会这样,我最好的猜测是正在检查是否应该调用ontouch的中断消耗的资源比应该消耗的多,但我对如何修改或检查ontouch中断行为一无所知有人可能知道。
关于一切如何组织的更多背景知识。整个类位于Main.java中,它在这里创建并请求Context视图,游戏类是ImageView的扩展。游戏类有一个@override OnTouchEvent,它根据什么状态和什么运动事件具有所做的所有定义。该类还有一个draw方法,在方法结束时调用h.postDelayed(r,FRAME_RATE);其中r是带有@Override的Runnable public void run(),它只调用invalidate();. h只是在类中初始化的处理程序。因此,每次游戏被绘制时,将在FRAME_RATE经过10ms的时间后调用invalidate,这将告诉游戏重绘。游戏的所有移动功能也都是从draw方法调用的。 OnTouch一直在这个过程中发生,所以为什么如果在OnTouch被调用而不是检查它是否真实,它会更顺畅,这一切似乎都是反直觉但我确信有合理的理由。最后,延迟时间可以使用系统时钟进行测量,并且取决于它的确切调用位置。它只是表明在未发生触摸事件时游戏移动功能之间的传递时间增加。
很抱歉没有太多实际代码上下文的长响应,我希望它足够描述。代码本身相当长,所以我认为发布它会有所帮助,但如果需要,我可以更好地发布一些带有可视化层次结构的伪代码。感谢您对此问题的任何帮助和建议。能够理解为什么会发生这种情况会很棒。
以下是代码,我试图将其纳入评论中并没有意识到您必须通过编辑原始帖子发布它。
public class Main extends Activity {
Game game;
private Menus menus; // contains menu info
int menu; //keep track of what menu you are at
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
game = new Game(this);
setContentView(game);
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
..some code here to process photo files
}
//get the orientation of loaded pictures
public static int getOrientation(Context context, Uri photoUri) {
/* it's on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if (cursor.getCount() != 1) {
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
public void Keyboard()
{
use keyboard listener and perform some actions if...
}
public class Game extends ImageView{
private Game game;
//Touch Events
boolean pressed;
private Context mContext;
private Handler h;
private final int FRAME_RATE = 10;
boolean initDimension = false;
//constant for defining the time duration between the click that can be considered as double-tap
static final int MAX_DURATION = 500;
Bitmap background;
int HEIGHT;
int WIDTH;
public Game(Context context) {
super(context);
mContext = context;
h = new Handler();
//ModeInit(); // load up puck game mode
menu = 0; //after tap from ontouch changes to menu = 1 for game
}
private Runnable r = new Runnable() {
@Override
public void run() {
invalidate();
}
};
@Override
public boolean onTouchEvent(MotionEvent e)
{
Switch Statement...
CHECK MOTION EVENT TYPE
CHECK menu state.. perform action
}
public void ModeInit()
{
game = new Game( mContext, WIDTH, HEIGHT );
}
protected void onDraw(Canvas c)
{
if(!initDimension)
{
WIDTH = this.getWidth();
HEIGHT = this.getHeight();
initDimension = true;
}
else
{
//logo screen
if(menu == 0)
{
menu = menus.DisplayIntro(c);
}
//game mode
else if(menu == 1)
{
game.paint_game(c);
long run_test = System.nanoTime()/1000;
game.Move();
Log.d("run time: ",": "+(System.nanoTime()/1000-run_test)); //Ontouch LAG TEST
}
... other menu items here
}
h.postDelayed(r, FRAME_RATE);
}
}
}