2

免責事項: 私は 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) {}
             }
       }
}

さらにコードを表示する必要がある場合は、お知らせください。障害がどこにあるのかわかりません。

4

2 に答える 2

1

ビューが等しい null を GameLoopThread コンストラクターに渡していることは確かなので、次の行を呼び出すと NPE がスローされますsetRunning(true)

c = view.getHolder().lockCanvas();

GameLoopThread(view)問題をよりよく理解するために、への呼び出しを含む他のコードを投稿する必要があります。

幸運を

于 2013-06-09T02:31:28.517 に答える
0

Grass.javaファイルの 24 行目にがあるNullPointerExceptionので、( の代わりに) ブレークポイントとDebugモードを使用しRunて、その行の値を簡単に確認し、どの変数が null であるかを確認し、その行の前に null チェッカーを配置するか、例外をキャッチします。

1.

if(canvas != null) {

...

}

2.

try {

...

} catch (NullPointerException e) {

....
}
于 2013-06-09T02:28:41.550 に答える