我的应用程序在模拟器上完全运行和工作,但在物理设备上崩溃



你们能帮我解决问题吗?我的程序在Android Studio Emulator(Pixel 2 API 28(上运行没有问题,但是在我将其安装在手机上(三星Galaxy S8 + API 28(后,每次我点击播放按钮:(时,它都会不断崩溃。我也在一些手机上尝试过,但我仍然有同样的问题

实际上这不是我的程序,但我在 youtube 上找到了它,但在 youtube 中制作代码的人给了我在我的术语项目中使用它的绿灯。

有关如何在YouTube中制作该程序的视频链接:

https://www.youtube.com/watch?v=5W3rVBDYFjE

这是您可以运行它的源代码的链接:

https://github.com/heyletscode/2D-Game-In-Android-Studio

我想要的只是在物理设备上运行此代码,尤其是在我的手机三星Galaxy S8 +上。我似乎无法解决我有点绝望的问题。我很抱歉对Java编程很陌生。

根据@Marc的要求为 com.heyletscode.ihavetofly.Flight Class 的代码

<小时 />
int toShoot = 0;
boolean isGoingUp = false;
int x, y, width, height, wingCounter = 0, shootCounter = 1;
Bitmap flight1, flight2, shoot1, shoot2, shoot3, shoot4, shoot5, dead;
private GameView gameView;
Flight(GameView gameView, int screenY, Resources res) {
this.gameView = gameView;
flight1 = BitmapFactory.decodeResource(res, R.drawable.fly1);
flight2 = BitmapFactory.decodeResource(res, R.drawable.fly2);
width = flight1.getWidth();
height = flight1.getHeight();
width /= 4;
height /= 4;
width *= (int) screenRatioX;
height *= (int) screenRatioY;
flight1 = Bitmap.createScaledBitmap(flight1, width, height, false);
flight2 = Bitmap.createScaledBitmap(flight2, width, height, false);
shoot1 = BitmapFactory.decodeResource(res, R.drawable.shoot1);
shoot2 = BitmapFactory.decodeResource(res, R.drawable.shoot2);
shoot3 = BitmapFactory.decodeResource(res, R.drawable.shoot3);
shoot4 = BitmapFactory.decodeResource(res, R.drawable.shoot4);
shoot5 = BitmapFactory.decodeResource(res, R.drawable.shoot5);
shoot1 = Bitmap.createScaledBitmap(shoot1, width, height, false);
shoot2 = Bitmap.createScaledBitmap(shoot2, width, height, false);
shoot3 = Bitmap.createScaledBitmap(shoot3, width, height, false);
shoot4 = Bitmap.createScaledBitmap(shoot4, width, height, false);
shoot5 = Bitmap.createScaledBitmap(shoot5, width, height, false);
dead = BitmapFactory.decodeResource(res, R.drawable.dead);
dead = Bitmap.createScaledBitmap(dead, width, height, false);
y = screenY / 2;
x = (int) (64 * screenRatioX);
}
Bitmap getFlight() {
if (toShoot != 0) {
if (shootCounter == 1) {
shootCounter++;
return shoot1;
}
if (shootCounter == 2) {
shootCounter++;
return shoot2;
}
if (shootCounter == 3) {
shootCounter++;
return shoot3;
}
if (shootCounter == 4) {
shootCounter++;
return shoot4;
}
shootCounter = 1;
toShoot--;
gameView.newBullet();
return shoot5;
}
if (wingCounter == 0) {
wingCounter++;
return flight1;
}
wingCounter--;
return flight2;
}
Rect getCollisionShape() {
return new Rect(x, y, x + width, y + height);
}
Bitmap getDead() {
return dead;
}
}

-----------编辑------------

>CODE for GameView.java
private Thread thread;
private boolean isPlaying, isGameOver = false;
private int screenX, screenY, score = 0;
public static float screenRatioX, screenRatioY;
private Paint paint;
private Bird[] birds;
private SharedPreferences prefs;
private Random random;
private SoundPool soundPool;
private List<Bullet> bullets;
private int sound;
private Flight flight;
private GameActivity activity;
private Background background1, background2;
public GameView(GameActivity activity, int screenX, int screenY) {
super(activity);
this.activity = activity;
prefs = activity.getSharedPreferences("game", Context.MODE_PRIVATE);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_GAME)
.build();
soundPool = new SoundPool.Builder()
.setAudioAttributes(audioAttributes)
.build();
} else
soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
sound = soundPool.load(activity, R.raw.shoot, 1);
this.screenX = screenX;
this.screenY = screenY;
screenRatioX = 1920f / screenX;
screenRatioY = 1080f / screenY;
background1 = new Background(screenX, screenY, getResources());
background2 = new Background(screenX, screenY, getResources());
flight = new Flight(this, screenY, getResources());
bullets = new ArrayList<>();
background2.x = screenX;
paint = new Paint();
paint.setTextSize(128);
paint.setColor(Color.WHITE);
birds = new Bird[4];
for (int i = 0;i < 4;i++) {
Bird bird = new Bird(getResources());
birds[i] = bird;
}
random = new Random();
}
@Override
public void run() {
while (isPlaying) {
update ();
draw ();
sleep ();
}
}
private void update () {
background1.x -= 10 * screenRatioX;
background2.x -= 10 * screenRatioX;
if (background1.x + background1.background.getWidth() < 0) {
background1.x = screenX;
}
if (background2.x + background2.background.getWidth() < 0) {
background2.x = screenX;
}
if (flight.isGoingUp)
flight.y -= 30 * screenRatioY;
else
flight.y += 30 * screenRatioY;
if (flight.y < 0)
flight.y = 0;
if (flight.y >= screenY - flight.height)
flight.y = screenY - flight.height;
List<Bullet> trash = new ArrayList<>();
for (Bullet bullet : bullets) {
if (bullet.x > screenX)
trash.add(bullet);
bullet.x += 50 * screenRatioX;
for (Bird bird : birds) {
if (Rect.intersects(bird.getCollisionShape(),
bullet.getCollisionShape())) {
score++;
bird.x = -500;
bullet.x = screenX + 500;
bird.wasShot = true;
}
}
}
for (Bullet bullet : trash)
bullets.remove(bullet);
for (Bird bird : birds) {
bird.x -= bird.speed;
if (bird.x + bird.width < 0) {
if (!bird.wasShot) {
isGameOver = true;
return;
}
int bound = (int) (30 * screenRatioX);
bird.speed = random.nextInt(bound);
if (bird.speed < 10 * screenRatioX)
bird.speed = (int) (10 * screenRatioX);
bird.x = screenX;
bird.y = random.nextInt(screenY - bird.height);
bird.wasShot = false;
}
if (Rect.intersects(bird.getCollisionShape(), flight.getCollisionShape())) {
isGameOver = true;
return;
}
}
}
private void draw () {
if (getHolder().getSurface().isValid()) {
Canvas canvas = getHolder().lockCanvas();
canvas.drawBitmap(background1.background, background1.x, background1.y, paint);
canvas.drawBitmap(background2.background, background2.x, background2.y, paint);
for (Bird bird : birds)
canvas.drawBitmap(bird.getBird(), bird.x, bird.y, paint);
canvas.drawText(score + "", screenX / 2f, 164, paint);
if (isGameOver) {
isPlaying = false;
canvas.drawBitmap(flight.getDead(), flight.x, flight.y, paint);
getHolder().unlockCanvasAndPost(canvas);
saveIfHighScore();
waitBeforeExiting ();
return;
}
canvas.drawBitmap(flight.getFlight(), flight.x, flight.y, paint);
for (Bullet bullet : bullets)
canvas.drawBitmap(bullet.bullet, bullet.x, bullet.y, paint);
getHolder().unlockCanvasAndPost(canvas);
}
}
private void waitBeforeExiting() {
try {
Thread.sleep(3000);
activity.startActivity(new Intent(activity, MainActivity.class));
activity.finish();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void saveIfHighScore() {
if (prefs.getInt("highscore", 0) < score) {
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("highscore", score);
editor.apply();
}
}
private void sleep () {
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void resume () {
isPlaying = true;
thread = new Thread(this);
thread.start();
}
public void pause () {
try {
isPlaying = false;
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (event.getX() < screenX / 2) {
flight.isGoingUp = true;
}
break;
case MotionEvent.ACTION_UP:
flight.isGoingUp = false;
if (event.getX() > screenX / 2)
flight.toShoot++;
break;
}
return true;
}
public void newBullet() {
if (!prefs.getBoolean("isMute", false))
soundPool.play(sound, 1, 1, 0, 0, 1);
Bullet bullet = new Bullet(getResources());
bullet.x = flight.x + flight.width;
bullet.y = flight.y + (flight.height / 2);
bullets.add(bullet);
}
}

这是我的三星Galaxy S8 +上安装程序上的播放按钮后,"错误"选项卡上的Logcat选项卡

<小时 />
2019-10-07 16:59:12.317 11879-11879/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2019-10-07 16:59:12.322 11879-11879/? E/Zygote: accessInfo : 1
2019-10-07 16:59:21.447 11879-11879/com.heyletscode.ihavetofly E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.heyletscode.ihavetofly, PID: 11879
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.heyletscode.ihavetofly/com.heyletscode.ihavetofly.GameActivity}: java.lang.IllegalArgumentException: width and height must be > 0
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3114)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
Caused by: java.lang.IllegalArgumentException: width and height must be > 0
at android.graphics.Bitmap.createBitmap(Bitmap.java:1074)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1041)
at android.graphics.Bitmap.createBitmap(Bitmap.java:991)
at android.graphics.Bitmap.createBitmap(Bitmap.java:912)
at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:782)
at com.heyletscode.ihavetofly.Flight.<init>(Flight.java:35)
at com.heyletscode.ihavetofly.GameView.<init>(GameView.java:70)
at com.heyletscode.ihavetofly.GameActivity.onCreate(GameActivity.java:22)
at android.app.Activity.performCreate(Activity.java:7327)
at android.app.Activity.performCreate(Activity.java:7318)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3094)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:214) 
at android.app.ActivityThread.main(ActivityThread.java:7050) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) 

实际问题出现在GameView.java:64中,其中使用固定的屏幕高度和宽度而不是动态。此代码在屏幕低于或等于 1920x1080 像素的设备上流畅运行。

当屏幕尺寸大于该尺寸时会导致问题,因为屏幕比率X和屏幕比率Y<1,在>Flight.java:32中通过投射变为o,这导致了异常

宽度和高度必须> 0

要使用动态屏幕尺寸,您可以使用以下内容:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);

分别使用 size.x 和 size.y 而不是 1920f 和 1080f。谢谢

最新更新