Class 从某个 KeyEvent 开始的 Cast Exception

Class Cast Exception starting on a certain KeyEvent

仍在改进同一个游戏作为我的一个旧问题,只是这次我现在有四个 classes 和另一个异常错误。还是一样"Java is 2nd language, still can't seem to prove my intermediate C++ sticker."

Briefer:制作游戏的时间跨度为 2-2.5 年,必须使用我不知道的语言来制作,因为我们团队中的多数规则(三个 java、一个 C++、1 个 php 家伙)。我正在用这个 "mini" 游戏测试机制并尝试修复损坏的东西,但这(以及其他)是 另一个我似乎无法自己解决的问题。 我尝试了论坛并浏览了 我们的一些旧 自学 java 书籍。

我需要帮助解决 Class 强制转换异常的情况。

我的代码并简要解释了应该发生的事情:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Stage extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private Timer start_stop;
private SPRITES player;
public Stage()
{
    addKeyListener(new TAdapter());
    setFocusable(true);
    setBackground(Color.black);
    setDoubleBuffered(true);

    player = new SPRITES();

    start_stop = new Timer(5, this);
    start_stop.start();

}

public void paint(Graphics character)
{
    super.paint(character);

    Graphics2D G2D = (Graphics2D) character;
    G2D.drawImage(player.getImage(), player.getX(), player.getY(), this);

    @SuppressWarnings("rawtypes")
    ArrayList ms = player.getMissiles();
    Toolkit.getDefaultToolkit().sync();
    character.dispose();

      for (int i = 0; i < ms.size(); i++ ) 
      {
            SPRITES m = (SPRITES) ms.get(i); //error here
            G2D.drawImage(m.getImage(), m.getX(), m.getY(), this);

            if(m.isVisible())
                m.move();
            else ms.remove(i);
      }
      }

      public void actionPerformedjuan(ActionEvent e) 
      {
            @SuppressWarnings("rawtypes")
            ArrayList ms = player.getMissiles();

            for (int i = 0; i < ms.size(); i++) 
            {
                SPRITES m = (SPRITES) ms.get(i);
                if (m.isVisible()) 
                    m.move();
                else ms.remove(i);  
            }
      player.move();
      repaint();
      }

public void actionPerformed(ActionEvent arg0) 
{
    player.move();
    repaint();
}

private class TAdapter extends KeyAdapter
{
    public void keyReleased(KeyEvent e)
    {
        player.keyReleased(e);
    }

    public void keyPressed(KeyEvent e)
    {
        player.keyPressed(e);
    }
}
}

设置舞台,为背景着色并准备好导入的图片。

import java.awt.event.KeyEvent;
import java.awt.Image;
import java.util.ArrayList;

import javax.swing.*;

public class SPRITES extends JPanel
{
private static final long serialVersionUID = 1L;

private static int x_sped;
private static int y_sped;
private static int x;
private static int y;
private Image sprite;

@SuppressWarnings("rawtypes")
private static ArrayList missiles;
private final static int sprite_size = 20;
@SuppressWarnings("rawtypes")
public SPRITES()
{
    ImageIcon pine = new ImageIcon(this.getClass().getResource("/resouse/SHIP.png")); 
    sprite = pine.getImage();
    missiles = new ArrayList();
    x = 40;
    y = 60;
}

public void move()
{
    x += x_sped;
    y += y_sped;
}

public int getX()
{
    return x;
}

public int getY()
{
    return y;
}

public Image getImage()
{
     return sprite;
}

@SuppressWarnings("rawtypes")
public ArrayList getMissiles()
 {
        return missiles;
 }
 @SuppressWarnings("unchecked")
public static void fire() 
{
    missiles.add(new Mussiles(x + sprite_size, y + sprite_size/2));
}
public void keyPressed(KeyEvent e)
{
    int key = e.getKeyCode();

    if(key == KeyEvent.VK_SPACE)
    {
        fire();
    }
    if(key == KeyEvent.VK_A)
    {
        x_sped = -1;
    }

    if(key == KeyEvent.VK_D)
    {
        x_sped = 2;
    }

    if(key == KeyEvent.VK_W)
    {
        y_sped = -1;
    }

    if(key == KeyEvent.VK_S)
    {
        y_sped = 1;
    }


}


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

    if(key == KeyEvent.VK_A)
    {
        x_sped = 0;
    }

    if(key == KeyEvent.VK_D)
    {
        x_sped = 0;
    }

    if(key == KeyEvent.VK_W)
    {
        y_sped = 0;
    }

    if(key == KeyEvent.VK_S)
    {
        y_sped = 0;
    }
}
}

做我的动作,导入图片。它也应该让我的导弹从船上发射 space 键,或者至少建立这个想法的结构。

import java.awt.Image;

import javax.swing.ImageIcon;

public class Mussiles 
{
private int x, y;
private Image missile;
boolean visible;

private final int width = 30;
private final int missile_sped = 2;

public Mussiles(int x, int y)
{
    ImageIcon pine = new ImageIcon(this.getClass().getResource("/resouse/missile.png"));
    missile = pine.getImage();
    visible = true;
    this.x = x;
    this.y = y; 
}

public Image getImage()
{
    return missile;
}

public int getX()
{
    return x;
}

public int getY()
{
    return y;
}

public boolean isVisible()
{
    return visible;
}

public void move()
{
    x += missile_sped;
    if(x > width)
        visible = false;
}
}

导入导弹并使其在未直接显示在屏幕上时不可见。

import javax.swing.JFrame;

@SuppressWarnings("serial")
public class Framing extends JFrame
{
public Framing()
{
    add(new Stage());

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(800, 600);
    setLocationRelativeTo(null);
    setTitle("Failing Mini Game");
    setResizable(false);
    setVisible(true);
}
public static void main(String[] args)
{
        new Framing();  
}
}

将所有 class 联系在一起以使其正常工作。

我遇到问题的地方是当我按下 space 按钮开火时。它只是用错误向控制台发送垃圾邮件,如果我正确阅读了 eclipse 回溯,它会在显示的第一个 class 中指向此处:

          SPRITES m = (SPRITES) ms.get(i); //error here

据我所知,这是因为我正在导入一个非扩展或实现的对象。这是我迷失了如何解决这个问题的地方。 我是将这个通用代码区域放在另一个 class 中还是有更聪明的方法来解决这个问题?

我也想知道是否有人知道一个很好的几乎外行的简单调试指南,我还没有听说过任何解释详细但不会在细节上过于麻木的。

您的 class Mussiles 不是 SPRITE。

另外,一个正常的 ArrayList 并不能保证你 return 一个 SPRITE。尝试将它的声明更改为 ArrayList<SPRITE> 以便它只能保存 SPRITE 对象(并相应地更新其他值)这样更安全。

public class Mussiles { ... 这不是 SPRITES 的类型,但您将其添加到 missiles ArrayList

missiles.add(new Mussiles(x + sprite_size, y + sprite_size/2));

这是 ClassCastException 的原因,因为 Mussiles 不可能被视为 SPRITES.

的实例

首先,确保 MussilesSPRITES 扩展,然后将 ArrayList 更新为只允许 SPRITES

类型
private static ArrayList<SPRITES> missiles;

(注意:你应该避免 static 例如 类,它们只会给你带来麻烦)

这也意味着你可以摆脱 @SuppressWarnings("rawtypes"),你真的应该避免,因为编译器试图警告你刚刚 运行 进入的潜在问题......

同时更新您的方法以反映这种限制...

public ArrayList<SPRITES> getMissiles() {
    //...

这也意味着您不需要盲目区分大小写值,因为现在类型将被更严格地定义...

ArrayList<SPRITES> ms = player.getMissiles();

for (int i = 0; i < ms.size(); i++) 
{
    SPRITES m = ms.get(i);

查看 Generics Trail 了解更多详情