简体   繁体   中英

How do you call the methods of a class instance that was created in another class, from another class?

I am trying to create some animated game play text for my breakout game in Java Swing GUI.

Expected behavior: Everytime a brick is hit its points will Slam onto the screen, pause for 0.25 seconds and then fade up into nothing.

What I have done: A timer is used inside a method inside a class called AlertText . When the brick is hit in the class GameLogic , a new AlertText is created and its timers start running. Now in the Game Class I have the paint class.

Question: So how do I call upon the specific instances of AlertText that were created in GameLogic to use the setter and getter methods to set my g.drawString in paint in Game class. I feel like this should be a common technique? Is there a name for it?

I got it to work with Global variables for one style of brick so I know animation is working, but I would need 100+ global variables to do every kind of brick.


Game Class

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; 
}

Alert Class method 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();      
 }

GameLogic method

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();
            }
        }
    }
}

As far as I understand you want to trigger a method in one object by another object both being wrapped up in the third, upper level one, right?

I would create both AlertText and GameLogic objects in the Game object and then pass the reference of the AlertText to the GameLogic, thus making it possible to the GameLogic to trigger the AletText's fireText() method. You would have to remove the instantiation of the AlertText from the spawnNewAlert method (in fact you need only one instance of AlertText), and rework a little bit the fireText method to reset after every run.

In GameLogic:

AlertText alert;

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

In Game let's say:

GameLogic gameLogic;
AlertText alertText;

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

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

Probably you want a list of alerts in your Game class where the rendering is done, and you want to be able to add to that list in your GameLogic class where you handle all the gameplay.

There are a number of ways to do this. Assuming you have a reference to your Game class in your GameLogic then move the code for spawnNewAlert() into Game . Then your code in GameLogic can call game.spawnNewAlert(b) and then leave it to the Game class to manage.

You will need to add a few things to your Game class:

  1. a new member field private List<AlertText> activeAlerts = new ArrayList<AlertText>();
  2. in spawnNewAlert() just before you fireText(), add the alert to activeAlerts
  3. in paint() , loop through activeAlerts and draw each one, remove any that are no longer valid (be careful about how you remove, either use an Iterator or defer the removes to after the iteration to prevent a ConcurrentModificationException .)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM