2013-06-09 4 views
2

Отказ от ответственности: Я начал программирование на Android (телефон) в первый раз 2 дня назад, так что я не так пережил. Я довольно хорош с C++, но я только пару раз коснулся Java.Сбой при работе с Android при выходе/секунде

Проблема: Когда я запускаю свою игру в своем эмуляторе, приложение работает так, как ожидалось. Однако, когда я нажимаю кнопку «Домой», я обычно получаю красные строки в моем LogCat, а в эмуляторе сообщение «К сожалению, имя приложения» остановлено ». всплывает. Если этого не произойдет, это произойдет, когда я снова попытаюсь открыть приложение.

Некоторая информация, которая может быть помощь, чтобы найти проблему: Я начал с этого урока: http://www.edu4java.com/androidgame.html При попытке использовать функцию OnDraw, я должен добавить «@SuppressLint (» WrongCall «)» abow функция, использующая «onDraw». В учебнике ничего не говорится об этом, поэтому я немного смущен.

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 (handeling игровой цикл), фона (изображение), мозга (изображение), Зомби (изображение) , таймер (только некоторое число handeling)

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); 
    } 
} 

(названия «БМЗ» являются лишь временными, и все звуки не будут объектом 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) {} 
      } 
     } 
} 

Если вам потребуется, чтобы увидеть больше кода, просто дай мне знать. Я понятия не имею, где вина.

+0

Ваше использование таймера в Gameview неверно. Таймер не имеет конструктора, который принимает контекст. http://developer.android.com/reference/java/util/Timer.html. проверьте таймер api в ссылке. Что такое "timer.width"? – Raghunandan

+0

Спасибо за ответ. «Таймер» - это класс, который я создал. Теперь я замечаю, что выбор имени был большой ошибкой. Этот класс функционирует как коробка, которая с течением времени сокращается. Когда бар находится в 0, игра закончена. «Timer» был глупым именем x) – CandyCreep

ответ

0

Это так просто, в 24-й строке файла Grass.java, у вас есть NullPointerException, поэтому использование контрольных точек и Debug режим (вместо Run) легко проверить значения этой строки и посмотреть, какие из переменных может быть пустым и либо поставить нулевую проверку перед тем, что линии или поймать исключение:

1.

if(canvas != null) { 

... 

} 

2.

try { 

... 

} catch (NullPointerException e) { 

.... 
} 
1

Я уверен, что точка зрения проходит равное NULL для GameLoopThread конструктора, так что эта линия будет бросать NPE, когда вы звоните setRunning(true):

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

Вы должны размещать другие фрагменты кода с вызовами до GameLoopThread(view), чтобы лучше разобраться с проблемой.

Удачи

+0

Я добавил еще код (MainActivity и GameView). Может быть, это поможет. – CandyCreep

Смежные вопросы