Я начинаю изучать анимацию на Java для Android, и на всю жизнь я не могу понять, почему это вызывает исключение нулевого указателя Может кто-нибудь помочь?
Программа проста. запускается, после нажатия кнопки «startGame» пользователю предлагается выбрать аватар. аватар затем передает тип графики, которая будет использоваться в игре. почему выбрасывает ноль?
я должен передать переменную аватара через намерение? если так, то почему
public class MainActivity extends AppCompatActivity {
public int avatar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClickStartGame(View view) {
choosePlayer();
}
private void startGame() {
Intent i = new Intent(MainActivity.this, GameActivity.class);
startActivity(i);
finish();
}
private void choosePlayer() {
AlertDialog choose =
new AlertDialog.Builder(this).create();
choose.setTitle("Choose Your Avatar...");
choose.setButton(AlertDialog.BUTTON_POSITIVE,
"Iggy",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
avatar = R.drawable.ship;
dialog.dismiss();
startGame();
}
});
choose.setButton(AlertDialog.BUTTON_NEGATIVE,
"DeuCe",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
avatar = R.drawable.impala_ship;
dialog.dismiss();
startGame();
}
});
choose.show();
}
public int getAvatar() {return avatar;}
}
//then...
public class GameActivity extends Activity {
private TDView gameView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gameView = new TDView(this);
setContentView(gameView);
}
@Override
protected void onPause() {
super.onPause();
gameView.pause();
}
@Override
protected void onResume(){
super.onResume();
gameView.resume();
}
}
//then....
public class TDView extends SurfaceView implements Runnable{
volatile boolean playing;
Thread gameThread = null;
private PlayerShip player;
private Paint paint;
private Canvas canvas;
private SurfaceHolder ourHolder;
public TDView(Context context) {
super(context);
ourHolder = getHolder();
paint = new Paint();
player = new PlayerShip(context);
}
@Override
public void run() {
while (playing) {
update();
draw();
control();
}
}
private void update(){ player.update();}
private void draw() {
if (ourHolder.getSurface().isValid()){
canvas = ourHolder.lockCanvas();
canvas.drawColor(Color.argb(255,0,0,0));
canvas.drawBitmap(player.getBitmap(), getX(), getY(), paint);
ourHolder.unlockCanvasAndPost(canvas);
}
}
private void control() {}
public void pause(){
playing = false;
try{
gameThread.join();
} catch (InterruptedException ie){
ie.printStackTrace();
}
}
public void resume(){
playing = true;
gameThread = new Thread(this);
gameThread.start();
}
//then finally....
public class PlayerShip {
private Bitmap bitmap;
private int x, y;
private int speed = 0;
MainActivity shipType;
public PlayerShip(Context context) {
x = 50;
y = 50;
speed = 1;
setBitmap(context);
}
public void update() { x++; }
public int getX() { return x; }
public int getY() { return y; }
public int speed() { return speed; }
public Bitmap getBitmap() { return bitmap; }
public void setBitmap(Context context) {
shipType = new MainActivity();
bitmap = BitmapFactory.decodeResource(context.getResources(),
shipType.getAvatar());
}
}
stackTrace...
05-09 10:18:02.502 31920-429/com.ff.deuceinspace E/AndroidRuntime: FATAL EXCEPTION: Thread-4758
Process: com.ff.deuceinspace, PID: 31920
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.isRecycled()' on a null object reference
at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1269)
at android.graphics.Canvas.drawBitmap(Canvas.java:1325)
at com.ff.deuceinspace.TDView.draw(TDView.java:43)
at com.ff.deuceinspace.TDView.run(TDView.java:31)
at java.lang.Thread.run(Thread.java:818)
//dont worry about the import statements