【问题标题】:Painting in multiple classes多班绘画
【发布时间】:2016-06-24 20:22:05
【问题描述】:

我不太擅长在 java 中使用多个类,因为我一直发现在 1 个类中完成所有代码更容易。最近我发现我正在制作的游戏需要使用第二个类,但我遇到了一个错误。

现在我只是想在用户点击的地方和时间生成敌人。

主类-

package joey.rts;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class RTSMain extends JFrame implements MouseListener{
    /**
     * 
     */
    private static final long serialVersionUID = -7122370886923000314L;
    public static BufferedImage menu,enemy;
    public static boolean onmenu,oneenemy;
    public static void main(String[] args){
        new RTSMain();
    }
    public RTSMain(){
        init();
    }
    public void init(){
        setSize(1700,1100);
        setVisible(true);
        setLocationRelativeTo(null);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("RTS");
        addMouseListener(this);
    }
    public void paint(Graphics g){
        Graphics2D g2 = (Graphics2D) g;
        if(onmenu == true){
            g2.drawImage(menu,0,0,this);
        }
    }
    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub

    }
    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }
    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }
    @Override
    public void mousePressed(MouseEvent e) {
        Enemy enemy = new Enemy();
        int x = e.getX();
        int y = e.getY();
        enemy.spawnEnemy(x, y);

    }
    @Override
    public void mouseReleased(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }
}

敌人等级 -

   package joey.rts;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

public class Enemy{
    /**
     * 
     */
    public static BufferedImage enemy;
    private static final long serialVersionUID = 7898827977636314494L;
    public static RTSMain rts;
    public static void main(String[] args){
        try{
            enemy = ImageIO.read(new File(javax.swing.filechooser.FileSystemView.getFileSystemView().getHomeDirectory() + "\\enemy.png"));
        } catch (Exception e){
            e.printStackTrace();
        }

    }
    public static void spawnEnemy(int x, int y){
        Graphics g = rts.getGraphics();
        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(enemy,x,y,null);
    }
}

【问题讨论】:

  • 那么你的问题是什么?你说的这个错误在哪里?
  • 但我确实看到了 OO 问题。为什么Enemy 扩展RTSMain?如果有的话,我认为RTSMain 应该包含Enemy 的集合,并在绘制它们时对其进行迭代。而spawnEnemy() 应该只生成一个Enemy 的实例,将它添加到Enemy 集合中,它会在下次通过绘制循环绘制(我假设你正在使用游戏循环)。正是我注意到的,但您遇到的错误是什么?
  • 您的主要问题是缺少super.paint(...) 作为第一个。 public void paint(Graphics g){里面的代码行,那么当前的绘画将被重置
  • mousePressed(MouseEvent e) { 必须包含repaint()

标签: java swing class paint mouselistener


【解决方案1】:

在您的 Main 类中,将 mouseClicked 函数更新为:

@Override
    public void mouseClicked(MouseEvent e) {
        Enemy enemy = new Enemy();
        int x=e.getX(); // get mouse positionX
        int y=e.getY();//get mouse positionY
        enemy.spawnEnemy(x,y);//spawn Enemy
    }

如果您以后需要重新使用它,请考虑保存敌人的对象。 我也认为没有必要在 Enemy Class 中扩展任何东西。

我已经更新了你的 Main 和 Enemy 类:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
public class Main extends JFrame implements MouseListener{
    /**
     * 
     */
    private static final long serialVersionUID = -7122370886923000314L;
    public static BufferedImage menu,enemy;
    public static boolean onmenu,oneenemy;
    public static void main(String[] args){
        new Main().setVisible(true);
    }
    public Main(){
        init();
    }
    public void init(){
        setSize(1700,1100);
        setVisible(true);
        setLocationRelativeTo(null);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("RTS");
        addMouseListener(this);
    }

    @Override
    public void paint(Graphics g){
        Graphics2D g2 = (Graphics2D) g;
        if(onmenu == true){
            g2.drawImage(menu,0,0,this);
        }
    }
    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub

    }
    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }
    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }
    @Override
    public void mousePressed(MouseEvent e) {
        Enemy enemy = new Enemy();
        int x = e.getX();
        int y = e.getY();
        enemy.spawnEnemy(x, y,this.getGraphics());

    }
    @Override
    public void mouseReleased(MouseEvent arg0) {
        // TODO Auto-generated method stub
    }
}

这是 Enemy 类:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

public class Enemy{

    public static BufferedImage enemy;
    private static final long serialVersionUID = 7898827977636314494L;
    public Enemy(){
        try {
            //MAKE SURE THAT THIS IS THE CORRECT IMAGE PATH
        enemy = ImageIO.read(new File(javax.swing.filechooser.FileSystemView.getFileSystemView().getHomeDirectory() + "\\enemy.png"));
        } catch (IOException ex) {
            Logger.getLogger(Enemy.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public void spawnEnemy(int x, int y,Graphics g){
        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(enemy,x,y,null);
    }
}

我已经删除了 Enemy 类中 Main 的实例变量。

我已经删除了 spawnEnemy 函数的静态修饰符。

我已将图形对象作为属性发送给 spawnEnemy 函数。

我已将 Enemy 类的 main 方法中的代码移至 Enemy 构造函数。

希望对你有帮助!

【讨论】:

  • 这取决于游戏中需要的行为,他无论如何都要求用户点击动作:)
  • 我这样做了,它只是不断地打开新的 JFrames。所以我删除了 Enemy 类中的扩展 RTSMain,并将缓冲的图像移动到了敌人类。还是一样的错误。 (更新上面的代码一秒)
  • 你在给你的Enemymain() 上课吗?如果不是,它永远不会为敌人读取图像。不过,我认为您的Enemy 类不需要main,除非它用于单元测试。将其更改为构造函数或init() 方法。但是,只要确保每个敌人都调用它。我会重新设计这个游戏,但这应该能让你工作。
  • Ahmed Amr,我遇到了和以前一样的错误。
  • 我已经在我的机器上尝试过它并且它正在工作,可能你收到错误是因为敌人.png 路径不正确。尝试将图像的直接路径放在代码中并再次检查。如果它没有解决问题,请在此处粘贴错误。
【解决方案2】:

粘贴答案似乎比尝试在评论中解释更容易。你的 OO 有点不对劲。将此添加到您的 RTSMain 课程中:

protected ArrayList<Enemy> enemies = new ArrayList<Enemy>();
protected BufferedImage enemyImage = null;
...
public void init() {
    ...
    // everything you already have...
    enemyImage = //read in your enemy image here
    ...
}
...

@Override
public void mouseClicked(MouseEvent e) {
    // this takes place of Enemy.spawn(), get rid of it
    int x = e.getX(); // get mouse positionX
    int y = e.getY(); //get mouse positionY
    Enemy enemy = new Enemy( enemyImage, x, y );
    Enemies.add( enemy );
    // Iterate over list above to draw each enemy in your paintComponent method
}

此外,JFrame 没有 paintComponent() 方法,您需要重写该方法才能进行绘画(paint() 已弃用)。添加一个JPanel,覆盖它的paintComponent() 等等。对于一款游戏,您可能希望创建一个游戏循环来进行绘画,除非它非常基于回合制。

编码愉快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多