Java Android:使用类时代码滞后
我是Android编程的初学者,正在开发一款小型的泡泡射击游戏。然而,我面临着一个我无法理解的奇怪问题。我有一段代码来处理应用程序的启动程序,如果我在课堂上对整个代码进行编程,应用程序就会运行顺畅。然而,如果我将代码“剪切”成不同的类,那么启动器的移动就会有明显的滞后 我的主要问题是:什么会导致这种滞后,以及(现在和将来)避免这种滞后的最佳方法是什么 提前感谢, 亲切问候, 这是我在一个类中编写所有程序时的代码Java Android:使用类时代码滞后,java,android,surfaceview,lag,Java,Android,Surfaceview,Lag,我是Android编程的初学者,正在开发一款小型的泡泡射击游戏。然而,我面临着一个我无法理解的奇怪问题。我有一段代码来处理应用程序的启动程序,如果我在课堂上对整个代码进行编程,应用程序就会运行顺畅。然而,如果我将代码“剪切”成不同的类,那么启动器的移动就会有明显的滞后 我的主要问题是:什么会导致这种滞后,以及(现在和将来)避免这种滞后的最佳方法是什么 提前感谢, 亲切问候, 这是我在一个类中编写所有程序时的代码 package com.example.bubbleshootergame; //
package com.example.bubbleshootergame;
// imports are delete to shorten the post
public class GameThree extends Activity implements OnTouchListener {
OurView v;
Bitmap launcher;
float x, y, rotationAngle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
v = new OurView(this);
v.setOnTouchListener(this);
launcher = BitmapFactory.decodeResource(getResources(),
R.drawable.launcher);
setContentView(v);
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
v.pause();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
v.resume();
}
public class OurView extends SurfaceView implements Runnable {
Thread t = null;
SurfaceHolder holder;
boolean bool = false;
public OurView(Context context) {
super(context);
// TODO Auto-generated constructor stub
holder = getHolder();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
View content = getWindow().findViewById(Window.ID_ANDROID_CONTENT);
// x & y are the width and height of the usable screen size
x = content.getWidth();
y = content.getHeight();
}
@Override
public void run() {
// TODO Auto-generated method stub
while (bool == true) {
if (!holder.getSurface().isValid()) {
continue;
}
Canvas c = holder.lockCanvas();
Paint Blackline = new Paint();
Blackline.setColor(Color.rgb(0, 0, 0));
Blackline.setStrokeWidth(10);
// background color of canvas
c.drawARGB(255, 255, 255, 255);
c.drawRect(0, (float) 0.85*y, x, (float) 0.84*y, Blackline);
// rotate by angle 'rotationAngle' around point x/2 and y
// this corresponds the middle of the launcher
c.rotate(rotationAngle, x / 2, y - (launcher.getHeight() / 2));
// draw the bitmap (this case the launcher) around the center of
// the width of the launcher and bottom of the launcher
c.drawBitmap(launcher, x / 2 - (launcher.getWidth() / 2), y
- (launcher.getHeight()), null);
holder.unlockCanvasAndPost(c);
}
}
public void pause() {
// TODO Auto-generated method stub
bool = false;
while (true) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
t = null;
}
public void resume() {
// TODO Auto-generated method stub
bool = true;
t = new Thread(this);
t.start();
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
float currentX = event.getX();
float currentY = event.getY();
if (currentY >= 0.85*y ){
}
else
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE: {
double rotationAngleRadians = Math.atan2(currentX - x / 2, y
- currentY);
rotationAngle = (int) Math.toDegrees(rotationAngleRadians);
return true;
}
}
return true;
}
}
以下是使用不同类时的代码块:
主要活动
package com.gabrudar.conquestappgame;
public class MainActivity extends Activity implements OnTouchListener {
GameView view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
view = new GameView(this);
view.setOnTouchListener(this);
setContentView(view);
}
@Override
protected void onPause() {
super.onPause();
view.pause();
}
@Override
protected void onResume() {
super.onResume();
view.resume();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
view.processTouch(event);
return true;
}
}
游戏视图:
package com.gabrudar.conquestappgame;
public class GameView extends SurfaceView implements Runnable {
Thread gameThread = null;
SurfaceHolder holder;
boolean continueRunning = false;
Bitmap blob;
Bitmap background;
Sprite sprite;
Rect screenRect;
Bitmap Launcher;
LauncherC launcher;
long startTime;
float deltaTime;
public GameView(Context context) {
super(context);
holder = getHolder();
screenRect = new Rect();
background = BitmapFactory.decodeResource(getResources(), R.drawable.androidbg);
blob = BitmapFactory.decodeResource(getResources(), R.drawable.spritesheet);
Launcher = BitmapFactory.decodeResource(getResources(),
R.drawable.launcher);
launcher = new LauncherC(Launcher);
}
@Override
public void run() {
startTime = System.nanoTime();
while (continueRunning == true){
if (!holder.getSurface().isValid()){
continue;
}
deltaTime = (System.nanoTime() - startTime)/1000000;
startTime = System.nanoTime();
Canvas c = holder.lockCanvas();
onDraw(c);
holder.unlockCanvasAndPost(c);
}
}
public void pause() {
continueRunning = false;
while(true){
try{
gameThread.join();
}catch(InterruptedException e){
e.printStackTrace();
}
break;
}
gameThread = null;
}
public void resume() {
continueRunning = true;
gameThread = new Thread(this);
gameThread.start();
}
protected void update(float dt) {
}
protected void onDraw(Canvas canvas) {
this.getDrawingRect(screenRect);
canvas.drawBitmap(background, null, screenRect, null);
launcher.onDraw(canvas);
}
public void processTouch(MotionEvent me) {
launcher.Toucher(me);
}
}
发射器:
package com.gabrudar.conquestappgame;
public class LauncherC {
float rotationAngle,x1,y1;
Bitmap L1;
public LauncherC(Bitmap Launcher){
L1 = Launcher;
}
public void onDraw(Canvas c) {
// TODO Auto-generated method stub
Paint Blackline = new Paint();
Blackline.setColor(Color.rgb(0, 0, 0));
Blackline.setStrokeWidth(10);
x1 = c.getWidth();
y1 = c.getHeight();
c.drawRect(0, (float) 0.85 * y1, x1, (float) 0.84 * y1, Blackline);
c.rotate(rotationAngle, x1 / 2, y1 - (L1.getHeight() / 2));
c.drawBitmap(L1, x1 / 2 - (L1.getWidth() / 2), y1
- (L1.getHeight()), null);
}
public void Toucher(MotionEvent event){
// TODO Auto-generated method stub
float currentX = event.getX();
float currentY = event.getY();
if (currentY >= 0.85 * y1) {
} else
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE: {
double rotationAngleRadians = Math.atan2(currentX - x1 / 2, y1
- currentY);
rotationAngle = (int) Math.toDegrees(rotationAngleRadians);
break;
}
}
}
}
我看到的一个明显的区别是你的“分离”代码。我在原始代码中没有看到,它肯定会引起延迟,因为每次收到触摸事件时,你都会睡50毫秒。这种情况在拖动类型的移动中每秒可能发生多次
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
try {
Thread.sleep(50);
....
我看到的一个明显的区别是你的“分离”代码。我在原始代码中没有看到,它肯定会引起延迟,因为每次收到触摸事件时,你都会睡50毫秒。这种情况在拖动类型的移动中每秒可能发生多次
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
try {
Thread.sleep(50);
....
不幸的是,这种大小的帖子很少被触碰——它太大了。如果你能用25%的代码展示这是多么的慢,你会有更好的机会。不幸的是,这样大小的帖子很少被触动——它太大了。如果你能用25%的代码显示这是多么的慢,你会有更好的机会。@MaximShoustin也许我错过了它,但我在顶部代码块中根本看不到
睡眠。你能指出这一点吗?天哪,我真不敢相信我竟然没有注意到这一点!我一直忽视它。谢谢你的回答,这确实是个问题。Thanks@Geobits是的,你是对的,一次睡眠算两次,tnx@user5489附带说明:如果你想放慢游戏速度,可以在单独的游戏中添加睡眠thread@MaximShoustin也许我错过了它,但我在顶部代码块中根本看不到睡眠。你能指出这一点吗?天哪,我真不敢相信我竟然没有注意到这一点!我一直忽视它。谢谢你的回答,这确实是个问题。Thanks@Geobits是的,你是对的,一次睡眠算两次,tnx@user5489附带说明:如果你想减缓游戏速度,可以在单独的游戏线程中添加睡眠