Java 2D游戏添加炸弹

时间:2014-04-28 13:22:42

标签: java android applet 2d

我对游戏设计很陌生(这是我的第一次尝试),这个项目将用于创建一个Android游戏。

我试图制作一个简单的游戏(尽可能简单)。

我需要什么:

  • 背景
  • 一艘船(可在屏幕底部左右移动)
  • 敌人(炸弹从天而降)
  • 射弹(射击炸弹,射击直射)
  • 得分(在上角)

我研究了这个教程: http://www.kilobolt.com/game-development-tutorial.html

并更改了代码以获取此信息: http://i297.photobucket.com/albums/mm231/mabee84/Battleship.png

黑色矩形是抛射物。

现在我需要制作炸弹,但我无法弄清楚如何实施炸弹。

他们需要以固定的y值和随机的x值(在屏幕内)产生 在炸弹上射击后,他们应该死亡,但如果炸弹击中了船只游戏结束了。

请帮助我有点卡住。

    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);
    }

}

这是我到目前为止所有的代码(我知道背景是f * ed,因为这是基于滚动的游戏,我还没有修复它。

1 个答案:

答案 0 :(得分:0)

我建议将所有对象创建放在程序的单独部分中。我用makeBomb mathod创建一个BombFactory,返回一个新的Bomb实例。在工厂内部,找出x坐标,例如使用随机数。作为参数,您可以指定y坐标,也可以指定x的上限和下限。这样你就可以动态制作新的炸弹。

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);
    }

}

至于行为,我会更多地研究继承和接口。我看到很多方法不止一次出现。您通常希望避免这种重复。您可以从采用与坐标或运动有关的所有方法开始,并将它们放在抽象基类中。

你可以在Enemy中创建一个检查碰撞的方法,并以不同的方式响应它,具体取决于子类如何覆盖它。在炸弹的情况下,它可能总是自杀,无论它接触到什么。