如何从main方法调用打开一个Jframe

时间:2013-09-24 09:49:37

标签: java swing jframe jbutton

我已经在java中下载了一个蛇游戏项目并尝试修改它。最初该项目包含三个java文件 即“Engine.jav a”,“Snake.java”,“GameBoard.java”。并且Engine.java具有main()方法,当我运行此Engine.java类游戏开始运行时。

为了改善项目的用户迭代性,我创建了两个JFrame:“PlayGame.java”,Rules.java

现在这个项目有五个java类 -

Engine.java(containing main() method) 
Snake.java
GameBoard.java
PlayGame.java(is a JFrame)
Rules.java(is a JFrame)

PlayGame.java have three buttons

Play - i want when play button get clicked snake game start/run.
Rules - when clicked Rules.java Jframe should be opened 
Exit - exits the application

现在我想要的是第一次“PlayGame.java”JFrame应该出现(这显示为游戏项目的主要输出)并且应该开始抛出这个游戏,即当我点击{{1的播放按钮时游戏应该开始 我面临的问题是,当我点击PlayGame JFrame按钮时,窗口上会出现play gamescreen

以下是我在snake is not moving

actionPerformed()方法中包含的代码
Play button

我也正在显示 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { JFrame frame = new JFrame("SnakeGame"); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setResizable(true); Canvas canvas = new Canvas(); canvas.setBackground(Color.black); canvas.setPreferredSize(new Dimension(GameBoard.MAP_SIZE * GameBoard.TILE_SIZE, GameBoard.MAP_SIZE * GameBoard.TILE_SIZE)); frame.getContentPane().add(canvas); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); new Engine(canvas).startGame(); }

startGame()方法的代码
Engine.java

这里我也在我的问题中附加了Engine.java类和PlayGame.java,以便更好地理解问题

  

Engine.java

public void startGame() {
    canvas.createBufferStrategy(2);

    Graphics2D g = (Graphics2D)canvas.getBufferStrategy().getDrawGraphics();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    long start = 0L;
    long sleepDuration = 0L;
    while(true) {
        start = System.currentTimeMillis();

        update();
        render(g);

        canvas.getBufferStrategy().show();

        g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());

        sleepDuration = (1500L / UPDATES_PER_SECOND) - (System.currentTimeMillis() - start);

        if(sleepDuration > 0) {
            try {
                Thread.sleep(sleepDuration);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
}
  

PlayGame.java

package org.psnbtech;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import org.psnbtech.GameBoard.TileType;
import org.psnbtech.Snake.Direction;


public class Engine extends KeyAdapter {

    private static final int UPDATES_PER_SECOND = 15;

    private static final Font FONT_SMALL = new Font("Arial", Font.BOLD, 20);

    private static final Font FONT_LARGE = new Font("Arial", Font.BOLD, 40);

    public Canvas canvas;

    public GameBoard board;

    public Snake snake;

    public int score;

    public boolean gameOver;


    public Engine(Canvas canvas) {
                this.canvas = canvas;
            this.board = new GameBoard();
        this.snake = new Snake(board);

        resetGame();

        canvas.addKeyListener(this);
                //new Engine(canvas).startGame();
    }


    public void startGame() {
        canvas.createBufferStrategy(2);

        Graphics2D g = (Graphics2D)canvas.getBufferStrategy().getDrawGraphics();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        long start = 0L;
        long sleepDuration = 0L;
        while(true) {
            start = System.currentTimeMillis();

            update();
            render(g);

            canvas.getBufferStrategy().show();

            g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());

            sleepDuration = (1500L / UPDATES_PER_SECOND) - (System.currentTimeMillis() - start);

            if(sleepDuration > 0) {
                try {
                    Thread.sleep(sleepDuration);
                } catch(Exception e) {
                                    e.printStackTrace();
                }
            }
        }
    }

    public void update() {
        if(gameOver || !canvas.isFocusOwner()) {
            return;
        }
        TileType snakeTile = snake.updateSnake();
        if(snakeTile == null || snakeTile.equals(TileType.SNAKE)) {
            gameOver = true;
        } else if(snakeTile.equals(TileType.FRUIT)) {
            score += 10;
            spawnFruit();
        }
    }

    public void render(Graphics2D g) {
        board.draw(g);

        g.setColor(Color.WHITE);

        if(gameOver) {
            g.setFont(FONT_LARGE);
            String message = new String("Your Score: " + score);
            g.drawString(message, canvas.getWidth() / 2 - (g.getFontMetrics().stringWidth(message) / 2), 250);

            g.setFont(FONT_SMALL);
            message = new String("Press Enter to Restart the Game");
            g.drawString(message, canvas.getWidth() / 2 - (g.getFontMetrics().stringWidth(message) / 2), 350);
        } else {
            g.setFont(FONT_SMALL);
            g.drawString("Score:" + score, 10, 20);
        }
    }

    public void resetGame() {
        board.resetBoard();
        snake.resetSnake();
        score = 0;
        gameOver = false;
        spawnFruit();
    }

    public void spawnFruit() {
        int random = (int)(Math.random() * ((GameBoard.MAP_SIZE * GameBoard.MAP_SIZE) - snake.getSnakeLength())); // if '*' replace by '/' then only one fruit is there for snake

        int emptyFound = 0;
        int index = 0;
        while(emptyFound < random) {
            index++;
            if(board.getTile(index % GameBoard.MAP_SIZE, index / GameBoard.MAP_SIZE).equals(TileType.EMPTY)) { // if '/' replaced by '*' then nothing displays on the board 
                emptyFound++;
            }
        }
        board.setTile(index % GameBoard.MAP_SIZE, index / GameBoard.MAP_SIZE, TileType.FRUIT); // it also show nothing when replacing '/' by '/' 
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if((e.getKeyCode() == KeyEvent.VK_UP)||(e.getKeyCode() == KeyEvent.VK_W)) {
            snake.setDirection(Direction.UP);
        }
        if((e.getKeyCode() == KeyEvent.VK_DOWN)||(e.getKeyCode() == KeyEvent.VK_S)) {
            snake.setDirection(Direction.DOWN);
        }
        if((e.getKeyCode() == KeyEvent.VK_LEFT)||(e.getKeyCode() == KeyEvent.VK_A)) {
            snake.setDirection(Direction.LEFT);
        }
        if((e.getKeyCode() == KeyEvent.VK_RIGHT)||(e.getKeyCode() == KeyEvent.VK_D)) {
            snake.setDirection(Direction.RIGHT);
        }
        if(e.getKeyCode() == KeyEvent.VK_ENTER && gameOver) {
            resetGame();
        }
    }

         public static void main(String[] args)  {
        new PlayGame().setVisible(true);

        /**JFrame frame = new JFrame("SnakeGame");
        frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        frame.setResizable(false);

        Canvas canvas = new Canvas();
        canvas.setBackground(Color.black);
        canvas.setPreferredSize(new Dimension(GameBoard.MAP_SIZE * GameBoard.TILE_SIZE, GameBoard.MAP_SIZE * GameBoard.TILE_SIZE));

        frame.getContentPane().add(canvas);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true); 

        new Engine(canvas).startGame();*/


             }        
}

2 个答案:

答案 0 :(得分:2)

Taht因为你打电话

而发生
new PlayGame().setVisible(true);

frame.setVisible(true); 

只显示第一帧,然后点击按钮点击第二帧。

推荐的方法是始终只使用一个帧但是多个面板1.渲染游戏的位置和2.选项窗格。交换它们,例如使用CardLayout

另请勿使用Canvas使用JPanel来覆盖paintComponent()方法。

答案 1 :(得分:0)

尝试以下内容:

JFrameAdd ja = new JFrameAdd();
ja.setVisible(true);
ja.setLocationRelativeTo(null);

希望它会有所帮助!