所以我一直在尝试用 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);
}
}
射手面板类:
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。但是,我无法弄清楚如何以每次计时器触发事件时重新绘制子弹的方式来执行此操作。如果有人知道这样做的方法,请告诉我。