Question

I'm very new to game design (this is my first attempt) and this project will be used to create an android game.

I'm trying to make a simple game (as simple as possible).

What I need:

  • A background
  • a ship (that can move left an right at the bottom of the screen)
  • Enemies (Bombs dropping down from the sky)
  • projectiles (to shoot bombs with, shoot straight up)
  • Score (in the upper corner)

I have studied this tutorial: http://www.kilobolt.com/game-development-tutorial.html

and changed code to get this: http://i297.photobucket.com/albums/mm231/mabee84/Battleship.png

the black rectangles are projectiles.

Now I need to create the bombs but I can't figure out how to implement them.

they need to spawn at fixed y-value and a random x-value (within the screen) Upon shooting on the bombs they should die but if bombs hit the ship game is over.

Please help i'm a bit stuck.

    package kiloboltgame;

    import java.applet.Applet;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.net.URL;
    import java.util.ArrayList;

    public class StartingClass extends Applet implements Runnable, KeyListener {
        private Ship ship;
        public static Bomb b1, b2;
        public static int score = 0;
        private Font font = new Font(null, Font.BOLD, 30);
        private Image image, Battleship, Background, Bomb;
        private static Background bg1, bg2;
        private URL base;
        private Graphics second;

        @Override
        public void init() {

            setSize(800, 480);
            setBackground(Color.BLACK);
            setFocusable(true);
            addKeyListener(this);
            Frame frame = (Frame) this.getParent().getParent();
            frame.setTitle("BattleShip");
            try{
                base = getDocumentBase();
            }catch (Exception e){
                //TODO: handle exception
            }

            //Image Setups
            Battleship = getImage(base, "data/Battleship.png");
            Background = getImage(base, "data/Background.png");
            Bomb = getImage(base, "data/Bomb1.png");
        }

        @Override
        public void start() {
            bg1 = new Background(0, 0);
            bg2 = new Background(800, 0);
            ship = new Ship();
            b1 = new Bomb(340, 100);
            b2 = new Bomb(700, 100);
            Thread thread = new Thread(this);
            thread.start();
        }

        @Override
        public void stop() {
            // TODO Auto-generated method stub
        }

        @Override
        public void destroy() {
            // TODO Auto-generated method stub
        }

        @Override
        public void run() {
            while (true) {
                ship.update();

                ArrayList projectiles = ship.getProjectiles();
                for(int i = 0; i < projectiles.size(); i++){
                    Projectile p = (Projectile) projectiles.get(i);
                    if(p.isVisible() == true){
                        p.update();
                    }else{
                        projectiles.remove(i);
                    }
                }
                b1.update();
                b2.update();
                bg1.update();
                bg2.update();
                repaint();
                try {
                    Thread.sleep(17);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }

        @Override
        public void update(Graphics g) {
            if(image == null){
                image = createImage(this.getWidth(), this.getHeight());
                second = image.getGraphics();
            }

            second.setColor(getBackground());
            second.fillRect(0, 0, getWidth(), getHeight());
            second.setColor(getForeground());
            paint(second);

            g.drawImage(image, 0, 0, this);
        }
        @Override
        public void paint(Graphics g) {
            g.drawImage(Background, bg1.getBgX(), bg1.getBgY(), this);

            ArrayList projectiles = ship.getProjectiles();
            for(int i = 0; i < projectiles.size(); i++){
                Projectile p = (Projectile) projectiles.get(i);
                g.setColor(Color.BLACK);
                g.fillRect(p.getX(), p.getY(), 5, 10);
            }
            g.drawImage(Battleship, ship.getCenterX() + 230, ship.getCenterY() -23, this);
            g.drawImage(Bomb, b1.getCenterX() - 20, b1.getCenterY() - 20, this);
            g.drawImage(Bomb, b2.getCenterX() - 20, b2.getCenterY() - 20, this);

            g.setFont(font);
            g.setColor(Color.BLACK);
            g.drawString(Integer.toString(score), 710, 30);
        }


        @Override
        public void keyPressed(KeyEvent e) {

            switch(e.getKeyCode()){
            case KeyEvent.VK_LEFT:
                ship.moveLeft();
            break;

            case KeyEvent.VK_RIGHT:
                ship.moveRight();
            break;

            case KeyEvent.VK_CONTROL:
                ship.shoot();
                score = score +100;
            break;

            }

        }

        @Override
        public void keyReleased(KeyEvent e) {
            switch (e.getKeyCode()) {
            case KeyEvent.VK_LEFT:
                ship.stop();
                break;

            case KeyEvent.VK_RIGHT:
                ship.stop();
                break;
            }

        }

        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub

        }

        public static Background getBg1() {
            return bg1;
        }

    }

    package kiloboltgame;

    import java.util.ArrayList;

    public class Ship {

             //In Java, Class Variables should be private so that only its methods can change them.
            private int centerX = 100;
            private int centerY = 382;

            private int speedX = 0;
            private int speedY = 1;

            private ArrayList<Projectile> projectiles = new ArrayList<Projectile>();

            public void update() {

                // Moves Character or Scrolls Background accordingly.
                if (speedX < 0) {
                    centerX += speedX;
                } else if (speedX == 0) {
                    System.out.println("Do not scroll the background.");

                } else {
                    if (centerX <= 440) {
                        centerX += speedX;
                    } else {
                        System.out.println("Scroll Background Here");
                    }
                }

                // Updates Y Position

                if (centerY + speedY >= 382) {
                    centerY = 382;
                }else{                       
                             centerY += speedY;
                        }


                // Prevents going beyond X coordinate of 0
                if (centerX + speedX <= -230) {
                    centerX = -229;
                }
            }

            public void moveRight() {
                speedX = 6;
            }

            public void moveLeft() {
                speedX = -6;
            }

            public void shoot(){
                Projectile p = new Projectile(centerX + 285, centerY -10);
                projectiles.add(p);
            }

            public ArrayList getProjectiles(){
                return projectiles;
            }

            public void stop() {
                speedX = 0;
            }

            public int getCenterX() {
                return centerX;
            }

            public int getCenterY() {
                return centerY;
            }

            public int getSpeedX() {
                return speedX;
            }

            public int getSpeedY() {
                return speedY;
            }

            public void setCenterX(int centerX) {
                this.centerX = centerX;
            }

            public void setCenterY(int centerY) {
                this.centerY = centerY;
            }

            public void setSpeedX(int speedX) {
                this.speedX = speedX;
            }

            public void setSpeedY(int speedY) {
                this.speedY = speedY;
            }


    }
    package kiloboltgame;

    public class Background {

    private int bgX, bgY, speedX;

        public Background(int x, int y){
            bgX = x;
            bgY = y;
            speedX = 0;
        }

        public void update() {
            bgX += speedX;

            if (bgX <= -800){
                bgX += 1600;
            }
        }

        public int getBgX() {
            return bgX;
        }

        public int getBgY() {
            return bgY;
        }

        public int getSpeedX() {
            return speedX;
        }

        public void setBgX(int bgX) {
            this.bgX = bgX;
        }

        public void setBgY(int bgY) {
            this.bgY = bgY;
        }

        public void setSpeedX(int speedX) {
            this.speedX = speedX;
        }
    }

public class Projectile {
    private int x, y, speedY;
    private boolean visible;

    public Projectile(int startX, int startY) {
        x = startX;
        y = startY;
        speedY = -7;
        visible = true;
    }

    public void update() {
        y += speedY;
        if(y > 480){
            visible = false;
        }

    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getSpeedY() {
        return speedY;
    }

    public boolean isVisible() {
        return visible;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setSpeedY(int speedY) {
        this.speedY = speedY;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }

}

package kiloboltgame;

public class Enemy {
    private int maxHealth, currentHealth, power, speedX, centerX, centerY;
    private Background bg = StartingClass.getBg1();

    //Behavioral Methods
    public void update(){
        centerX += speedX;
        speedX = bg.getSpeedX();
    }

    public void die(){
    }

    public void attack(){
    }

    public int getMaxHealth() {
        return maxHealth;
    }

    public int getCurrentHealth() {
        return currentHealth;
    }

    public int getPower() {
        return power;
    }

    public int getSpeedX() {
        return speedX;
    }

    public int getCenterX() {
        return centerX;
    }

    public int getCenterY() {
        return centerY;
    }

    public Background getBg() {
        return bg;
    }

    public void setMaxHealth(int maxHealth) {
        this.maxHealth = maxHealth;
    }

    public void setCurrentHealth(int currentHealth) {
        this.currentHealth = currentHealth;
    }

    public void setPower(int power) {
        this.power = power;
    }

    public void setSpeedX(int speedX) {
        this.speedX = speedX;
    }

    public void setCenterX(int centerX) {
        this.centerX = centerX;
    }

    public void setCenterY(int centerY) {
        this.centerY = centerY;
    }

    public void setBg(Background bg) {
        this.bg = bg;
    }

}

package kiloboltgame;

public class Bomb extends Enemy {

    public Bomb(int centerX, int centerY) {
        setCenterX(centerX);
        setCenterY(centerY);
    }

}

This is all code that i have so far (I know the background is f*ed since the game this is based on is scrolling right and i haven't fixed it yet.

Was it helpful?

Solution

I recommend putting all object creation in a seperate part of the program. I'd make a BombFactory with a makeBomb mathod that returns a new Bomb instance. Inside the factory, figure out the x-coordinate, for instance using a randomiser. As parameters, you could specify a y-coordinate and possibly an upper and lower bound for the x. This way you can make new Bombs on the fly.

public class BombFactory {

    private final Random rand;

    public BombFactory() {
        this.rand = new Random();
    }

    public Bomb makeBomb(int lowerboundX, int rangeX, int yPos) {
        final int xPos = lowerboundX + rand.nextInt(rangeX);
        return new Bomb(xPos, yPos);
    }

}

As for the behaviour, I'd look into inheritance and interfaces some more. I see a lot of methods occurring more than once. You generally want to avoid that kind of duplication. You can start by taking all the methods having something to do with coords or movement and putting them in an abstract base class.

You can make a method inside Enemy that checks for a collision and responds to that in different ways, depending on how the subclass overrides it. In case of a Bomb, it would probably always kill itself and whatever it came in contact with.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top