每次在不同地方的背景图片

时间:2016-02-26 07:29:11

标签: java

我有一个大型程序,我将发布一些类,希望你们可以找到问题。基本上,有时当我开始它时,它创建游戏就好了,而其他背景是向北和向西方向上几个像素,留下非常难看的空白。我似乎无法找到缺少的代码来决定它是否会这样做。说实话,我的机器上有某种渲染故障。无论如何,我已经将后台getXgetY方法用于调试,并注意到背景是否完全拉伸到屏幕(它是自定义背景,因此像素高度和宽度完全匹配),或者它的向上和向左,背景仍然显示它显示在(0,0)。我将把所有方法从主线程发布到菜单中创建背景。我将留下注释,指出通过此代码获取创建背景所需的路径。感谢您的帮助,我会定期登记进行编辑和更多信息。

编辑:添加了background.java EDIT2:添加解释问题的图片

Menu.java *忽略FileIO代码,主要是创建一个新的GamePanel()

    public class Menu {

    private static File file;

    public static void main(String[] args) throws IOException {
        file = new File("saves.txt");
        if(file.exists()){
            FileIO.run();
            FileIO.profileChoose();
        }
        else{
            FileIO.profileCreate();
            FileIO.run();
        }

        JFrame window = new JFrame("Jolly Jackpot Land");
        window.setContentPane(new GamePanel());
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setResizable(false);
        window.pack();
        window.setLocationRelativeTo(null);
        window.setVisible(true);
    }
}

接下来是GamePanel.java

    public class GamePanel extends JPanel implements Runnable, KeyListener {
    // ID
    private static final long serialVersionUID = 1L;

    // Dimensions
    public static final int WIDTH = 320;
    public static final int HEIGHT = 240;
    public static final int SCALE = 2;

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

    // Image
    private BufferedImage image;
    private Graphics2D g;

    // Game State Manager
    private GameStateManager gsm;

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

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    }

    private void init() {
        image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        g = (Graphics2D) image.getGraphics();
        running = true;

        gsm = new GameStateManager();
    }

    @Override
    public void run() {
        init();

        long start;
        long elapsed;
        long wait;

        // Game Loop
        while (running) {
            start = System.nanoTime();
            update();
            draw();
            drawToScreen();

            elapsed = System.nanoTime() - start;
            wait = targetTime - (elapsed / 1000000);

            if (wait < 0) {
                wait = 5;
            }

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

    private void update() {
        gsm.update();
    }

    private void draw() {
        gsm.draw(g);
    }

    private void drawToScreen() {
        Graphics g2 = getGraphics();
        g2.drawImage(image, 0, 0, WIDTH * SCALE, HEIGHT * SCALE, null);
        g2.dispose();
    }

    @Override
    public void keyPressed(KeyEvent k) {
        gsm.keyPressed(k.getKeyCode());
    }

    @Override
    public void keyReleased(KeyEvent k) {
    }

    @Override
    public void keyTyped(KeyEvent arg0) {
    }
}

这要求在GameStateManager方法中创建一个新的init()对象,其类就在这里。

GameStateManager.java

public class GameStateManager {


    private ArrayList<GameState> gameStates;
    private int currentState;

    public static final int MENUSTATE = 0;
    public static final int SLOTGAMESTATE = 1;
    public static final int DICEGAMESTATE = 2;
    public static final int ROULETTEGAMESTATE = 3;
    public static final int LEADERBOARDSTATE = 4;
    public static final int SETTINGSSTATE = 5;
    public static final int HELPSTATE = 6;


    public GameStateManager() {
        gameStates = new ArrayList<GameState>();

        currentState = 0;
        gameStates.add(new MenuState(this));
        gameStates.add(new SlotGameState(this));
        gameStates.add(new DiceGameState(this));
        gameStates.add(new RouletteGameState(this));
        gameStates.add(new LeaderboardState(this));
        gameStates.add(new SettingsState(this));
        gameStates.add(new HelpState(this));


    }

    public void setState(int state){
        currentState = state;
        gameStates.get(currentState).init();
        currentState = 0;
    }

    public int getState() {
        return currentState;
    }

    public void update() {
        gameStates.get(currentState).init();
    }

    public void draw(java.awt.Graphics2D g){
        gameStates.get(currentState).draw(g);
    }

    public void keyPressed(int k){
        gameStates.get(currentState).keyPressed(k);
    }

    public void keyReleased(int k) {
        gameStates.get(currentState).keyReleased(k);
    }
}

GameState是一个抽象类,所以它不值得发布,它只包含init()draw()等。下一个类是最后一个和最后一个类,因为它被调用,因为GameStateManangerMENUSTATE或0开始,当初始化GSM时,它会初始化其当前状态,从而将我们带到课程MenuState

MenuState.java

public class MenuState extends GameState {

    private Background bg;

    public FontMetrics fontMetrics;

    private int choice = 0;
    private String[] options = { "Slot Machine", "Dice Toss", "Roulette Wheel", "Leaderboards", "Settings", "Help",
            "Quit" };

    private Color titleColor;
    private Font titleFont;

    private Font font;

    public MenuState(GameStateManager gsm) {
        this.gsm = gsm;
        try {
            bg = new Background("/Backgrounds/happybg.png");

            titleColor = Color.WHITE;
            titleFont = new Font("Georgia", Font.PLAIN, 28);
        } catch (Exception e) {
            e.printStackTrace();
        }

        font = new Font("Arial", Font.PLAIN, 12);
    }

    @Override
    public void init() {
    }

    @Override
    public void update() {
    }

    @Override
    public void draw(Graphics2D g) {
        Canvas c = new Canvas();
        fontMetrics = c.getFontMetrics(font);
        // Draw BG
        bg.draw(g);

        // Draw title
        g.setColor(titleColor);
        g.setFont(titleFont);
        String title = "Jolly Jackpot Land!";
        g.drawString(title, 36, 60);

        g.setFont(font);

        for (int i = 0; i < options.length; i++) {
            if (i == choice)
                g.setColor(Color.RED);
            else
                g.setColor(Color.WHITE);
            g.drawString(options[i], 30, 120 + i * 15);
        }
        g.setColor(Color.WHITE);
        g.setFont(new Font("Arial", Font.PLAIN, 10));
        g.drawString("v1.1", 165, 235);

        Object[] a = { ("Name: " + Player.getName()), ("Gil: " + Player.getGil()),
                ("Personal Best: " + Player.getPersonalBest()), ("Winnings: " + Player.getWinnings()),
                ("Wins: " + Player.getWins()), ("Losses: " + Player.getLosses()),
                ("Win/Loss Ratio: " + String.format("%.2f", Player.getRatio()) + "%") };

        g.setFont(font);

        if (Player.getName() != null) {
            for (int x = 0; x < a.length; x++) {
                g.drawString(a[x].toString(), GamePanel.WIDTH - fontMetrics.stringWidth(a[x].toString()) - 30,
                        120 + x * 15);
            }
        }
    }

    private void select() {
        if (choice == 0) {
            // Slots
            gsm.setState(GameStateManager.SLOTGAMESTATE);
        }
        if (choice == 1) {
            // Dice
            gsm.setState(GameStateManager.DICEGAMESTATE);
        }
        if (choice == 2) {
            // Roulette
            gsm.setState(GameStateManager.ROULETTEGAMESTATE);
        }
        if (choice == 3) {
            // Leaderboards
            gsm.setState(GameStateManager.LEADERBOARDSTATE);
        }
        if (choice == 4) {
            // Settings
            gsm.setState(GameStateManager.SETTINGSSTATE);
        }
        if (choice == 5) {
            // Help
            gsm.setState(GameStateManager.HELPSTATE);
        }
        if (choice == 6) {
            // Quit
            System.exit(0);
        }
    }

    @Override
    public void keyPressed(int k) {
        if (k == KeyEvent.VK_ENTER) {
            select();
        }
        if (k == KeyEvent.VK_UP) {
            choice--;
            if (choice == -1) {
                choice = options.length - 1;
            }
        }
        if (k == KeyEvent.VK_DOWN) {
            choice++;
            if (choice == options.length) {
                choice = 0;
            }
        }
    }

    @Override
    public void keyReleased(int k) {
    }
}

Background.java

public class Background {

    private BufferedImage image;
    private double x;
    private double y;

    public Background(String s) {
        try {
            image = ImageIO.read(getClass().getResourceAsStream(s));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setPosition(double x, double y) {
        this.setX(x);
        this.setY(y);
    }

    public void draw(Graphics2D g) {
        g.drawImage(image, 0, 0, null);
    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }
}

这是它在游戏循环中等待输入的地方。我知道这是很多代码,但很多都是略读,直到方法调用带你到下一堂课。我只是无法弄清楚为什么它有时会发生,如果它是一致的我可以调试它。任何帮助都将非常感激。

running the code running it again, but different result

这些都来自单击上述程序的.jar,完全相同的.jar,完全相同的源代码,不同的结果。我很困惑。

0 个答案:

没有答案