我正在创建一个类似Frogger的游戏,如果你愿意的话,我的精灵(青蛙)(图像)会被创建,但不会在我的按键上移动,我相信错误发生在draw()方法的某个地方对于实际的frog.java类。这是我自己的项目,我正在尝试合并多态和继承。有没有办法使用我拥有的绘制和移动方法移动我的精灵,否则这是正确的方法。不幸的是,这是在Netbeans中完成的。
import java.awt.*;
import java.awt.event.*;
public class FroggerForm extends Frame implements ActionListener
{
private Frog frog;
private javax.swing.Timer moveTimer = new javax.swing.Timer(500, this);
/**
Creates new form FroggerForm
*/
public FroggerForm()
{
initComponents();
this.setSize(400, 400);
frog = new Frog(froggerPanel);
moveTimer.start();
}
/**
This method is called from within the constructor to initialize the form.
WARNING: Do NOT modify this code. The content of this method is always
regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents()
{
froggerPanel = new java.awt.Panel();
setMinimumSize(new java.awt.Dimension(500, 500));
addWindowListener(new java.awt.event.WindowAdapter()
{
public void windowClosing(java.awt.event.WindowEvent evt)
{
exitForm(evt);
}
});
setLayout(null);
froggerPanel.setBackground(new java.awt.Color(190, 190, 190));
froggerPanel.setPreferredSize(new java.awt.Dimension(400, 400));
froggerPanel.addKeyListener(new java.awt.event.KeyAdapter()
{
public void keyPressed(java.awt.event.KeyEvent evt)
{
keyAdapter(evt);
}
});
add(froggerPanel);
froggerPanel.setBounds(100, 0, 400, 400);
pack();
}// </editor-fold>
/**
Exit the Application
*/
private void exitForm(java.awt.event.WindowEvent evt) {
System.exit(0);
}
private void keyAdapter(java.awt.event.KeyEvent evt)
{
frog.hide();
if(evt.getSource() == KeyEvent.VK_UP)
frog.move(0, -10);
else if(evt.getSource() == KeyEvent.VK_DOWN)
frog.move(0, 10);
else if(evt.getSource() == KeyEvent.VK_RIGHT)
frog.move(10, 0);
else if(evt.getSource() == KeyEvent.VK_LEFT)
frog.move(-10 , 0);
}
/**
@param args the command line arguments
*/
public static void main(String args[])
{
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
new FroggerForm().setVisible(true);
}
});
}
// Variables declaration - do not modify
private java.awt.Panel froggerPanel;
// End of variables declaration
@Override
public void actionPerformed(ActionEvent ae)
{
frog.draw();
frog.move();
}
}
public abstract class PFigure implements Comparable
{
protected int x, y; // Current position of the figure
protected int width, height; // Drawn (displayed) this size
protected int priority; // Can use to determine "winner"
protected Panel panel; // Panel the figure lives on
public PFigure ( int startX, int startY, int _width, int _height,
int pr, Panel p )
{
x = startX;
y = startY;
width = _width;
height = _height;
priority = pr;
panel = p;
}
// Can use this in "battles", which figures is "greater"
public int compareTo(Object o)
{
if( o instanceof PFigure )
return priority - ((PFigure)o).priority;
return Integer.MAX_VALUE;
}
// Has "this" figure collided with p?
public boolean collidedWith ( PFigure p )
{
if ( p == null )
return false;
return ( x + width ) >= p.x && ( p.x + p.width ) >= x &&
( y + height ) >= p.y && ( p.y + p.height ) >= y;
}
// Can be used for moving by keyboard or mouse
public void move ( int deltaX, int deltaY )
{
x = x + deltaX;
y = y + deltaY;
}
public void hide()
{
Graphics g = panel.getGraphics();
Color oldColor = g.getColor();
g.setColor(panel.getBackground() );
g.fillRect(x, y, width, height);
g.setColor(oldColor);
}
// Can be automatic move, for example, called based on timer
public void move()
{
}
// Draw the figure.
// Each derived class will write their own drawing method.
// The first line should be:
// Graphics g = panel.getGraphics();
abstract public void draw();
}
import java.awt.*;
import java.io.File;
import javax.imageio.ImageIO;
public class Frog extends PFigure
{
private Image frogImg;
public Frog(Panel p)
{
super(200, 350, 30, 30, 0, p);
try
{
File file = new File("frogger.png");
frogImg = ImageIO.read(file);
}
catch ( Exception e )
{
System.out.println("Crashing: " + e);
}
}
@Override
public void draw()
{
if(frogImg != null)
{
Graphics g = panel.getGraphics();
g.drawImage(frogImg, x, y, width, height, null);
}
}
@Override
public void move(int deltaX, int deltaY)
{
if ( x <= 0)
x = 1;
else if(x >= panel.getSize().width)
x = panel.getSize().width - 1;
else if(y >= panel.getSize().height)
y = panel.getSize().height - 1;
x += deltaX;
y += deltaY;
}
}
答案 0 :(得分:0)
我相信您的第一个错误是使用KeyListener
。
KeyListener
只会在注册的组件具有焦点并且可以对焦时响应击键。
使用Key Bindings代替,它们允许您定义将生成关键事件的焦点级别
<强>更新强>
作为一个例子......
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class WizardFireball {
public static void main(String[] args) {
new WizardFireball();
}
public WizardFireball() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GamePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GamePane extends JPanel {
private GameModel model;
public GamePane() {
try {
model = new DefaultModel();
ActionMap am = getActionMap();
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "up-pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "down-pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "left-pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "right-pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "up-released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "down-released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "left-released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "right-released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "fire");
am.put("up-pressed", new KeyPressedAction(getModel(), Key.UP));
am.put("down-pressed", new KeyPressedAction(getModel(), Key.DOWN));
am.put("left-pressed", new KeyPressedAction(getModel(), Key.LEFT));
am.put("right-pressed", new KeyPressedAction(getModel(), Key.RIGHT));
am.put("up-released", new KeyReleasedAction(getModel(), Key.UP));
am.put("down-released", new KeyReleasedAction(getModel(), Key.DOWN));
am.put("left-released", new KeyReleasedAction(getModel(), Key.LEFT));
am.put("right-released", new KeyReleasedAction(getModel(), Key.RIGHT));
am.put("fire", new FireBallAction(getModel()));
} catch (IOException ex) {
ex.printStackTrace();
}
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for (Asset asset : getModel().getAssets()) {
asset.update(GamePane.this);
}
repaint();
}
});
timer.start();
}
public GameModel getModel() {
return model;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Asset asset : getModel().getAssets()) {
asset.paint(this, g2d);
}
g2d.dispose();
}
}
public enum Key {
LEFT,
RIGHT,
UP,
DOWN
}
public interface GameModel {
public void keyPressed(Key key);
public void keyReleased(Key key);
public boolean isKeyPressed(Key key);
public void addFireball();
public void remove(Asset asset);
public Wizard getWizard();
public Iterable<Asset> getAssets();
}
public class DefaultModel implements GameModel {
private Set<Key> keys;
private Wizard wizard;
private List<Asset> assets;
public DefaultModel() throws IOException {
keys = new HashSet<>(25);
assets = new ArrayList<>(25);
wizard = new Wizard();
}
@Override
public void keyPressed(Key key) {
keys.add(key);
}
@Override
public void keyReleased(Key key) {
keys.remove(key);
}
@Override
public boolean isKeyPressed(Key key) {
return keys.contains(key);
}
@Override
public Wizard getWizard() {
return wizard;
}
@Override
public void addFireball() {
try {
assets.add(new Fireball(getWizard()));
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public void remove(Asset asset) {
assets.remove(asset);
}
@Override
public Iterable<Asset> getAssets() {
List<Asset> proxy = new ArrayList<>(assets);
proxy.add(wizard);
return proxy;
}
}
public abstract class AbstractGameAction extends AbstractAction {
private GameModel model;
public AbstractGameAction(GameModel model) {
this.model = model;
}
public GameModel getModel() {
return model;
}
}
public abstract class AbstractKeyAction extends AbstractGameAction {
private Key key;
public AbstractKeyAction(GameModel model, Key key) {
super(model);
this.key = key;
}
public Key getKey() {
return key;
}
}
public class KeyPressedAction extends AbstractKeyAction {
public KeyPressedAction(GameModel model, Key key) {
super(model, key);
}
@Override
public void actionPerformed(ActionEvent e) {
getModel().keyPressed(getKey());
}
}
public class KeyReleasedAction extends AbstractKeyAction {
public KeyReleasedAction(GameModel model, Key key) {
super(model, key);
}
@Override
public void actionPerformed(ActionEvent e) {
getModel().keyReleased(getKey());
}
}
public class FireBallAction extends AbstractGameAction {
public FireBallAction(GameModel model) {
super(model);
}
@Override
public void actionPerformed(ActionEvent e) {
getModel().addFireball();
}
}
public interface Asset {
public void paint(GamePane surface, Graphics2D g2d);
public void update(GamePane surface);
public Rectangle getBounds();
}
public class Fireball implements Asset {
private final BufferedImage fireball;
private final Rectangle bounds;
public Fireball(Wizard wizard) throws IOException {
fireball = ImageIO.read(getClass().getResource("/Fireball.png"));
bounds = new Rectangle();
bounds.x = wizard.getBounds().x + wizard.getBounds().width;
bounds.y = wizard.getBounds().y + (wizard.getBounds().height - fireball.getHeight());
bounds.setSize(fireball.getWidth(), fireball.getHeight());
}
@Override
public Rectangle getBounds() {
return bounds;
}
@Override
public void paint(GamePane surface, Graphics2D g2d) {
Rectangle bounds = getBounds();
g2d.drawImage(fireball, bounds.x, bounds.y, surface);
}
@Override
public void update(GamePane surface) {
Rectangle bounds = getBounds();
bounds.x += 8;
if (bounds.x > surface.getWidth()) {
surface.getModel().remove(this);
}
}
}
public class Wizard implements Asset {
private final BufferedImage wizard;
private final Rectangle bounds;
private boolean initialised = false;
public Wizard() throws IOException {
wizard = ImageIO.read(getClass().getResource("/Wizard.png"));
bounds = new Rectangle(wizard.getWidth(), wizard.getHeight());
}
@Override
public Rectangle getBounds() {
return bounds;
}
@Override
public void paint(GamePane surface, Graphics2D g2d) {
Rectangle bounds = getBounds();
Point point = bounds.getLocation();
if (!initialised) {
point = new Point(5, (surface.getHeight() - bounds.height) / 2);
bounds.setLocation(point);
initialised = true;
}
g2d.drawImage(wizard, point.x, point.y, surface);
}
@Override
public void update(GamePane surface) {
Rectangle bounds = getBounds();
Point point = bounds.getLocation();
if (initialised) {
GameModel model = surface.getModel();
if (model.isKeyPressed(Key.UP)) {
point.y -= 4;
} else if (model.isKeyPressed(Key.DOWN)) {
point.y += 4;
}
if (point.y < 0) {
point.y = 0;
} else if (point.y + bounds.height > surface.getHeight()) {
point.y = surface.getHeight() - bounds.height;
}
bounds.setLocation(point);
}
}
}
}