免責事項: 私は 2 日前に初めて Android (電話) のプログラミングを始めたので、それほど経験がありません。私は C++ はかなり得意ですが、Java には数回しか触れていません。
問題: エミュレーターでゲームを実行すると、アプリは期待どおりに動作します。ただし、ホーム ボタンを押すと、通常、LogCat に赤い線が表示され、エミュレーターには「残念ながら [アプリ名] が停止しました」というメッセージが表示されます。浮き出る。これが発生しない場合は、アプリを再度開こうとすると発生します。
問題を見つけるのに役立つ情報: このチュートリアルから始めました: http://www.edu4java.com/androidgame.html onDraw 関数を使用しようとすると、「@SuppressLint(」を追加する必要があります。 「onDraw」を使用する関数については、WrongCall")" を使用してください。チュートリアルにはそれについて何も書かれていないので、少し混乱しています。
LogCat:
06-09 01:51:43.161: E/AndroidRuntime(23830): FATAL EXCEPTION: Thread-1173
06-09 01:51:43.161: E/AndroidRuntime(23830): java.lang.NullPointerException
06-09 01:51:43.161: E/AndroidRuntime(23830): at com.example.braincollect.Background.onDraw(Background.java:24)
06-09 01:51:43.161: E/AndroidRuntime(23830): at com.example.braincollect.GameView.onDraw(GameView.java:132)
06-09 01:51:43.161: E/AndroidRuntime(23830): at com.example.braincollect.GameLoopThread.run(GameLoopThread.java:37)
Background.java:24 のコード:
canvas.drawBitmap(bmp, 0, 0, null);
GameView.java:117 のコード
introBackground.onDraw(canvas);
GameLoopThread.java:37 のコード:
view.getHolder().unlockCanvasAndPost(c);
私のプロジェクトには7つのJavaクラスがあります:MainActivity(アクティビティ)、GameView(ビュー)、GameLoopThread(ゲームループの処理)、Background(画像)、Brain(画像)、Zombie(画像)、Timer(いくつかの数値処理)
MainActivity.java:
package com.example.braincollect;
import android.media.AudioManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.view.KeyEvent;
import android.view.Window;
public class MainActivity extends Activity {
private AudioManager am;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new GameView(this));
am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
return true;
case KeyEvent.KEYCODE_MENU:
return true;
case KeyEvent.KEYCODE_VOLUME_UP:
am.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
am.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
return true;
default:
return false;
}
}
}
GameView.java:
package com.example.braincollect;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.media.MediaPlayer;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GameView extends SurfaceView {
private Bitmap bmp;
private Bitmap bmp2;
private Bitmap bmp3;
private Bitmap bmp4;
private SurfaceHolder holder;
private GameLoopThread gameLoopThread;
private Timer timer;
public Background introBackground;
public Background background;
private Zombie zombie;
private Brain brain;
private int score = 0;
MediaPlayer mTheme;
MediaPlayer mGameover;
MediaPlayer mBrain;
MediaPlayer mCollect;
Context myContext;
int pauseTimer;
boolean intro = true;
public GameView(Context context) {
super(context);
myContext = context;
gameLoopThread = new GameLoopThread(this);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
gameLoopThread.setRunning(false);
mTheme.stop();
while (gameLoopThread != null) {
try {
gameLoopThread.join();
gameLoopThread = null;
} catch (InterruptedException e) {
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
});
timer = new Timer(context);
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.zombie);
zombie = new Zombie(this, bmp);
bmp2 = BitmapFactory.decodeResource(getResources(), R.drawable.brain);
brain = new Brain(this, bmp2);
bmp3 = BitmapFactory.decodeResource(getResources(), R.drawable.background);
background = new Background(this, bmp3);
bmp4 = BitmapFactory.decodeResource(getResources(), R.drawable.intro);
introBackground = new Background(this, bmp4);
// Music
mTheme = MediaPlayer.create(context, R.raw.theme);
mTheme.setLooping(true);
mTheme.setVolume(0.99f, 0.99f);
mBrain = MediaPlayer.create(context, R.raw.brain);
mBrain.setVolume(0.9f, 0.9f);
mCollect = MediaPlayer.create(context, R.raw.getbrain);
mCollect.setVolume(0.2f, 0.2f);
mGameover = MediaPlayer.create(context, R.raw.gameover);
mGameover.setVolume(0.2f, 0.2f);
pauseTimer = 0;
}
@SuppressLint({ "WrongCall", "DrawAllocation" })
@Override
protected void onDraw(Canvas canvas) {
if(intro == true) {
introBackground.onDraw(canvas);
Paint paint;
paint = new Paint();
paint.setARGB(200, 255, 0, 0);
paint.setTextSize(30);
if(pauseTimer >= 20) {
canvas.drawText("Click to play!", 100, getHeight() - 200, paint);
}
pauseTimer += 1;
}
else if(gameLoopThread.pause == false) {
background.onDraw(canvas);
brain.onDraw(canvas);
zombie.onDraw(canvas);
timer.onDraw(canvas);
if(zombie.isWalking) {
timer.update();
}
Paint paint;
paint = new Paint();
paint.setARGB(200, 255, 0, 0);
paint.setTextSize(25);
canvas.drawText(Integer.toString(score), 10, 30, paint);
if(zombie.isCollition(brain.x, brain.y, brain.width, brain.height)) {
brain.changePos();
if(zombie.isWalking) {
score += 1;
mBrain.start();
}
timer.reset();
}
if(timer.width <= 0) {
mGameover.start();
pauseTimer = 0;
gameLoopThread.pause = true;
mTheme.setVolume(0.3f, 0.3f);
}
} else {
background.onDraw(canvas);
Paint paint;
paint = new Paint();
paint.setARGB(200, 255, 0, 0);
paint.setTextSize(30);
canvas.drawText("Your Score: " + Integer.toString(score), 100, (getHeight() / 2) - 40, paint);
if(pauseTimer >= 20) {
canvas.drawText("Click to play again!", 100, getHeight() / 2, paint);
}
pauseTimer += 1;
}
}
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
zombie.changeDir();
if(intro == true && pauseTimer >= 20) {
intro = false;
mTheme.start();
mCollect.start();
pauseTimer = 0;
gameLoopThread.pause = false;
mTheme.setVolume(0.99f, 0.99f);
mTheme.start();
timer.width = timer.widthMax;
score = 0;
zombie.x = zombie.xStart;
zombie.y = zombie.yStart;
zombie.isWalking = false;
zombie.xSpeed = 1;
zombie.ySpeed = 0;
zombie.currentFrame = 0;
brain.changePos();
}
if(gameLoopThread.pause == true && pauseTimer >= 20) {
pauseTimer = 0;
gameLoopThread.pause = false;
mTheme.setVolume(0.99f, 0.99f);
mTheme.start();
mCollect.start();
timer.width = timer.widthMax;
score = 0;
zombie.x = zombie.xStart;
zombie.y = zombie.yStart;
zombie.isWalking = false;
zombie.xSpeed = 1;
zombie.ySpeed = 0;
zombie.currentFrame = 0;
brain.changePos();
}
}
return super.onTouchEvent(event);
}
}
(「bmp」という名前は一時的なものであり、すべてのサウンドが MediaPlayer オブジェクトになるわけではありません)
GameLoopThread.java:
package com.example.appname;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
public class GameLoopThread extends Thread {
static final long FPS = 10;
private GameView view;
public boolean running = false;
public boolean pause = false;
public GameLoopThread(GameView view) {
this.view = view;
}
public void setRunning(boolean run) {
running = run;
}
@SuppressLint("WrongCall") @Override
public void run() {
long ticksPS = 1000 / FPS;
long startTime;
long sleepTime;
while (running) {
Canvas c = null;
startTime = System.currentTimeMillis();
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.onDraw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
try {
if (sleepTime > 0)
sleep(sleepTime);
else
sleep(10);
} catch (Exception e) {}
}
}
}
さらにコードを表示する必要がある場合は、お知らせください。障害がどこにあるのかわかりません。