Helicopter Game

By tv3636 on May 30, 2009

This is my final project for APCS (Advanced Placement Computer Science). It's currently unfinished, we (my partner and I) still need to add a crash sequence as well as some modifications to make the game more difficult.
Anyway, you can play this by copying the code below and pasting into JCreator or downloading the .zip with an .exe file and the images used in the game here:
Helicopter Game .zip

The code is pretty messy because we've just been focusing on getting the game working, and also the class files are mashed together below because you can't submit multiple forms on Hawkee for one piece of code.

All code is by me and my partner except for the MP3 class which we found online and parts of the imagepanel and movingimage classes which were started by a classmate for the rest of us to use, The mp3 class is currently commented out because you need a .jar file to make it work even in JCreator so I figured it was unnecessary. For some reason the sounds messed up the .jar/.exe.

Enjoy :D And I know it's not as good as the flash version, but I'm proud of it so I want to show it off and there aren't too many java snippets on the site so I thought this would be cool to post.

Hopefully I can figure out how to get an applet version working soon so you don't have to download it, but I had trouble the last time I tried.
Screenshot:
Image

import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class HelicopterForm implements MouseListener
{
    public static void main (String [] args)
    {
        HelicopterForm a = new HelicopterForm();
    }

    private JFrame background;
    private Container container;
    private JButton button;
    private ImagePanel back;

    public static boolean paused;
    public static boolean crashed;
    public static boolean started;
    public static boolean playedOnce;   

    public boolean goingUp;
    private double upCount;

    public static int distance;
    public static int maxDistance;

    public final int XPOS;
    public final int NUMRECS;
    public final int RECHEIGHT;
    public final int RECWIDTH;

    private int moveIncrement;
    private int numSmoke;

    private ArrayList<MovingImage> toprecs;
    private ArrayList<MovingImage> bottomrecs;
    private ArrayList<MovingImage> middlerecs;
    private ArrayList<MovingImage> recs;
    private ArrayList<MovingImage> smoke;
    private MovingImage helicopter;

    //private MP3 move = new MP3("HelicopterSound.mp3");

    /*Graphics information:
     *Background is 812 x 537
     *Floor is 74 and Ceiling is 72 pixels high
     *28 rectangles across that are 29 x 73
     */

    public HelicopterForm()
    {
        NUMRECS = 28;
        RECHEIGHT = 73;
        RECWIDTH = 29;
        XPOS = 200;
        playedOnce = false;
        maxDistance = 0;

        load(new File("Best.txt"));

        initiate();
    }

    public void load(File file)
    {
        try
        {
            Scanner reader = new Scanner(file);
            while(reader.hasNext())
            {
                int value = reader.nextInt();
                if(value > maxDistance)
                    maxDistance = value;
            }
        }
        catch(IOException i )
        {
            System.out.println("Error. "+i);
        }
    }

    public void save()
    {
        FileWriter out;
        try
        {
            out = new FileWriter("Best.txt");
            out.write("" + maxDistance);
            out.close();
        }
        catch(IOException i)
        {
            System.out.println("Error: "+i.getMessage());
        }
    }

    public void initiate()
    {
        if(!playedOnce)
        {
            background = new JFrame("Helicopter Game"); 
            background.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //closes the program when the window is closed
            background.setResizable(false); //don't allow the user to resize the window
            background.setSize(new Dimension(818,568));
            background.setVisible(true);

            back = new ImagePanel("back.JPG");
            background.add(back);

            back.addMouseListener(this);
        }
        playedOnce = true;
        goingUp = false;
        paused = false;
        crashed = false;
        started = false;

        distance = 0;
        upCount = 0;

        moveIncrement = 2;
        numSmoke = 15;

        recs = new ArrayList<MovingImage>();
        toprecs = new ArrayList<MovingImage>();
        middlerecs = new ArrayList<MovingImage>();
        bottomrecs = new ArrayList<MovingImage>();
        smoke = new ArrayList<MovingImage>();

        helicopter = new MovingImage("helicopter.GIF",XPOS,270);

        for(int x = 0; x < NUMRECS; x++)
            toprecs.add(new MovingImage("rec2.JPG",RECWIDTH*x,30));
        for(int x = 0; x < NUMRECS; x++)
            bottomrecs.add(new MovingImage("rec2.JPG",RECWIDTH*x,450));

        middlerecs.add(new MovingImage("rec2.JPG",1392,randomMidHeight()));
        middlerecs.add(new MovingImage("rec2.JPG",1972,randomMidHeight()));

        drawRectangles();
    }

    public void drawRectangles()
    {
        long last = System.currentTimeMillis();
        long lastCopter = System.currentTimeMillis();
        long lastSmoke = System.currentTimeMillis();
        long lastSound = System.currentTimeMillis();
        int firstUpdates = 0;
        double lastDistance = (double)System.currentTimeMillis();
        while(true)
        {
            if(!paused && !crashed && started && (double)System.currentTimeMillis() - (double)(2900/40) > lastDistance)
            {   
                lastDistance = System.currentTimeMillis();
                distance++;
            }   

        /*  if(!paused && !crashed && started && System.currentTimeMillis() - 1300 > lastSound)
            {
                lastSound = System.currentTimeMillis();
                move.play();
            }
        */

            if(!paused && !crashed && started && System.currentTimeMillis() - 10 > lastCopter)
            {
                lastCopter = System.currentTimeMillis();
                updateCopter();
                updateMiddle();
            }
            if(!paused && !crashed && started && System.currentTimeMillis() - 100 > last)
            {
                last = System.currentTimeMillis();
                updateRecs();
            }
            if(!paused && !crashed && started && System.currentTimeMillis() - 75 > lastSmoke)
            {
                lastSmoke = System.currentTimeMillis();
                if (firstUpdates < numSmoke)
                {
                    firstUpdates++;
                    smoke.add(new MovingImage("smoke.GIF",187,helicopter.getY()));
                    for(int x = 0; x < firstUpdates; x++)
                        smoke.set(x,new MovingImage("smoke.GIF",smoke.get(x).getX() - 12, smoke.get(x).getY()));
                }
                else
                {
                    for(int x = 0; x < numSmoke - 1; x++)
                        smoke.get(x).setY(smoke.get(x+1).getY());
                    smoke.set(numSmoke - 1,new MovingImage("smoke.GIF",187,helicopter.getY()));
                }
                    }
                    back.updateImages(toprecs,middlerecs,bottomrecs,helicopter,smoke);
                }
    }

    public void updateRecs()
    {
        for(int x = 0; x < (NUMRECS - 1); x++) //move all but the last rectangle 1 spot to the left
        {
            toprecs.set(x,new MovingImage("rec2.JPG",RECWIDTH*x,toprecs.get(x+1).getY()));
            bottomrecs.set(x,new MovingImage("rec2.JPG",RECWIDTH*x,bottomrecs.get(x+1).getY()));
        }
        lastRec();
    }

    public void lastRec()
    {
        if(distance % 400 == 0)
            moveIncrement++;
        if(toprecs.get(26).getY() < 2) //if too high, move down
            moveDown();
        else if (bottomrecs.get(26).getY() > 463) //else if too low, move up
            moveUp();
        else //else move randomly
        {
            if((int)(Math.random() * 60) == 50)
                randomDrop();
            else
            {
                if((int)(Math.random() * 2) == 1)
                    moveUp();
                else
                    moveDown();
            }
        }
    }

    public void randomDrop()
    {
        toprecs.get(26).setY(toprecs.get(26).getY() + (463 - bottomrecs.get(26).getY()));
        bottomrecs.get(26).setY(463);
    }

    public void moveDown()
    {
        toprecs.set((NUMRECS - 1),new MovingImage("rec2.JPG",RECWIDTH*(NUMRECS - 1),toprecs.get(26).getY() + moveIncrement));
        bottomrecs.set((NUMRECS - 1),new MovingImage("rec2.JPG",RECWIDTH*(NUMRECS - 1),bottomrecs.get(26).getY() + moveIncrement));
    }

    public void moveUp()
    {
        bottomrecs.set((NUMRECS - 1),new MovingImage("rec2.JPG",RECWIDTH*(NUMRECS - 1),bottomrecs.get(26).getY() - moveIncrement));
        toprecs.set((NUMRECS - 1),new MovingImage("rec2.JPG",RECWIDTH*(NUMRECS - 1),toprecs.get(26).getY() - moveIncrement));
    }

    public int randomMidHeight()
    {
        int max = 10000;
        int min = 0;

        for(int x = 0; x < NUMRECS; x++)
        {
            if(toprecs.get(x).getY() > min)
                min = (int)toprecs.get(x).getY();
            if(bottomrecs.get(x).getY() < max)
                max = (int)bottomrecs.get(x).getY();
        }
        min += RECHEIGHT;
        max -= (RECHEIGHT + min);
        return min + (int)(Math.random() * max);
    }

    //moves the randomly generated middle rectangles
    public void updateMiddle()
    {
        if(middlerecs.get(0).getX() > -1 * RECWIDTH)
        {
            middlerecs.set(0,new MovingImage("rec2.JPG",middlerecs.get(0).getX() - (RECWIDTH/5), middlerecs.get(0).getY()));
            middlerecs.set(1,new MovingImage("rec2.JPG",middlerecs.get(1).getX() - (RECWIDTH/5), middlerecs.get(1).getY()));
        }
        else
        {
            middlerecs.set(0,new MovingImage("rec2.JPG",middlerecs.get(1).getX() - (RECWIDTH/5), middlerecs.get(1).getY()));
            middlerecs.set(1,new MovingImage("rec2.JPG",middlerecs.get(0).getX() + 580,randomMidHeight()));
        }
    }

    public boolean isHit()
    {
        for(int x = 3; x <= 7; x++)
            if(helicopter.getY() + 48 >= bottomrecs.get(x).getY())
                return true;

        for(int y = 3; y <= 7; y++)
                if(helicopter.getY() <= toprecs.get(y).getY() + RECHEIGHT)
                    return true;
        for(int z = 0; z <= 1; z++)
            if(isInMidRange(z))
                return true;
        return false;
    }

    public boolean isInMidRange(int num)
    {
        Rectangle middlecheck = new Rectangle((int)middlerecs.get(num).getX(),(int)middlerecs.get(num).getY(),RECWIDTH,RECHEIGHT);
        Rectangle coptercheck = new Rectangle((int)helicopter.getX(),(int)helicopter.getY(),106,48);
        return middlecheck.intersects(coptercheck);
    }

    public void crash()
    {
        crashed = true;
        if(distance > maxDistance) 
        {
            maxDistance = distance;
            save();
        }

        initiate();
    }

    //moves the helicopter
    public void updateCopter()
    {
        upCount += .08;
        if(goingUp)
        {
            if(upCount < 3.5)
                helicopter.setPosition(XPOS,(double)(helicopter.getY() - (.3 + upCount)));
            else
                helicopter.setPosition(XPOS,(double)(helicopter.getY() - (1.2 + upCount)));
            helicopter.setImage("upCopter.GIF");    
        }
        else
        {
            if(upCount < 1)
                helicopter.setPosition(XPOS,(double)(helicopter.getY() + upCount));
            else
                helicopter.setPosition(XPOS,(double)(helicopter.getY() + (1.2 + upCount)));
            helicopter.setImage("helicopter.GIF");
        }
        if(isHit())
            crash();
    }

    //Called when the mouse exits the game window
    public void mouseExited(MouseEvent e)
    {

        if(started)
        {
            paused = true;
            //move.close(); 
        }

    }

    //Called when the mouse enters the game window
    public void mouseEntered(MouseEvent e)
    {

    }

    //Called when the mouse is released
    public void mouseReleased(MouseEvent e)
    {
        goingUp = false;
        upCount = 0;
        if(paused)
            paused = false;
    }

    //Called when the mouse is pressed
    public void mousePressed(MouseEvent e)
    {
        if (!started)
            started = true;
        goingUp = true;
        upCount = 0;
    }

    //Called when the mouse is released
    public void mouseClicked(MouseEvent e)
    {

    }
}

class ImagePanel extends JPanel {

    private Image background;                   //The background image
    private ArrayList<MovingImage> top; //An array list of foreground images
    private ArrayList<MovingImage> bottom;
    private ArrayList<MovingImage> middle;
    private MovingImage copter;
    private ArrayList<MovingImage> smoke;

    //Constructs a new ImagePanel with the background image specified by the file path given
    public ImagePanel(String img) 
    {
        this(new ImageIcon(img).getImage());    
            //The easiest way to make images from file paths in Swing
    }

    //Constructs a new ImagePanel with the background image given
    public ImagePanel(Image img)
    {
        background = img;
        Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));    
            //Get the size of the image
        //Thoroughly make the size of the panel equal to the size of the image
        //(Various layout managers will try to mess with the size of things to fit everything)
        setPreferredSize(size);
        setMinimumSize(size);
        setMaximumSize(size);
        setSize(size);

        top = new ArrayList<MovingImage>();
        middle = new ArrayList<MovingImage>();
        bottom = new ArrayList<MovingImage>();

        smoke = new ArrayList<MovingImage>();
    }

    //This is called whenever the computer decides to repaint the window
    //It's a method in JPanel that I've overwritten to paint the background and foreground images
    public void paintComponent(Graphics g) 
    {
        //Paint the background with its upper left corner at the upper left corner of the panel
        g.drawImage(background, 0, 0, null); 
        //Paint each image in the foreground where it should go
        for(MovingImage img : top)
            g.drawImage(img.getImage(), (int)(img.getX()), (int)(img.getY()), null);
        for(MovingImage img : middle)
            g.drawImage(img.getImage(), (int)(img.getX()), (int)(img.getY()), null);
        for(MovingImage img : bottom)
            g.drawImage(img.getImage(), (int)(img.getX()), (int)(img.getY()), null);
        for(MovingImage img : smoke)
            g.drawImage(img.getImage(), (int)(img.getX()), (int)(img.getY()), null);
        if(copter != null)
            g.drawImage(copter.getImage(), (int)(copter.getX()), (int)(copter.getY()), null);
        drawStrings(g);
    }

    public void drawStrings(Graphics g)
    {
        g.setFont(new Font("Arial",Font.BOLD,20));
        g.drawString("Distance: " + HelicopterForm.distance,30,500);
        g.setFont(new Font("Arial",Font.BOLD,20));
        if (HelicopterForm.distance > HelicopterForm.maxDistance)
            g.drawString("Best: " + HelicopterForm.distance,650,500);
        else
            g.drawString("Best: " + HelicopterForm.maxDistance,650,500);
        if(HelicopterForm.paused)
        {
                g.setColor(Color.WHITE);
                g.setFont(new Font("Chiller",Font.BOLD,72));
                g.drawString("Paused",325,290);
                g.setFont(new Font("Chiller",Font.BOLD,30));
                g.drawString("Click to unpause.",320,340);
        }
    }

    //Replaces the list of foreground images with the one given, and repaints the panel
    public void updateImages(ArrayList<MovingImage> newTop,ArrayList<MovingImage> newMiddle,ArrayList<MovingImage> newBottom,MovingImage newCopter,ArrayList<MovingImage> newSmoke)
    {
        top = newTop;
        copter = newCopter;
        middle = newMiddle;
        bottom = newBottom;
        smoke = newSmoke;
        repaint();  //This repaints stuff... you don't need to know how it works
    }
}

class MovingImage
{
    private Image image;        //The picture
    private double x;           //X position
    private double y;           //Y position

    //Construct a new Moving Image with image, x position, and y position given
    public MovingImage(Image img, double xPos, double yPos)
    {
        image = img;
        x = xPos;
        y = yPos;
    }

    //Construct a new Moving Image with image (from file path), x position, and y position given
    public MovingImage(String path, double xPos, double yPos)
    {
        this(new ImageIcon(path).getImage(), xPos, yPos);   
            //easiest way to make an image from a file path in Swing
    }

    //They are set methods.  I don't feel like commenting them.
    public void setPosition(double xPos, double yPos)
    {
        x = xPos;
        y = yPos;
    }

    public void setImage(String path)
    {
        image = new ImageIcon(path).getImage();
    }

    public void setY(double newY)
    {
        y = newY;
    }

    public void setX(double newX)
    {
        x = newX;
    }

    //Get methods which I'm also not commenting
    public double getX()
    {
        return x;
    }

    public double getY()
    {
        return y;
    }

    public Image getImage()
    {
        return image;
    }
}
/*
class MP3 {
    private String filename;
    private Player player; 

    // constructor that takes the name of an MP3 file
    public MP3(String filename) {
        this.filename = filename;
    }

    public void close() { if (player != null) player.close(); }

    // play the MP3 file to the sound card
    public void play() {
        try {
            FileInputStream fis     = new FileInputStream(filename);
            BufferedInputStream bis = new BufferedInputStream(fis);
            player = new Player(bis);
        }
        catch (Exception e) {
            System.out.println("Problem playing file " + filename);
            System.out.println(e);
        }

        // run in new thread to play in background
        new Thread() {
            public void run() {
                try { player.play(); }
                catch (Exception e) { System.out.println(e); }
            }
        }.start();
    }

}
*/

Comments

Sign in to comment.
nanad   -  Nov 05, 2015

how to display "game over" in this code?

 Respond  
Hawkee   -  Feb 26, 2014

I wonder how easily this could be adapted into a Flappy Bird clone. It's pretty much all right there.

F*U*R*B*Y*  -  Feb 26, 2014

its like http://www.flappymmo.com/ or something

Hawkee  -  Feb 26, 2014

Yeah, I saw that the other day. Hilarious to watch.

Joshuaxiong1  -  Feb 26, 2014

I thought of this helicopter game also when I played flappy bird but didn't want to spend the time to find this helicopter java page on Hawkee.

Hawkee  -  Feb 26, 2014

Not very difficult. Just search "helicopter".

Sign in to comment

javastudent   -  May 01, 2013

just thought i would put this out there that i am in 10th grade basic java making the same game for y final project and it is a lot easier then you are making it i am like half way done in 2 hours and and i am doing it alone, so just because you are in ap does not mean that it has to be this hard and complicated. and BTW to the ones that copied it i hope you fail because if you want to make it anywhere in life do your own work!

Joshuaxiong1  -  May 01, 2013

Lol I hope you fail English class.

Hawkee  -  May 01, 2013

@Joshuaxiong1 That's not very nice.

Sign in to comment

Hawkee   -  Nov 04, 2012

Since you didn't write the MP3 bit its probably best just to exclude it.

 Respond  
blackvenomm666   -  Jun 10, 2011

sweet

 Respond  
napa182   -  Jun 09, 2011

lol fun lil game for a few seconds lol

 Respond  
Joshuaxiong1   -  Jun 09, 2011

Lol I used it for a school project too.

 Respond  
Rao Mn Akhi   -  Jun 09, 2011

Hey
So Iwas using your code for my school projetc.. I created a new file as an "applet" and I got it to run. but i couldn't ee any images, although I trasfered the images..

but it says Applet not initialized

Thanks you

 Respond  
tv3636   -  Aug 13, 2010

Are you sure you have the images in the right place? If you're getting a blank window it's probably because the images aren't being loaded properly. Can't think of what else it would be though, sorry.

 Respond  
Mnel94   -  Aug 12, 2010

hey guys;

im kinda new to java, im 16 in grade 10.
i take IT and i saw your helicopter program code and tried to use it but when i run it it throws a blank window out. please tell me how to get it right. thanks guys.

 Respond  
tv3636   -  Nov 17, 2009

yeah, it still is, this is my remake of it

 Respond  
asakura   -  Nov 16, 2009

dude i know this it use to be on loads of websites its like everywhere

 Respond  
tv3636   -  Nov 16, 2009

As I said in PM, nope I'm not, and yes it is but I wasn't able to figure it out myself. I didn't learn how to make web applets and although I got it pretty close to working online I wasn't able to figure it out. Feel free to take the code and try yourself though!

 Respond  
Joshuaxiong1   -  Nov 16, 2009

It is possible to put this in the web?

 Respond  
Joshuaxiong1   -  Nov 16, 2009

You from CART Unified?

 Respond  
Joshuaxiong1   -  Nov 16, 2009

Yes my best! 709

 Respond  
tv3636   -  Jun 22, 2009

Sorry..I saw this comment and forgot to reply to it.

I tried tons of different things and I could never totally get the web applet working, the way it was coded didn't allow an easy (or any) transition to the web. I'll get around to updating the final code and .exe soon but I'm going on vacation tomorrow.

Oh, and hundreds of visits a day? Wow! I bet it's people at school trying to play the game though, and I wouldn't be surprised if that number has gone down drastically in the past few days.

 Respond  
Hawkee   -  Jun 07, 2009

This has turned out to be quite a popular page. It gets a few hundred visits/day from Google, so maybe you should get your applet running ;)

 Respond  
Jonesy44   -  Jun 07, 2009

Perhaps it's a windows DLL that's missing? Who knows!! I'm learning VB/C++ Atm, so i'll give java another go some other time lol :D

 Respond  
tv3636   -  Jun 07, 2009

the exe file says that? O_o I didn't use any dll's so that wouldn't make sense..unless you mean JCreator in which case I dunno. Still haven't had time to make a web version, I'll just wait until it's totally complete though.

And thank you Hawkee and Daniel :)

 Respond  
Jonesy44   -  Jun 02, 2009

It says it's missing a DLL plugin for me, but the game runs eventually. Any ideas? :D

 Respond  
_Daniel_   -  Jun 02, 2009

my best was 1300, nice work tv3636 ;D

 Respond  
Hawkee   -  Jun 01, 2009

This is great! It compiled and ran on the first try with OS X Eclipse. I only played a few times but my best score is 1,268. Should make it get harder as you go along so it doesn't get boring after a while.

 Respond  
tv3636   -  Jun 01, 2009

It's a popular flash game, but I recreated it in Java myself.

 Respond  
_Daniel_   -  Jun 01, 2009

I already saw this game, but the scenery collors are different

 Respond  
Jonesy44   -  May 31, 2009

ok. I'll give it a go :D

 Respond  
tv3636   -  May 31, 2009

Probably a couple hundred, but the free version is fine for my purposes..and I have no idea really, I just use it because our teacher expects us to. I haven't seen/tried other IDE's. I have no real problems with it though.

 Respond  
Jonesy44   -  May 31, 2009

ooh ok cool. i'll give it a go sometime :D how much is the full thing? and is it the best going?

 Respond  
tv3636   -  May 31, 2009

JCreator has a free version called learning edition if you want to run it that way, and then you would make a class called HelicopterForm (case matters) and paste this in there. There's a run button at the top and you can probably figure out the rest from there. You need the images from the zip file inside the project folder though, so you have to download the .zip.

Or, download the zip file and run the .exe inside it :p

I'll try to get a web version of this running today, I think I know how to now.

 Respond  
Jonesy44   -  May 31, 2009

Sorry for my n00bness. But how would I go about running this? Is there a freeware edition? :)

JanetRandall  -  May 30, 2013
Sign in to comment

Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.