如何从另一个类调用在另一个类中创建的类实例的方法?

时间:2015-04-24 01:34:51

标签: java swing class methods

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

预期的行为:每当一块砖被击中时,它的点将猛击到屏幕上,暂停0.25秒然后逐渐消失。

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

问题:那么如何调用在AlertText中创建的GameLogic的特定实例来使用setter和getter方法来设置g.drawStringGame类中的paint中。我觉得这应该是一种常见的技巧?它有名字吗?

我使用全局变量处理一种砖的风格,所以我知道动画是有效的,但是我需要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();      
 }

GameLogic方法

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

2 个答案:

答案 0 :(得分:0)

据我所知,你想要在另一个对象中触发一个方法,而另一个对象都被包裹在第三层,上层一层,对吧?

我会在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);
}

答案 1 :(得分:0)

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

有很多方法可以做到这一点。假设您在Game中引用了GameLogic课程,请将spawnNewAlert()的代码移至Game。然后,GameLogic中的代码可以调用game.spawnNewAlert(b),然后将其留给Game类进行管理。

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

  1. 新成员字段private List<AlertText> activeAlerts = new ArrayList<AlertText>();
  2. 在fireText()之前的spawnNewAlert()
  3. ,将警报添加到activeAlerts
  4. paint()中,循环浏览activeAlerts并绘制每一个,删除任何不再有效的内容(请注意删除方法,使用Iterator或将删除延迟到在迭代之后阻止ConcurrentModificationException。)