I recently hit a frustrating roadblock while working on my Android game project in Android Studio. Everything was working fine until I added a new activity called MatheGame
. When I tried to start the game, the app crashed immediately.
If you’ve run into a similar situation where your app crashes right after launching a game screen, chances are the root cause is hidden somewhere in the onCreate()
method. Let me walk you through what happened in my case, how I debugged it, and how I even turned it into an opportunity to make the game better.
The Problem
Here’s the full error message I got:
: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setX(float)' on a null object reference
at com.eitisoft.mathetrainer.MatheGame.onCreate(MatheGame.java:85)
Ouch. It pointed directly to this line:
orange.setX(-80);
At first, I was confused I did define the orange
ImageView in my layout. So why was it null
Let’s Analyze the Code
The orange
ImageView was initialized like this:
orange = (ImageView)findViewById(R.id.orange);
And just before the app crashed, this line was trying to use it:
orange.setX(-80); // Line 85
But here’s the twist: the layout I was loading in onCreate()
was not the one that actually contains the orange
ImageView.
setContentView(R.layout.activity_main); // Wrong layout!
I had created a custom layout named activity_mathe_game.xml
for this activity, but forgot to reference it properly in onCreate()
.
The Simple Fix
I replaced the incorrect line with this one:
setContentView(R.layout.activity_mathe_game); // Correct layout!
Once I did that, everything initialized correctly and the crash was gone. findViewById()
was finally able to find orange
and the rest of my game UI elements.
Improving the Game
Now that the crash was fixed, I didn’t stop there. I decided to make the android game more robust and fun by adding the following features:
Game Over Logic
I added a lives system and stopped the game if the player hit the screen boundaries too many times:
int lives = 3;
public void changePos() {
hitCheck();
if (action_flg) {
boxY -= boxSpeed;
} else {
boxY += boxSpeed;
}
if (boxY < 0 || boxY > frameHeight - boxSize) {
lives--;
if (lives <= 0) {
gameOver();
return;
}
}
box.setY(boxY);
scoreLabel.setText("Score : " + score + " | Lives: " + lives);
}
private void gameOver() {
timer.cancel();
startLabel.setText("Game Over!");
startLabel.setVisibility(View.VISIBLE);
}
Sound Effects
I added sound effects for scoring and game over events using MediaPlayer
:
hitSound, gameOverSound;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
hitSound = MediaPlayer.create(this, R.raw.hit);
gameOverSound = MediaPlayer.create(this, R.raw.game_over);
}
public void hitCheck() {
...
if (collisionDetected) {
hitSound.start();
}
}
private void gameOver() {
gameOverSound.start();
...
}
Make sure to add your hit.mp3
and game_over.mp3
files in the res/raw/
folder.
High Score Saving
Using SharedPreferences
, I stored and retrieved the high score across game sessions:
SharedPreferences prefs;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
prefs = getSharedPreferences("GamePrefs", MODE_PRIVATE);
}
private void gameOver() {
int highScore = prefs.getInt("HighScore", 0);
if (score > highScore) {
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("HighScore", score);
editor.apply();
}
}
I also displayed it along with the current score:
highScore = prefs.getInt("HighScore", 0);
scoreLabel.setText("Score : " + score + " | High Score: " + highScore);
More Enemies
I cloned the orange
logic and created new enemies for added difficulty:
ImageView redApple;
int redAppleX, redAppleY, redAppleSpeed;
redApple = (ImageView)findViewById(R.id.redApple);
redAppleSpeed = Math.round(screenWidth / 50);
And added this in the layout file:
<ImageView
android:id="@+id/redApple"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/red_apple"/>
Now the player has to dodge or collect multiple objects on the screen more fun
Final Thought
This experience reminded me of two valuable lessons always verify you’re loading the correct layout file in each activity, and never underestimate the learning potential of a crash. What started as a frustrating error became a chance to improve my game by adding new features like lives, sound effects, high scores, and more obstacles. Fixing bugs doesn’t just solve problems it often opens the door to make your app more polished and fun.