使用OOP的简单Java游戏任务

时间:2012-08-05 20:31:27

标签: java oop graphics

所以我一直在尝试用Java制作非常简单的游戏。当我在一个类中创建整个程序时,我一直在取得成功,但每当我尝试添加面向对象的原则时,一切都会崩溃。我想要的是从我的好人那里发射子弹,这或多或少是一个炮塔。我可以轻松地设置这样的东西,但当我尝试使用类来代表好人和子弹时,一切都崩溃了。 这是我到目前为止所拥有的。 设置主程序框架:

import javax.swing.JFrame;

public class Shooter 
{
    public static void main (String[] args)
    {
        JFrame frame = new JFrame("Car");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        ShooterPanel panel = new ShooterPanel();

        frame.getContentPane().add(panel);
        frame.pack();
        frame.setVisible(true);
    }
}

ShooterPanel类:

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

public class ShooterPanel extends JPanel
{
    final int WIDTH = 200, HEIGHT = 100;
    GoodGuy hero;

    public ShooterPanel()
    {
        hero = new GoodGuy(0, HEIGHT-20, 20);
        addKeyListener(new MoveListener());
        setPreferredSize(new Dimension (WIDTH, HEIGHT));
        setFocusable(true); 
    }
    public void paintComponent(Graphics page)
    {
        super.paintComponent(page);
        hero.draw(page);
    }
    private class MoveListener implements KeyListener
    {

        public void keyPressed (KeyEvent event)
        {
            switch (event.getKeyCode())
            {
                case KeyEvent.VK_SPACE:
                    hero.shoot();
                    break;
            }
        }
        //--------------------------------------------------------------
        //Provide empty definitions for unused event methods.
        //--------------------------------------------------------------
        public void keyTyped (KeyEvent event) {}
        public void keyReleased (KeyEvent event) {}
    }
}

我们的主角:

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class GoodGuy 
{
    private int x, y, size;
    private Bullet bullet;

    public GoodGuy(int x, int y, int height)
    {
        size = height;
        this.x = x;
        this.y = y;
    }
    public int getSize()
    {
        return size;
    }
    public void draw(Graphics page)
    {
        page.drawRect(x, y, size, size);
    }
    public void shoot()
    {
        bullet = new Bullet(x+size, y);
    }
}

他的子弹:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

public class Bullet 
{
    private int x, y;
    final int LENGTH = 5, DELAY =200;
    private Timer timer;
    Graphics page1;

    public Bullet(int x, int y)
    {
        this.x = x;
        this.y = y;
        timer = new Timer(DELAY, new BulletListener());
        timer.start();
    }
    public void draw(Graphics page)
    {
        page.drawLine (x, y, x+LENGTH, y);  
    }

    //*****************************************************************
    // Represents the action listener for the timer.
    //*****************************************************************
    private class BulletListener implements ActionListener
    {
        public void actionPerformed (ActionEvent event)
        {
            x +=5;  
            draw(page1);
        }
    }
}

我想要发生的是空格键被按下,子弹出现在好人身上,并且它会在屏幕上向右移动。我根本无法得到子弹。我尝试了几件事,都无济于事。我确信这很容易。正如我所说,我可以在我的ShooterPanel类中使用变量来绘制子弹而不是创建对象,但我想要面向对象。有没有人有我的解决方案?我非常感谢一些帮助,但我正在寻找解决方案。如果你只是提出一个模糊的建议,我宁愿没有回应。编辑:这是我希望我的程序工作的方式:

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

public class ShooterPanel extends JPanel
{
final int WIDTH = 200, HEIGHT = 100;
GoodGuy hero;
ArrayList<BadGuy> enemies = new ArrayList<BadGuy>();
ArrayList<Bullet> bullets = new ArrayList<Bullet>();
private Timer timer, bulletTimer;

final int DELAY = 200;
int count=0;
private boolean bulletOut = false;

public ShooterPanel()
{
    hero = new GoodGuy(0, HEIGHT-20, 20);
    addKeyListener(new MoveListener());
    timer = new Timer(DELAY, new EnemyListener());
    bulletTimer = new Timer(100, new BulletListener());
    setPreferredSize(new Dimension (WIDTH, HEIGHT));
    //enemies.add(new BadGuy(WIDTH-10, HEIGHT-10));
    setFocusable(true );
    timer.start();
}
public void paintComponent(Graphics page)
{
    super.paintComponent(page);
    hero.draw(page);
    for (int i = 0; i < enemies.size(); i++)
    {
        enemies.get(i).draw(page);
    }
    if (bulletOut)
        for(Bullet bullet: bullets)
            bullet.draw(page);

}
private class MoveListener implements KeyListener
{
    //--------------------------------------------------------------
    //Responds to the user pressing arrow keys by adjusting the
    //image and image location accordingly.
    //--------------------------------------------------------------
    public void keyPressed (KeyEvent event)
    {
        switch (event.getKeyCode())
        {
        case KeyEvent.VK_SPACE:
            bullets.add(new Bullet(20,95));
            bulletOut = true;
            bulletTimer.start();
            break;
        }

    }
    //--------------------------------------------------------------
    //Provide empty definitions for unused event methods.
    //--------------------------------------------------------------
    public void keyTyped (KeyEvent event) {}
    public void keyReleased (KeyEvent event) {}
}
//*****************************************************************
// Represents the action listener for the timer.
//*****************************************************************
private class EnemyListener implements ActionListener
{
    //--------------------------------------------------------------
    // Updates the position of the image and possibly the direction
    // of movement whenever the timer fires an action event.
    //--------------------------------------------------------------
    public void actionPerformed (ActionEvent event)
    {
        if (count%20==0)
            enemies.add(new BadGuy(WIDTH-10, HEIGHT-10));

        for (BadGuy enemy: enemies)
        {
            enemy.move();
        }

        count++;
        repaint();
    }
}
private class BulletListener implements ActionListener
{
    //--------------------------------------------------------------
    // Updates the position of the image and possibly the direction
    // of movement whenever the timer fires an action event.
    //--------------------------------------------------------------
    public void actionPerformed (ActionEvent event)
    {
        for(Bullet bullet: bullets)
            bullet.move();
        for(int i = 0; i < bullets.size(); i++)
        {

            if (enemies.size() != 0)
            {
                if (bullets.get(i).getX() > enemies.get(0).getX())
                {
                    bullets.remove(i);
                    enemies.remove(0);
                }
            }
            if (bullets.size() != 0)
            {
                if (bullets.get(i).getX()>WIDTH)
                    bullets.remove(i);
            }       
        }
        repaint();
    }
}
}
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class GoodGuy 
{
private int x, y, size;
private Bullet bullet;

public GoodGuy(int x, int y, int height)
{
    size = height;
    this.x = x;
    this.y = y;
}
public int getSize()
{
    return size;
}
public void draw(Graphics page)
{
    page.drawRect(x, y, size, size);
}
public void shoot()
{
    bullet = new Bullet(x+size, y);

}
}

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

public class BadGuy 
{
private int x, y;
final int RADIUS = 5;


public BadGuy(int x, int y)
{
    this.x = x;
    this.y = y;

}
public void move()
{
    x -= 5;

}
public void draw(Graphics page)
{
    page.drawOval(x, y, RADIUS*2, RADIUS*2);
}
public int getX()
{
    return x;
}

}
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

public class Bullet 
{
private int x, y;
final int LENGTH = 5, DELAY =200;

public Bullet(int x, int y)
{
    this.x = x;
    this.y = y;
}
public void draw(Graphics page)
{
    page.drawLine (x, y, x+LENGTH, y);

}
public void move()
{
    x += 5;
}
public int getX()
{
    return x;
}   
}

射手类保持不变。这就是我希望程序要做的事情,但这并不是我想要它做到的。我更喜欢它是否更加面向对象,每个类都照顾好自己。 ShooterPanel已经开始对我的品味有点复杂,并且随着更多的添加到程序中而变得更糟。我想改变的一件事是每个子弹都有自己的计时器,在Bullet类中定义了一个ActionListener。但是,我无法弄清楚如何以每次计时器触发事件​​时重新绘制子弹的方式执行此操作。如果有人知道这样做的方法,请告诉我。

2 个答案:

答案 0 :(得分:0)

你需要让你的ShooterPanel成为焦点。添加:

    setFocusable(true);
    requestFocusInWindow();

从不设置BulletListener的图形。这种绘画应该可能发生在ShooterPanel本身。

答案 1 :(得分:0)

尝试利用KeyBindings API代替KeyListener,如果设置正确,则应该重点关注问题。