gpt4 book ai didi

java - 多个面板/ Canvas

转载 作者:行者123 更新时间:2023-12-01 17:28:15 29 4
gpt4 key购买 nike

我正在寻找一种在面板之间/面板或 Canvas 之间动态切换的方法。更具体地说:我正在开发一款游戏。在我的代码中有一个类扩展 canvas 并实现Runnable,并且在 Game 的构造函数中,它创建了一个名为 window 的类的新实例。即窗口类:

public class Window extends Canvas {
private static final long serialVersionUID = -299686449326748512L;

public static JFrame frame = new JFrame();

public Window(int width, int height, String title, Game game) {
// JFrame frame = new JFrame();
frame.setPreferredSize(new Dimension(width, height));
frame.setMaximumSize(new Dimension(width, height));
frame.setMinimumSize(new Dimension(width, height));
frame.setTitle(title);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.add(game);
frame.setVisible(true);
game.start();
}
}

我希望能够从框架中删除游戏,激活另一个面板,并停止游戏的执行。我已经尝试过了:

game.stop();
Window.frame.remove(game);

但这会使程序崩溃。这些是 start() 和 stop() 方法:

/**
* starts the game.
*/
public synchronized void start() {
thread = new Thread(this);
thread.start();
running = true;
}
/**
* tries to stop the game.
*/
public synchronized void stop() {
try {
thread.join();
running = false;
} catch (Exception e) {
e.printStackTrace();
}
}

我的主要目标是能够在发生某些事件时播放过场动画,并且我正在尝试使用 vlcj 来实现此目的。如果有人有一个想法可以让我实现这个目标,那就太好了。

最佳答案

我做了一个例子,在没有卡片布局的情况下做我认为你想做的事情,并使用线程。我认为这是一个概念证明,你的要求是可能的。下面,我将包括一些我会做的改进工作。

import javax.swing.*;
import java.awt.*;
public class SwapCards{
Thread gameLoop;
volatile boolean running = false;
double x = 0;
double y = 0;
double theta = 0;
JFrame frame = new JFrame("swapped");
Canvas gamePanel = new Canvas(){
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.BLACK);
g.drawOval((int)x, (int)y, 25, 25);
}
};
Canvas nonGame = new Canvas(){
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.BLUE);
g.fillRect(0,0,200, 200);
}
};
public void step(){
x = 100 + 50*Math.sin( theta );
y = 100 + 50*Math.cos( theta );
theta += 0.02;
if(theta > 6.28) theta = 0;
}

public void startGameLoop(){
frame.remove(nonGame);
frame.add(gamePanel, BorderLayout.CENTER);
frame.validate();
running = true;
gameLoop = new Thread(()->{
while(running){
step();
gamePanel.repaint();
try{
Thread.sleep(30);
}catch (Exception e){
running = false;
throw new RuntimeException(e);
}
}
});
gameLoop.start();
}
public void stopGameLoop(){
frame.remove(gamePanel);
frame.add(nonGame, BorderLayout.CENTER);
running = false;
try{
gameLoop.join();
} catch(Exception e){
throw new RuntimeException(e);
}
}
public void buildGui(){
JButton button = new JButton("action");
button.addActionListener( evt->{
if(!running){
startGameLoop();
} else{
stopGameLoop();
}
});
frame.add(nonGame, BorderLayout.CENTER);
frame.add(button, BorderLayout.SOUTH);
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

}
public static void main(String[] args){
EventQueue.invokeLater( new SwapCards()::buildGui );
}
}

首先,Canvas 有点过时,请使用 JPane 并覆盖 paintComponent。这让您能够更好地发挥挥杆的力量。

在这个例子中,我正在做一些琐碎的工作,所以线程绝对是多余的,我可以用 javax.swing.Timer 替换它。

    Timer timer = new Timer(30, evt->{
step();
gamePanel.repaint();
});

然后在 start 和 stop 方法中,我只需分别调用 timer.start()timer.stop() 即可。

使用 CardLayout 可以让您更清楚地了解您想要做什么,而且它还具有导航卡片的方法。例如。如果您的过场动画包含要显示的一系列组件,则可以使用 cardLayout.next(parent)

当我们创建布局时:

cards = new CardLayout();
swap = new JPanel(cards);
swap.add(gamePanel, "game");
swap.add(nonGame, "nogame");
cards.last(swap);
frame.add(swap, BorderLayout.CENTER);

这会将卡片添加到交换并使其显示“nogame”。然后在启动/停止方法中我们只需切换到相应的卡。

cards.show(swap, "game");

关于java - 多个面板/ Canvas ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61175802/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com