Helicopter Fighter Game in Android Studio

In this blog you will learn how to code​​ HELI FIGHTER​​ game in Android studio:

Download Android Studio from the link given blow according to your operating system Windows, Mac, Linux, Chrome OS etc.

Link:​​ https://developer.android.com/studio

More downloads are available here.​​ 

Link:​​ https://developer.android.com/studio/archive

This is a simple game developed using Android Studio in which the helicopter needs to be saved from the incoming missiles. Below are some screenshots from the game:

y+4wQzwJ2viSgAAAABJRU5ErkJggg== - Helicopter Fighter Game in Android Studio

wQ2SQAAAABJRU5ErkJggg== - Helicopter Fighter Game in Android Studio

Source codes are given below:

MainThread.java code:


import android.graphics.Canvas;
import android.view.SurfaceHolder;

public class MainThread extends Thread
{
private int FPS = 30;
private double averageFPS;
private SurfaceHolder surfaceHolder;
private GamePanel gamePanel;
private boolean running;
public static Canvas canvas;

public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel)
{
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
@Override
public void run()
{
long startTime;
long timeMillis;
long waitTime;
long totalTime = 0;
int frameCount =0;
long targetTime = 1000/FPS;

while(running) {
startTime = System.nanoTime();
canvas = null;

//try locking the canvas for pixel editing
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
this.gamePanel.update();
this.gamePanel.draw(canvas);
}
} catch (Exception e) {
}
finally{
if(canvas!=null)
{
try {
surfaceHolder.unlockCanvasAndPost(canvas);
}
catch(Exception e){e.printStackTrace();}
}
}


timeMillis = (System.nanoTime() - startTime) / 1000000;
waitTime = targetTime-timeMillis;

try{
this.sleep(waitTime);
}catch(Exception e){}

totalTime += System.nanoTime()-startTime;
frameCount++;
if(frameCount == FPS)
{
averageFPS = 1000/((totalTime/frameCount)/1000000);
frameCount =0;
totalTime = 0;
System.out.println(averageFPS);
}
}
}
public void setRunning(boolean b)
{
running=b;
}
}

GamePanel.java code:

import android.content.Context;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;


public class GamePanel extends SurfaceView implements SurfaceHolder.Callback
{
private MainThread thread;
public GamePanel(Context context)
{
super(context);


//add the callback to the surfaceholder to intercept events
getHolder().addCallback(this);

thread = new MainThread(getHolder(), this);

//make gamePanel focusable so it can handle events
setFocusable(true);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){}

@Override
public void surfaceDestroyed(SurfaceHolder holder){
boolean retry = true;
while(retry)
{
try{thread.setRunning(false);
thread.join();

}catch(InterruptedException e){e.printStackTrace();}
retry = false;
}

}

@Override
public void surfaceCreated(SurfaceHolder holder){

//we can safely start the game loop
thread.setRunning(true);
thread.start();

}
@Override
public boolean onTouchEvent(MotionEvent event)
{
return super.onTouchEvent(event);
}
public void update()
{

}
}

Game.java code:


import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;


public class Game extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

//turn title off
requestWindowFeature(Window.FEATURE_NO_TITLE);

//set to full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

setContentView(new GamePanel(this));
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_game, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}
}

Background.java code:

import android.graphics.Bitmap;
import android.graphics.Canvas;

public class Background {

private Bitmap image;
private int x, y, dx;

public Background(Bitmap res)
{
image = res;
}
public void update()
{
x+=dx;
if(x<-GamePanel.WIDTH){
x=0;
}
}
public void draw(Canvas canvas)
{
canvas.drawBitmap(image, x, y,null);
if(x<0)
{
canvas.drawBitmap(image, x+GamePanel.WIDTH, y, null);
}
}
public void setVector(int dx)
{
this.dx = dx;
}
}

GamePanel.java code:

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;


public class GamePanel extends SurfaceView implements SurfaceHolder.Callback
{
public static final int WIDTH = 856;
public static final int HEIGHT = 480;
private MainThread thread;
private Background bg;

public GamePanel(Context context)
{
super(context);


//add the callback to the surfaceholder to intercept events
getHolder().addCallback(this);

thread = new MainThread(getHolder(), this);

//make gamePanel focusable so it can handle events
setFocusable(true);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){}

@Override
public void surfaceDestroyed(SurfaceHolder holder){
boolean retry = true;
while(retry)
{
try{thread.setRunning(false);
thread.join();

}catch(InterruptedException e){e.printStackTrace();}
retry = false;
}

}

@Override
public void surfaceCreated(SurfaceHolder holder){

bg = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.grassbg1));
bg.setVector(-5);
//we can safely start the game loop
thread.setRunning(true);
thread.start();

}
@Override
public boolean onTouchEvent(MotionEvent event)
{
return super.onTouchEvent(event);
}

public void update()
{

bg.update();
}
@Override
public void draw(Canvas canvas)
{
final float scaleFactorX = getWidth()/WIDTH;
final float scaleFactorY = getHeight()/HEIGHT;
if(canvas!=null) {
final int savedState = canvas.save();
canvas.scale(scaleFactorX, scaleFactorY);
bg.draw(canvas);
canvas.restoreToCount(savedState);
}
}

}

GamePanel.java code:

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;


public class GamePanel extends SurfaceView implements SurfaceHolder.Callback
{
public static final int WIDTH = 856;
public static final int HEIGHT = 480;
public static final int MOVESPEED = -5;
private MainThread thread;
private Background bg;
private Player player;

public GamePanel(Context context)
{
super(context);


//add the callback to the surfaceholder to intercept events
getHolder().addCallback(this);

thread = new MainThread(getHolder(), this);

//make gamePanel focusable so it can handle events
setFocusable(true);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){}

@Override
public void surfaceDestroyed(SurfaceHolder holder){
boolean retry = true;
while(retry)
{
try{thread.setRunning(false);
thread.join();

}catch(InterruptedException e){e.printStackTrace();}
retry = false;
}

}

@Override
public void surfaceCreated(SurfaceHolder holder){

bg = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.grassbg1));
player = new Player(BitmapFactory.decodeResource(getResources(), R.drawable.helicopter), 65, 25, 3);
//we can safely start the game loop
thread.setRunning(true);
thread.start();

}
@Override
public boolean onTouchEvent(MotionEvent event)
{
if(event.getAction()==MotionEvent.ACTION_DOWN){
if(!player.getPlaying())
{
player.setPlaying(true);
}
else
{
player.setUp(true);
}
return true;
}
if(event.getAction()==MotionEvent.ACTION_UP)
{
player.setUp(false);
return true;
}

return super.onTouchEvent(event);
}

public void update()
{
if(player.getPlaying()) {
bg.update();
player.update();
}
}
@Override
public void draw(Canvas canvas)
{
final float scaleFactorX = getWidth()/(WIDTH*1.f);
final float scaleFactorY = getHeight()/(HEIGHT*1.f);

if(canvas!=null) {
final int savedState = canvas.save();
canvas.scale(scaleFactorX, scaleFactorY);
bg.draw(canvas);
player.draw(canvas);
canvas.restoreToCount(savedState);
}
}


}

GameObject.java code:

import android.graphics.Rect;

public abstract class GameObject {
protected int x;
protected int y;
protected int dy;
protected int dx;
protected int width;
protected int height;

public void setX(int x)
{
this.x = x;
}
public void setY(int y)
{
this.y = y;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public int getHeight()
{
return height;
}
public int getWidth()
{
return width;
}
public Rect getRectangle()
{
return new Rect(x, y, x+width, y+height);
}

}

Player.java code:


import android.graphics.Bitmap;
import android.graphics.Canvas;


public class Player extends GameObject{
private Bitmap spritesheet;
private int score;
private double dya;
private boolean up;
private boolean playing;
private Animation animation = new Animation();
private long startTime;

public Player(Bitmap res, int w, int h, int numFrames) {

x = 100;
y = GamePanel.HEIGHT / 2;
dy = 0;
score = 0;
height = h;
width = w;

Bitmap[] image = new Bitmap[numFrames];
spritesheet = res;

for (int i = 0; i < image.length; i++)
{
image[i] = Bitmap.createBitmap(spritesheet, i*width, 0, width, height);
}

animation.setFrames(image);
animation.setDelay(10);
startTime = System.nanoTime();

}

public void setUp(boolean b){up = b;}

public void update()
{
long elapsed = (System.nanoTime()-startTime)/1000000;
if(elapsed>100)
{
score++;
startTime = System.nanoTime();
}
animation.update();

if(up){
dy = (int)(dya-=1.1);

}
else{
dy = (int)(dya+=1.1);
}

if(dy>14)dy = 14;
if(dy<-14)dy = -14;

y += dy*2;
dy = 0;
}

public void draw(Canvas canvas)
{
canvas.drawBitmap(animation.getImage(),x,y,null);
}
public int getScore(){return score;}
public boolean getPlaying(){return playing;}
public void setPlaying(boolean b){playing = b;}
public void resetDYA(){dya = 0;}
public void resetScore(){score = 0;}
}

Animation.java code:


import android.graphics.Bitmap;

public class Animation {
private Bitmap[] frames;
private int currentFrame;
private long startTime;
private long delay;
private boolean playedOnce;

public void setFrames(Bitmap[] frames)
{
this.frames = frames;
currentFrame = 0;
startTime = System.nanoTime();
}
public void setDelay(long d){delay = d;}
public void setFrame(int i){currentFrame= i;}

public void update()
{
long elapsed = (System.nanoTime()-startTime)/1000000;

if(elapsed>delay)
{
currentFrame++;
startTime = System.nanoTime();
}
if(currentFrame == frames.length){
currentFrame = 0;
playedOnce = true;
}
}
public Bitmap getImage(){
return frames[currentFrame];
}
public int getFrame(){return currentFrame;}
public boolean playedOnce(){return playedOnce;}
}

Smokepuff.java code:

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

public class Smokepuff extends GameObject{
public int r;
public Smokepuff(int x, int y)
{
r = 5;
super.x = x;
super.y = y;
}
public void update()
{
x-=10;
}
public void draw(Canvas canvas)
{
Paint paint = new Paint();
paint.setColor(Color.GRAY);
paint.setStyle(Paint.Style.FILL);

canvas.drawCircle(x-r, y-r, r, paint);
canvas.drawCircle(x-r+2, y-r-2,r,paint);
canvas.drawCircle(x-r+4, y-r+1, r, paint);
}

}

GamePanel.java code:

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.util.ArrayList;


public class GamePanel extends SurfaceView implements SurfaceHolder.Callback
{
public static final int WIDTH = 856;
public static final int HEIGHT = 480;
public static final int MOVESPEED = -5;
private long smokeStartTime;
private MainThread thread;
private Background bg;
private Player player;
private ArrayList<Smokepuff> smoke;


public GamePanel(Context context)
{
super(context);


//add the callback to the surfaceholder to intercept events
getHolder().addCallback(this);

thread = new MainThread(getHolder(), this);

//make gamePanel focusable so it can handle events
setFocusable(true);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){}

@Override
public void surfaceDestroyed(SurfaceHolder holder){
boolean retry = true;
int counter = 0;
while(retry && counter<1000)
{
counter++;
try{thread.setRunning(false);
thread.join();
retry = false;

}catch(InterruptedException e){e.printStackTrace();}

}

}

@Override
public void surfaceCreated(SurfaceHolder holder){

bg = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.grassbg1));
player = new Player(BitmapFactory.decodeResource(getResources(), R.drawable.helicopter), 65, 25, 3);
smoke = new ArrayList<Smokepuff>();

smokeStartTime= System.nanoTime();

//we can safely start the game loop
thread.setRunning(true);
thread.start();

}
@Override
public boolean onTouchEvent(MotionEvent event)
{
if(event.getAction()==MotionEvent.ACTION_DOWN){
if(!player.getPlaying())
{
player.setPlaying(true);
}
else
{
player.setUp(true);
}
return true;
}
if(event.getAction()==MotionEvent.ACTION_UP)
{
player.setUp(false);
return true;
}

return super.onTouchEvent(event);
}

public void update()
{
if(player.getPlaying()) {

bg.update();
player.update();

long elapsed = (System.nanoTime() - smokeStartTime)/1000000;
if(elapsed > 120){
smoke.add(new Smokepuff(player.getX(), player.getY()+10));
smokeStartTime = System.nanoTime();
}

for(int i = 0; i<smoke.size();i++)
{
smoke.get(i).update();
if(smoke.get(i).getX()<-10)
{
smoke.remove(i);
}
}
}
}
@Override
public void draw(Canvas canvas)
{
final float scaleFactorX = getWidth()/(WIDTH*1.f);
final float scaleFactorY = getHeight()/(HEIGHT*1.f);

if(canvas!=null) {
final int savedState = canvas.save();

canvas.scale(scaleFactorX, scaleFactorY);
bg.draw(canvas);
player.draw(canvas);
for(Smokepuff sp: smoke)
{
sp.draw(canvas);
}


canvas.restoreToCount(savedState);
}
}


}

Player.java code:

import android.graphics.Bitmap;
import android.graphics.Canvas;


public class Player extends GameObject{
private Bitmap spritesheet;
private int score;

private boolean up;
private boolean playing;
private Animation animation = new Animation();
private long startTime;

public Player(Bitmap res, int w, int h, int numFrames) {

x = 100;
y = GamePanel.HEIGHT / 2;
dy = 0;
score = 0;
height = h;
width = w;

Bitmap[] image = new Bitmap[numFrames];
spritesheet = res;

for (int i = 0; i < image.length; i++)
{
image[i] = Bitmap.createBitmap(spritesheet, i*width, 0, width, height);
}

animation.setFrames(image);
animation.setDelay(10);
startTime = System.nanoTime();

}

public void setUp(boolean b){up = b;}

public void update()
{
long elapsed = (System.nanoTime()-startTime)/1000000;
if(elapsed>100)
{
score++;
startTime = System.nanoTime();
}
animation.update();

if(up){
dy -=1;

}
else{
dy +=1;
}

if(dy>14)dy = 14;
if(dy<-14)dy = -14;

y += dy*2;

}

public void draw(Canvas canvas)
{
canvas.drawBitmap(animation.getImage(),x,y,null);
}
public int getScore(){return score;}
public boolean getPlaying(){return playing;}
public void setPlaying(boolean b){playing = b;}
public void resetDY(){dy = 0;}
public void resetScore(){score = 0;}
}

Please use the above code and develop the game. If you still need more help​​ and assistance, please​​ comment down below so that we can help you. Good Luck!!