有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在屏幕上移动/动画单个子类对象而不移动其他子类?

在Java的最后一个作业中,我必须对一些“怪物”进行建模,并使其中一个在屏幕上移动。为此,我需要使用已经实现的计时器,(timer = new Timer (50, monsterPanel)使子类'MovingMonster'(父类'Monster')的X坐标移动到屏幕的右侧。同时,其他的子类,目前只有“SeeingMonster"不在屏幕上移动

我的猜测是必须更改MovingMonster的void draw(Graphics g)方法中的x坐标,但我不确定如何将其链接到class MonsterPanel中的public void actionPerformed (ActionEvent e),如果它应该在同一个侦听器中

任何帮助都将不胜感激。下面是项目的完整代码,可以在任何IDE中运行

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

class MonsterMania {
    MonsterPanel monsterPanel = new MonsterPanel();
    Timer timer;

    void createGUI() {
        // create the GUI on the event thread.
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                final JFrame frame = new JFrame("Monster Mania");
                frame.add(monsterPanel, BorderLayout.CENTER);
                frame.setSize( 600, 400 );
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);

                monsterPanel.setBackground( Color.DARK_GRAY );
                monsterPanel.addMonsters();

                timer = new Timer( 50, monsterPanel);
                timer.start();
            }
        });
    }

    public static void main( String[] a ) {
        new MonsterMania().createGUI();
    }
}

class MonsterPanel extends JPanel implements ActionListener {
    ArrayList<Monster> monsters = new ArrayList<Monster>();  // the list of monsters on the screen

    void addMonsters() {
        monsters.add( new Monster( 50, 40 ));
        monsters.add( new Monster (150, 200 ));
        monsters.add( new Monster (300, 300 ));
        monsters.add (new SeeingMonster (150, 50, Color.GREEN));
        monsters.add (new MovingMonster (400, 150));
    }

    public void paintComponent( Graphics g ) {
        super.paintComponent( g );
        for (Monster monster : monsters) {
            monster.draw( g );
        }
    }

    public void actionPerformed( ActionEvent e ) {
        for (Monster monster : monsters) {
            monster.step( this );
        }

        repaint();
    }  
}

class Monster {
    int size = 50;
    int arcSize = 10;  // size of arc that defines roundedness of rounded rectangle
    int locx = 0; // x coordinate center (pixel coordinates)
    int locy = 0; // y coordinate center (pixel coordinates)
    Color fill = Color.YELLOW;  // inner color
    Color line = Color.BLACK;   // color of border
    int phase = 0; // phase in the animation, a counter of time steps

    Monster( int x, int y ) {
        locx = x;
        locy = y;
    }

    // update the monster because a time step has passed
    // the parameter monsterPanel can be used for getting information about the panel, e.g., the size
    void step( MonsterPanel monsterPanel ) {
        phase++;
    }

    void draw( Graphics g ) {
        // draw body
        g.setColor( fill );
        g.fillRoundRect( locx - size/2, locy - size/2, size, size, arcSize, arcSize );
        g.setColor( line );
        g.drawRoundRect( locx - size/2, locy -size/2, size, size, arcSize, arcSize );
        // draw mouth
        // every 5 time steps, mouth is changed
        if ( phase % 20 < 10 ) {
            int s = size/5; // size of closed mouth
            g.drawOval( locx - s/2, locy + size/6, s, s );
        } else {
            int s = size/3; // size of open mouth
            g.fillOval( locx - s/2, locy + size/6, size/3, size/3 );
        }
    }
}

class SeeingMonster extends Monster{
  Color eyecolor;


  public SeeingMonster ( int x, int y , Color color){
    super( x, y);
    locx = x;
    locy = y;
    eyecolor = color;
  }

  void draw( Graphics g ) {
    super.draw(g);
    int s = size/7;
    g.setColor(eyecolor);
    g.fillOval ( locx + 10, locy - 15 , size/5, size/5 );
    g.fillOval ( locx + -15 , locy - 15 , size/5, size/5 );
}
}

class MovingMonster extends Monster{


  MovingMonster( int x, int y){
    super(x,y);
    locx = x;
    locy = y;
  }
  public int getLocationX() {
    return locx;
  }




  void draw (Graphics g ) {
    super.draw(g);




  }
}

共 (1) 个答案

  1. # 1 楼答案

    另一种方法是重写step类中的方法SeeingMonster,让它什么都不做

    class SeeingMonster {
        @Override
        void step( MonsterPanel monsterPanel ) {}
    }
    

    更好的方法是使用方法step创建一个接口Movable

    public interface Movable {
        void step(MonsterPanel monsterPanel);
    }
    

    现在你可以在你的MovingMonster类中实现这个接口,现在你可以在这里实现这个方法了

    class MovingMonster extends Monster implements Movable {
        @Override
        void step( MonsterPanel monsterPanel ) {
            ++phase;
        }
    }
    

    现在,您可以仅为Movable的实例保留一个单独的List

    List<Movable> monsters = new ArrayList<Movable>();
    

    你可以创建一个单独的函数来获取一个怪物作为参数,如果怪物真的实现了接口,那么你可以将这个怪物添加到单独的List

    private List<Movable> movables = new ArrayList<Movable>();
    private List<Monster> monsters = new ArrayList<Monster>();
    private void add(Monster monster) {
        monsters.add(monster);
        if (monster instanceof Movable) {
            movables.add((Movable)monster);
        }
    }
    

    现在你可以让你的addMonster方法看起来像这样

    void addMonsters() {
        add( new Monster( 50, 40 ));
        add( new Monster (150, 200 ));
        add( new Monster (300, 300 ));
        add (new SeeingMonster (150, 50, Color.GREEN));
        add (new MovingMonster (400, 150));
    }
    

    最后,你的actionsPerformed方法只能在Movable实例上循环,这些实例实际上是Monster可以移动的

    public void actionPerformed( ActionEvent e ) {
        for (Movable movable : movables) {
            movable.step(this);
        }
        repaint();
    }