我一直无法在网上找到类似的问题,所以我想我会提交这个问题。在大多数情况下,似乎人们遇到了相反的问题,即在触摸事件期间可能会发生延迟,但我看到的情况恰恰相反。我正在创建一个空气曲棍球游戏,每一帧都根据它们当前的参数移动棋子,并且在后台重写 ontouch 侦听器正在寻找运动事件时重绘游戏。问题是当没有手指触摸屏幕而只是观看动画片段时会有明显的延迟,但只要有任何形式的运动事件发生,如果调用 ontouch,则动画是流畅的。我真的想不通这是为什么,
关于如何组织一切的更多背景知识。整体类位于Main.java中,在这里创建并请求Context视图,游戏类是ImageView的扩展。游戏类有一个@override OnTouchEvent,它包含根据什么状态和什么运动事件做什么的所有定义。该类还有一个draw方法,在方法结束时它调用h.postDelayed(r, FRAME_RATE); 其中 r 是带有 @Override public void run() 的 Runnable,它只调用 invalidate();。h 只是一个在类中初始化的处理程序。所以每次绘制游戏时,都会在 10 毫秒的 FRAME_RATE 消逝时间后调用 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);
}
}
}