【问题标题】:How do you call the methods of a class instance that was created in another class, from another class?如何从另一个类调用在另一个类中创建的类实例的方法?
【发布时间】:2015-04-24 01:34:50
【问题描述】:

我正在尝试在 Java Swing GUI 中为我的突围游戏创建一些动画游戏文本。

预期行为:每次击中砖块时,它的点都会撞击屏幕,暂停 0.25 秒,然后消失。

我做了什么: 在一个名为AlertText 的类的方法中使用了一个计时器。当GameLogic 类中的砖块被击中时,会创建一个新的AlertText,并且它的计时器开始运行。现在在游戏类中,我有了绘画类。

问题:那么我如何调用在GameLogic 中创建的AlertText 的特定实例以使用setter 和getter 方法在@987654327 中设置我的g.drawString @ 班级。我觉得这应该是一种常见的技术?有名字吗?

我让它与全局变量一起用于一种风格的砖块,所以我知道动画正在工作,但我需要 100 多个全局变量来制作每种砖块。


游戏类

public class Game extends JPanel   
 {
 public static final int HEIGHT = 720;
 public static final int WIDTH = 600;
 public Color color;

private GameLogic gl = new GameLogic();
private KeyboardController  controller;
public Paddle player = new Paddle(110, HEIGHT-30, 100, 10, 10, color.black, controller);
public Ball gameBall = new Ball(300, 300, 15,  color.black);
private boolean PaddleUpdateComplete = false;

private List<AlertText> activeAlerts = new ArrayList<AlertText>();
Game game = new Game();



public void spawnNewAlert(Brick b){
    AlertText alert = new AlertText();
    alert.setxPos(b.getXPosition());
    alert.setyPos(b.getYPosition());
    alert.setText(b.getPoints()+"");
    alert.setColor(b.getColor());
    activeAlerts.add(alert);
    alert.fireText();
}    

@Override
public void paint(Graphics g)
{
     g.clearRect(0, 0, WIDTH, HEIGHT);
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, WIDTH, HEIGHT);


    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, (int)AlertText.staticAlertSize));
    g.setColor(new Color(AlertText.staticRed, AlertText.staticGreen, AlertText.staticBlue));
    g.drawString(AlertText.staticAlertOne, AlertText.staticAlertXPos, AlertText.staticAlertYPos);

    player.draw((Graphics2D)g);
    gameBall.draw((Graphics2D)g);
    gl.drawBricks(g);
    // Draw GameObjects and anything else here
    g.setFont(scoreFont);
    g.drawString("Score: " + player.getScore(), 10, 25);
    g.drawString("LIVES: " + player.getLives(), 150, 25);
    if(gl.gameOver(player) &&
            gameBall.getYPosition() >= HEIGHT){
        g.setColor(Color.black);
        g.setFont(endFont);
        g.drawString("Game Over!  Score: " + player.getScore(), (WIDTH/2) - 85, (HEIGHT/2));
    }
    if(gl.empty()){
        g.setColor(Color.black);
        g.setFont(endFont);
        g.drawString("You won!  Score: " + player.getScore(), (WIDTH/2) - 85, (HEIGHT/2));
        timer.stop();
    }
    if(PowerUps.isMegaPaddle){
    g.setColor(Color.orange);
    g.setFont(TimeFont);
    g.drawString(PowerUps.megaPaddlecount+"", 300, 500);
    }
    if(PowerUps.isMegaBall){
     g.setColor(Color.red);
     g.setFont(TimeFont);
     g.drawString(PowerUps.megaBallcount+"", 250, 400);   
    }
    if(!game.activeAlerts.isEmpty()){

        for(AlertText alert: game.activeAlerts){
        g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, alert.getTextSize()));
        g.setColor(alert.getColor());
        g.drawString(alert.getText(), alert.getxPos(), alert.getxPos());
        if(alert.count<=0){
         game.activeAlerts.remove(alert);
        }
     }

    } 
}

public void updateGameState()
{
    gameBall.move();
    player.move(controller);
    gl.checkCollisions(gameBall, player, timer, WIDTH, HEIGHT, game);
    gl.removeBrick();
    // Move GameObjects and check for collisions here
    if(Paddle.paddleHits==1 && !PaddleUpdateComplete){
        gameBall.setXVelocity(10);
        gameBall.setYVelocity(gameBall.getYVelocity()-6);
        PaddleUpdateComplete = true;
    }


}

public final void setupGame()
{
    gameBall.setXVelocity(0);
    gameBall.setYVelocity(-10);
    player.setLives(5);
    gl.makeBricks();
    // Instantiate instance variables here




}

// Constructor method should not be modified
public Game()
{
    // Set the size of the Panel to the correct size
    this.setPreferredSize(new Dimension(WIDTH, HEIGHT));

    // Set the background color of the Panel to black
    this.setBackground(Color.BLACK);

    // Instantiate a KeyboardController and listen for input with it
    controller = new KeyboardController(); 
    this.addKeyListener(controller);

    // Call the setupGame method to initialize instance variables
    this.setupGame();

    // Get focus in the window
    this.setFocusable(true);
    this.requestFocusInWindow();
}

// Start method should not be modified
public void start()
{
    // Set up a new Timer to repeat every 20 milliseconds (50 FPS)
    timer = new Timer(20, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) 
        {
            repaint();
            updateGameState();
        }
    });

    timer.setRepeats(true);
    timer.start();
}

Timer timer; 
}

警报类方法fireText()

public void fireText(){ 
  count = 50;
  textSize=0;
  Firing=true;
  Timer time = new Timer(50, null);
    time.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        if(count>47){
            textSize+=10;
            xPos-=2;
            count--;
        }
        else if(count>42){
            count--;
        }
        else {
        yPos -= 1;
        xPos += 1;
        textSize -= 1;
        count--;
        if(count<=0) {
            text ="";
            count=-1;
            Firing =false;
            time.stop();     
        }
        }

  }
  });
    time.start();      
 }

游戏逻辑方法

public void checkCollisions(Ball ball, Paddle player, Timer time, int WIDTH, int HEIGHT, Game game) {
    if(hitPaddle(ball, player)){
        ball.setYVelocity(ball.getYVelocity() * -1);
        Paddle.paddleHits++;
        return;
    }
    //check if ball hit any walls
    if(ball.getXPosition() >= (WIDTH - ball.getDiameter()) || ball.getXPosition() <= 0){
        ball.setXVelocity(ball.getXVelocity() * -1);
    }
    if(ball.getYPosition() > (player.getYPosition() + player.getHeight() + 10)){
        resetBall(ball, player, time, WIDTH, HEIGHT);
    }
    if(ball.getYPosition() <= 0){
        ball.setYVelocity(ball.getYVelocity() * -1);
    }

    //handle collisions between bricks
    int brickRowsActive = 0;
    for(ArrayList<Brick> alb : bricks){
        if(alb.size() == horizontalCount){
            ++brickRowsActive;
        }
    }

    for(int i = (brickRowsActive==0) ? 0 : (brickRowsActive - 1); i < bricks.size(); ++i){
        for(Brick b : bricks.get(i)){ 
            if(brickHitByBall(ball, b)){
                checkPowerUps(b, player, ball);
                game.spawnNewAlert(b);
                player.setScore(player.getScore() + b.getPoints());
                b.decrementType();
            }
        }
    }
}

【问题讨论】:

  • 你能显示一些相关的代码吗?
  • Swing 还是 Android?不能两者兼有。

标签: java swing class methods


【解决方案1】:

您可能希望在完成渲染的Game 类中列出警报列表,并且希望能够在处理所有游戏玩法的GameLogic 类中添加到该列表。

有很多方法可以做到这一点。假设您在 GameLogic 中引用了 Game 类,然后将 spawnNewAlert() 的代码移动到 Game。那么GameLogic中的代码可以调用game.spawnNewAlert(b),然后交给Game类来管理。

您需要在Game 类中添加一些内容:

  1. 新成员字段private List&lt;AlertText&gt; activeAlerts = new ArrayList&lt;AlertText&gt;();
  2. spawnNewAlert() 中,就在您触发Text() 之前,将警报添加到activeAlerts
  3. paint() 中,循环遍历activeAlerts 并绘制每一个,删除任何不再有效的内容(注意删除方式,使用Iterator 或将删除推迟到迭代之后以防止ConcurrentModificationException.)

【讨论】:

  • 这是一个好主意,我会尝试的,我对一件事有点困惑——paint() 如何访问我要添加的同一个 activeAlert?为了在 GameLogic 中调用 game.spawnNewAlert(b),我是否必须在 GameLogic 中制作新游戏?哪个将有自己单独的 activeAlerts 列表,远离paint() 可以访问的内容? - 我想我在这里的职业机制的一些细节上搞错了?
  • 我假设GameLogic 引用了它正在执行逻辑的Game。如果没有,您可以在创建时传递一个,并将其存储在成员变量中。
  • 啊,所以我可以将 Game 游戏添加到 GameLogic 构造函数中,我想我明白了
  • 在 Class2 中有一个 Class1 class1 是不是很奇怪,而反之亦然?似乎可能会发生某种无限循环,我不得不在我的脑海中把它翻过来
  • 我遇到了 stackOverflow 错误,我将更新代码
【解决方案2】:

据我了解,您希望通过另一个对象触发一个对象中的方法,而另一个对象都被包裹在第三个上层对象中,对吧?

我将在 Game 对象中创建 AlertText 和 GameLogic 对象,然后将 AlertText 的引用传递给 GameLogic,从而使 GameLogic 可以触发 AletText 的 fireText() 方法。您必须从 spawnNewAlert 方法中删除 AlertText 的实例化(实际上您只需要一个 AlertText 实例),并在每次运行后重新设计 fireText 方法以重置。

在 GameLogic 中:

AlertText alert;

public GameLogic(AlertText alert //other parameters) {
  this.alert = alert;
  //other stuff you do here
}

在游戏中假设:

GameLogic gameLogic;
AlertText alertText;

public Game() {
  alertText = new AlertText();
  gameLogic = new GameLogic(alertText);
}

public void paint(Graphics g) {
  gameLogic.spawnNewAlert(brick);
}

【讨论】:

    猜你喜欢
    • 2020-10-16
    • 1970-01-01
    • 2015-06-10
    • 2016-08-25
    • 2018-11-02
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 2018-02-27
    相关资源
    最近更新 更多