java 2d游戏 - 游戏和碰撞问题

时间:2014-01-15 12:39:13

标签: java

我正在设计一个简单的java 2d游戏。飞机射击导弹并且他们击中外星人的船只。(图片附上以便更好地理解)。 enter image description here

现在我需要检测导弹何时撞到外星飞船。以便计算总命中数。我使用rectangle1.intersects(rec2)方法,但不是给我一个整数1作为答案(当然是在布尔值之后),它给了我一些有趣的答案。我想两个矩形相交多少... 此外,当在arraylist中添加新的外星人时,我使用以下内容:我每两秒钟添加一次新的外星人,但这会让游戏变慢。

所以请指导我这两个问题。

game类(包含主框架),board类(我绘制的面板),导弹和craft类。下面我给出actionPerformed()类的panel,每2ms由一个定时器调用(其余代码在下面)。

///要聚焦的代码

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

    public class game extends JFrame {

        static long z;

    game()

    {
        add(new board());
        setBounds(0, 0, 500, 500);
        setVisible(true);
        setLayout(null);
        setLocationRelativeTo(null);

        setTitle("\t\t...................::::~~~~'S GAME~~~~:::::...............");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }

    public static void main(String[] args) {

        new game();
        z = System.currentTimeMillis();

    }

}

class board extends JPanel implements ActionListener

{
    Timer t = new Timer(5, this);
    public ArrayList alien_list;
    craft craft_list = new craft();
    Label l = new Label();
    int total_hits = 0;

    public board() {
        setFocusable(true);
        setLayout(null);
        setDoubleBuffered(true);
        setBackground(Color.BLACK);
        addKeyListener(craft_list);
        l.setBounds(0, 0, 150, 30);
        l.setBackground(Color.GREEN);
        add(l);
        t.start();

        alien_list = new ArrayList();
        alien_list.add(new alien(0, 100));
        alien_list.add(new alien(0, 150));
        alien_list.add(new alien(0, 200));

    }

    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g1 = (Graphics2D) g;

        long z = (System.currentTimeMillis() - game.z) / 1000;
        if (z >= 60)

        {
            remove(l);
            g.setColor(Color.red);
            g1.drawString("time up", 100, 100);
        } else

        {
            g1.drawImage(craft_list.getImage(), craft_list.getX(),
                    craft_list.getY(), null);

            ArrayList a = craft_list.getmissile();

            for (int i = 0; i < a.size(); i++) {
                missile m = (missile) a.get(i);
                g1.drawImage(m.getImage(), m.getX(), m.getY(), null);
            }

            l.setText("time elapsed:" + " " + +z + " " + "hits:" + " "
                    + total_hits);

            for (int i = 0; i < alien_list.size(); i++) {
                alien m = (alien) alien_list.get(i);
                g1.drawImage(m.getImage(), m.getX(), m.getY(), null);
            }

        }
    }

    public void actionPerformed(ActionEvent e) {

        ArrayList a = craft_list.getmissile();

        for (int i = 0; i < a.size(); i++) {
            missile m = (missile) a.get(i);
            if (m.visible == true)
                m.move();
            else
                a.remove(i);
        }

        long z = (System.currentTimeMillis() - game.z) / 1000;
        if (z % 3 == 0)
            alien_list.add(new alien(-10, 100));

        for (int j = 0; j < alien_list.size(); j++) {
            alien m = (alien) alien_list.get(j);

            if (m.visible == true)
                m.move();
            else
                alien_list.remove(j);

        }

        craft_list.move();
        collison();
        repaint();

    }

    public void collison() {

        ArrayList a = craft_list.getmissile();
        for (int i = 0; i < a.size(); i++) {
            missile m = (missile) a.get(i);
            Rectangle r1 = m.getBounds();

            for (int j = 0; j < alien_list.size(); j++) {
                alien l = (alien) alien_list.get(j);
                Rectangle r2 = l.getBounds();
                if (r1.intersects(r2)) {
                    total_hits++;

                    m.setVisible(false);
                    l.setVisible(false);

                }

            }
        }
    }
}

class craft extends KeyAdapter

{

    int x = 250;
    int y = 400;
    ArrayList m = new ArrayList();
    Image i;
    int dx, dy;

    craft() {
        ImageIcon i1 = new ImageIcon("1a.jpg");
        i = i1.getImage();
    }

    public Image getImage() {
        return i;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public void move() {
        x += dx;
        y += dy;

        if (x < 0)
            x = 0;
        if (x > 450)
            x = 450;
        if (y > 420)
            y = 420;
        if (y < 200)
            y = 200;

    }

    public void keyPressed(KeyEvent k)

    {

        int key = k.getKeyCode();

        if (key == KeyEvent.VK_SPACE) {
            fire();
        }

        if (key == KeyEvent.VK_LEFT) {
            dx = -1;
        }

        if (key == KeyEvent.VK_RIGHT) {
            dx = 1;
        }

        if (key == KeyEvent.VK_UP) {
            dy = -1;
        }

        if (key == KeyEvent.VK_DOWN) {
            dy = 1;
        }

    }

    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT) {
            dx = 0;
        }

        if (key == KeyEvent.VK_RIGHT) {
            dx = 0;
        }

        if (key == KeyEvent.VK_UP) {
            dy = 0;
        }

        if (key == KeyEvent.VK_DOWN) {
            dy = 0;
        }
    }

    public void fire() {
        m.add(new missile(getX() + 13, getY() - 6));

    }

    public ArrayList getmissile() {
        return m;
    }

    public Rectangle getBounds() {
        return new Rectangle(x, y, i.getWidth(null), i.getHeight(null));
    }
}

class missile {

    Image i;

    int x, y;
    public boolean visible;

    missile(int x, int y) {

        this.x = x;
        this.y = y;
        visible = true;
        ImageIcon i1 = new ImageIcon("1c.jpg");
        i = i1.getImage();

    }

    public Image getImage() {
        return i;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public void move() {

        y--;
        if (y < 0)
            visible = false;
    }

    public Rectangle getBounds() {
        return new Rectangle(x, y, i.getWidth(null), i.getHeight(null));
    }

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

class alien {
    Image i;
    int x, y;;
    public boolean visible;

    public alien(int x, int y)

    {

        this.x = x;
        this.y = y;
        ImageIcon i1 = new ImageIcon("b.jpg");
        i = i1.getImage();
        visible = true;

    }

    public int getX() {
        return x;

    }

    public int getY() {
        return y;

    }

    public Image getImage() {
        return i;
    }

    public void move() {

        x++;
        if (x > 500)
            visible = false;
    }

    public Rectangle getBounds() {
        return new Rectangle(x, y, i.getWidth(null), i.getHeight(null));
    }

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

1 个答案:

答案 0 :(得分:2)

好的,您的代码格式有点难以理解,并邀请所有人监督其他明显的错误。这就是我迄今为止针对您的性能问题所看到的:

  1. getBounds()每次调用时都会创建一个新的Rectangle实例。你应该在move()的最后一行更新bounds矩形,然后返回矩形实例,而不是创建一个新的。
  2. 重用Image或ImageIcon对象。无需在构造函数中反复加载相同的jpg文件。使其静态或使用图像缓存。
  3. 你应该使用o = m.size()而不是fire()中的o ++。主要是因为你从不调用o--,你只能从ArrayList中删除火箭。
  4. 此时,每个人都会忘记om的含义。更好地命名变量! o应该是amountOfRockets而m应该是listOfRockets。

    使用Eclipse时,按ctrl + shift + f格式化我强烈推荐的代码。之后,查看代码并正确命名变量。这意味着你应该给他们一个描述性的名字。最后:让你的课程名称以大写字母开头。

    很可能这还不能解决所有问题,但它至少可以帮助我们更轻松地理解和阅读您的代码......这可能会让我们找到解决方案......

    更新

    你还没有完成1.和2.我建议你做了3。

    以下是1.应该作为Alien类的样本:

    private Rectangle bounds
    
    //constructor
    Alien() {
        // your stuff and the bounds:
        bounds = new Rectangle(x, y, i.getWidth(null), i.getHeight(null));
    }
    
    public void move() {
        bounds.x++;
        if (bounds.x > 500)
            visible = false;
    }
    
    public Rectangle getBounds() {
        return bounds;
    }
    

    你也需要为Rocket类实现它。

    我还没有得到的是删除旧Alien对象的地方。仅仅设置他们的可见性是不够的。您应该从Alien对象列表中删除它们。否则,你将遍历不再存在的对象。