Java屏幕变量为null

时间:2015-04-08 01:50:37

标签: java nullpointerexception

我正在制作Point课程,以便更轻松地制作积分。我希望它在我自己的坐标系统和屏幕的坐标系之间进行转换,但是当我调用方法getWidth时,它表示它为null并给出NullPointerException。这是我的Point类:

import java.awt.Graphics2D;
import java.awt.Image;

public class Point extends GameLoop{
public float X, Y;
private float scale;

public float getScale() {
    return scale;
}

public void setScale(float scale) {
    this.scale = scale;
}

public Point toScreenCoordinates(){
    return new Point(((this.X + scale)/2 * screen.getWidth()), ((this.Y + scale)/2 * screen.getHeight()));
}

public void drawImageHere(Image i, Graphics2D g){
    Point p = this.toScreenCoordinates();
    g.drawImage(i, Math.round(p.X) - i.getWidth(null)/2, (Math.round(p.Y) - i.getHeight(null))/2, null);
}

public Point(float x, float y){
    X = x;
    Y = y;
    scale = 1;
}

public void update(long timePassed) {

}

public void draw(Graphics2D g) {

}
}

这是我的GameLoop类,其中包含屏幕对象:

import java.awt.Color;
import java.awt.DisplayMode;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Window;

public abstract class GameLoop {

private static DisplayMode[] modes = {
    new DisplayMode(800, 600, 32, 0),
    new DisplayMode(800, 600, 24, 0),
    new DisplayMode(800, 600, 16, 0),
    new DisplayMode(640, 480, 32, 0),
    new DisplayMode(640, 480, 24, 0),
    new DisplayMode(640, 480, 16, 0)
};

private boolean running;
public Animation a;
public int fps;

public ScreenManager screen;

public void stopAll(){
    running = false;
}

public void run(){
    try{
        init();
        gameLoop();
    }finally{
        screen.restoreScreen();
    }
}

public void gameLoop(){
    long startTime = System.currentTimeMillis();
    long cumTime = startTime;

    while(running){
        long timePassed = System.currentTimeMillis() - cumTime;
        cumTime += timePassed;

        update(timePassed);

        Graphics2D g = screen.getGraphics();
        draw(g);
        g.dispose();
        screen.update();
        a.update(timePassed);

        try{
            Thread.sleep((1000 + (fps - (1000 % fps)))/fps);
        }catch(Exception ex){}
    }
}

public void init(){
    fps = 60;
    a = new Animation();
    screen = new ScreenManager();
    DisplayMode dm = screen.findFirstCompatibleMode(modes);
    screen.setFullScreen(dm);

    Window w = screen.getFullScreenWindow();
    w.setFont(new Font("Times New Roman", Font.PLAIN, 30));
    w.setBackground(Color.YELLOW);
    w.setForeground(Color.BLACK);
    running = true;
}

public abstract void update(long timePassed);
public abstract void draw(Graphics2D g);


}

这是我的ScreenManager类,它是我的屏幕变量是以下对象的类:

import java.awt.DisplayMode;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Window;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;

public class ScreenManager {

private GraphicsDevice vc;

public ScreenManager(){
    GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
    vc = e.getDefaultScreenDevice();
}

public DisplayMode[] getCompatibleDisplayModes(){
    return vc.getDisplayModes();
}

public DisplayMode findFirstCompatibleMode(DisplayMode[] modes){
    DisplayMode goodModes[] = vc.getDisplayModes();
    for(int x = 0;x<modes.length;x++){
        for(int y = 0;y<goodModes.length;y++){
            if(displayModesMatch(modes[x], goodModes[y])){
                return modes[x];
            }
        }
    }
    return null;
}

public boolean displayModesMatch(DisplayMode m1, DisplayMode m2){
    if(m1.getWidth() != m2.getWidth() || m1.getHeight() != m2.getHeight()){
        return false;
    }
    if(m1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m1.getBitDepth() != m2.getBitDepth()){
        return false;
    }
    if(m1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN &&         m2.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && m1.getRefreshRate() != m2.getRefreshRate()){
        return false;
    }
    return true;
}

public DisplayMode getCurrentDisplayMode(){
    return vc.getDisplayMode();
}

public void setFullScreen(DisplayMode dm){
    JFrame f = new JFrame();
    f.setUndecorated(true);
    f.setResizable(false);
    f.setIgnoreRepaint(true);
    vc.setFullScreenWindow(f);

    if(dm != null && vc.isDisplayChangeSupported()){
        try{
            vc.setDisplayMode(dm);
        }catch(Exception ex){}
    }

    f.createBufferStrategy(2);
}

public Graphics2D getGraphics(){
    Window w = vc.getFullScreenWindow();
    if(w != null){
        BufferStrategy s = w.getBufferStrategy();
        return (Graphics2D)s.getDrawGraphics();
    }else{
        return null;
    }
}

public void update(){
    Window w = vc.getFullScreenWindow();
    if(w != null){
        BufferStrategy s = w.getBufferStrategy();
        if(!s.contentsLost()){
            s.show();
        }
    }
}

public Window getFullScreenWindow(){
    return vc.getFullScreenWindow();
}

public int getWidth(){
    Window w = vc.getFullScreenWindow();
    if(w != null){
        return w.getWidth();
    }else{
        return 0;
    }
}

public int getHeight(){
    Window w = vc.getFullScreenWindow();
    if(w != null){
        return w.getHeight();
    }else{
        return 0;
    }
}

public void restoreScreen(){
    Window w = vc.getFullScreenWindow();
    if(w != null){
        w.dispose();
    }
    vc.setFullScreenWindow(null);
}

public BufferedImage createCompatibleImage(int w, int h, int t){
    Window win = vc.getFullScreenWindow();
    if(win != null){
        GraphicsConfiguration gc = win.getGraphicsConfiguration();
        return gc.createCompatibleImage(w, h, t);
    }else{
        return null;
    }
}

}

1 个答案:

答案 0 :(得分:0)

您只是在GameLoop的init方法中初始化屏幕字段,而且只能从run方法调用。

构建Point时,它会创建自己的屏幕字段,因为它是GameLoop的子类。所以它没有使用你可能拥有的GameLoop类的屏幕字段。

你实际上并不需要Point扩展GameLoop。但是如果你这样做,你必须在构造函数中初始化Point的本地版本的屏幕。