【问题标题】:Why does it wants the method to be static?为什么它希望方法是静态的?
【发布时间】:2015-05-23 19:43:01
【问题描述】:

我正在构建我的第一个游戏,严重依赖 Java 网站上的各种教程和指南,但我遇到了一个问题。 在我的游戏引擎中,我想调用Player.update() 方法,但它说它必须是static(不能对非静态方法进行静态引用) 但是,调用它的方法不是static。谁能告诉我为什么它要求它是static?它不需要 Update 中唯一的其他方法是 static

package Main;

import java.awt.*;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

import Graphics.Assets;
import Sprites.Player;

@SuppressWarnings("serial")
public class Game extends JPanel
implements Runnable, KeyListener{

//TEST CODE
private int x = 0;
private int y = 0;
private int dY = 1;
private int dX = 1;

public void moveBall() {
    x = x + dX;
    y = y + dY;

    if(x > WIDTH - 28) {
        dX = -1;
    }
    if(y > HEIGHT) {
        dY = -1;
    }
    if(x < 0) {
        dX = 1;
    }
    if(y < 10) {
        dY = 1;
    }
}

//dimensions
public static final int WIDTH = 400;
public static final int HEIGHT = 300;
public static final int SCALE = 2;

//game thread
private Thread thread;
private boolean running;
private int FPS = 60;
private long targetTime = 1000 / FPS;

//image
private BufferedImage image;
private Graphics2D g;

//Constructor
public Game () {
    super();
    setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
    setFocusable(true);
    requestFocus();
}

public void addNotify() {
    super.addNotify();
    if(thread == null) {
        thread = new Thread(this);
        addKeyListener(this);
        thread.start();
    }
}

private void init () {
    image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

    g = (Graphics2D)image.getGraphics();

    running = true;
    Assets.init();
}

public void run() {

    init();

    long start;
    long elapsed;
    long wait;

    //game loop
    while(running){
    start = System.nanoTime();

    update();
    draw(g);
    drawToScreen();

    elapsed = System.nanoTime() - start;

    wait = targetTime - elapsed / 1000000;
    if(wait < 0) wait= 5;

    try {
        Thread.sleep(wait);
    }
    catch(Exception e) {
        e.printStackTrace();
    }
    }
}

private void update() {
    moveBall();
    Player.update();
}
private void draw(Graphics g2d) {
    super.paint(g2d);
    Graphics2D g = (Graphics2D) g2d;
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    g.drawString("Hello", x, y);
}
private void drawToScreen() {
    Graphics g2 = getGraphics();
    g2.drawImage(image, 0, 0, WIDTH * SCALE, HEIGHT * SCALE, null);
    g2.dispose();
}



public void keyPressed(KeyEvent e){}

public void keyReleased(KeyEvent e){}

public void keyTyped(KeyEvent e){}

}

这是主要代码。现在是 Player 类。

package Sprites;

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import Main.Game;
import Graphics.*;


public class Player extends Creature implements KeyListener{

private int dir;

public Player(Game game, float x, float y) {
    super(game, x, y, Creature.DEFAULT_CREATURE_WIDTH, Creature.DEFAULT_CREATURE_HEIGHT);
    dir = 0;
}

public void update() {
    getInput();
    move();

}

private void getInput() {
    xMove = dir;
}

public void render(Graphics g) {
    g.drawImage(Assets.player, (int) (x), (int) (y), width, height, null);
}

public void keyPressed(KeyEvent e) {

    if(e.getKeyCode()  == KeyEvent.VK_A)
        dir = -1;
    if(e.getKeyCode() == KeyEvent.VK_D)
        dir = 1;
    else dir = 0;
}

public void keyReleased(KeyEvent e) {

    if(e.getKeyCode()  == KeyEvent.VK_A)
        dir = 0;
    if(e.getKeyCode() == KeyEvent.VK_D)
        dir = 0;
}

public void keyTyped(KeyEvent e) {  
}

}

【问题讨论】:

    标签: java methods static


    【解决方案1】:

    看看你的方法调用:

    Player.update();
    

    这就像它是一个静态方法一样调用它 - 在类型上,而不是在类型的 instance 上。 您要更新哪个播放器?您似乎没有它的任何实例...您几乎可以肯定在Game 中创建Player 的实例,并保存对它的引用。

    【讨论】:

      【解决方案2】:

      你已经像这样调用了Playerupdate()方法-

      private void update() {
          moveBall();
          Player.update();
      }  
      

      这里你没有创建Player的对象。所以编译器期望update() 方法是静态的。要解决问题,您可以执行以下任一操作 -

      1. 制作玩家staticupdate()。或者 -
      2. 在调用 Player 类的 update() 方法之前,在 Game 类中创建 Player 的实例/对象作为字段/属性 -

          Player aPlayer = new Player(.....);
          .....
          .....
          ..... 
          private void update(){   
             moveBall();
             aPlayer.update();
         }
      

      【讨论】:

      • 在前面创建一个实例几乎肯定是错误的做法。更有可能应该有一个GamePlayer 实例变量,因此在整个游戏中使用相同的Player 对象。
      • 谢谢。我已经更新了我的帖子,以便在 Game 类中所有操作都可以使用相同的 Player 实例 - aPlayer 完成。
      • 对,这更合理(虽然我自己不会有无意义的a前缀......)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-06
      • 1970-01-01
      • 2013-08-18
      • 2010-09-28
      • 1970-01-01
      • 2012-10-12
      • 2014-01-03
      相关资源
      最近更新 更多