我仍然是java编程的新手,所以请帮助我纠正我可能忽略的任何错误或提供有关如何改进此程序的提示.
好的,所以很多问题都解决了,现在我有了一个CardLayout,但我仍然对如何让我的管道显示在里面有疑问.
当我尝试添加刷新率计时器和我的速度计时器时,我遇到了如何声明和初始化布尔变量的问题.
此外,当我编译并运行这个游戏时,我得到的文件如Game$1.class
.有没有办法让我清理它,有人可以解释为什么会这样吗?这些对成品有影响吗?(当游戏编译并打包成JAR时.)
我想在点击播放按钮时将playerIsReady设置为true.从那里,当if语句为真时,然后切换到显示管道的面板,并开始在屏幕上移动管道.最好是该管道的3个实例,每个实例在不同的时间开始,但无论你能提供什么帮助都很好.
这些代码中的一些需要工作,所以我已经注释了一些部分并留下了注释.
我可以在这里找到关于这个游戏的其他问题.
这是我目前的代码
Game.java
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; import javax.swing.border.EmptyBorder; import javax.swing.SwingUtilities; public class Game { public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { // the GUI as seen by the user (without frame) final CardLayout cl = new CardLayout(); final JPanel gui = new JPanel(cl); // remove if no border is needed gui.setBorder(new EmptyBorder(10,10,10,10)); JPanel menu = new JPanel(new GridBagLayout()); JButton playGame = new JButton("Play!"); ActionListener playGameListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { cl.show(gui, "game"); } }; playGame.addActionListener(playGameListener); Insets margin = new Insets(20, 50, 20, 50); playGame.setMargin(margin); menu.add(playGame); gui.add(menu); cl.addLayoutComponent(menu, "menu"); final JPanel pipes = new Pipes(); gui.add(pipes); cl.addLayoutComponent(pipes, "game"); JFrame f = new JFrame("Pipes Game"); f.add(gui); // Ensures JVM closes after frame(s) closed and // all non-daemon threads are finished f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // See /sf/ask/17360801/ for demo. f.setLocationByPlatform(true); // ensures the frame is the minimum size it needs to be // in order display the components within it f.pack(); // should be done last, to avoid flickering, moving, // resizing artifacts. f.setVisible(true); /*if (playerIsReady) { Timer speed = new Timer(10, new ActionListener() { //pipe speed @Override public void actionPerformed(ActionEvent e) { pipes.move(); } }); speed.start(); Timer refresh = new Timer(30, new ActionListener() { //refresh rate @Override public void actionPerformed(ActionEvent e) { pipes.repaint(); } }); refresh.start(); }*/ } }; // Swing GUIs should be created and updated on the EDT // http://docs.oracle.com/javase/tutorial/uiswing/concurrency SwingUtilities.invokeLater(r); } }
Pipes.java
// What import(s) do I need for ArrayList? public class Pipes { Listpipes = new ArrayList (); public Pipes() { pipes.add(new Pipe(50, 100)); pipes.add(new Pipe(150, 100)); pipes.add(new Pipe(250, 100)); } protected void paintComponent(Graphics g) { super.paintComponent(g); for ( Pipe pipe : pipes ){ pipe.drawPipe(g); } } }
PipeObject.java
import java.awt.Graphics; public class PipeObject { //Declare and initialiaze variables int x1 = 754; //xVal start int x2 = 75; //pipe width //total width is 83 int y1 = -1; //yVal start int y2 = setHeightVal(); //pipe height int gap = 130; //gap height public void drawPipe(Graphics g) { g.clearRect(0,0,750,500); //Clear screen g.drawRect(x1,y1,x2,y2); //Draw part 1 g.drawRect(x1-3,y2-1,x2+6,25); //Draw part 2 g.drawRect(x1-3,y2+25+gap,x2+6,25); //Draw part 3 g.drawRect(x1,y2+25+gap+25,x2,500-y2-49-gap); //Draw part 4 } public void move() { x1--; } public int getMyX() { //To determine where the pipe is horizontally return x1-3; } public int getMyY() { //To determine where the pipe is vertically return y2+25; } public int setHeightVal() { //Get a random number and select a preset height int num = (int)(9*Math.random() + 1); int val = 0; if (num == 9) { val = 295; } else if (num == 8) { val = 246; } else if (num == 7) { val = 216; } else if (num == 6) { val = 185; } else if (num == 5) { val = 156; } else if (num == 4) { val = 125; } else if (num == 3) { val = 96; } else if (num == 2) { val = 66; } else { val = 25; } return val; } }
Andrew Thomp.. 6
解决这个问题的最佳方法是使用a CardLayout
.
一个带有a的按钮ActionListener
远远MouseListener
超过一个矩形.
当鼠标指向该按钮时,该按钮将显示焦点,或者通过键盘将该组件标记为按钮.
该按钮可通过键盘访问.
该按钮具有支持内置多个图标的功能(例如,用于"初始外观",聚焦,按下等)
通过添加一个菜单面板和游戏,在GUI中提供空白区域 EmptyBorder
通过设置边距使按钮变大.
根据需要调整边距,边框和首选尺寸.这些尺寸是由我设定的,以免使截图过大.
在代码注释中查看更多提示.
以下是产生上述屏幕截图的MCTaRE(最小完整测试和可读示例).
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import javax.swing.border.EmptyBorder; public class PipesGame { public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { // the GUI as seen by the user (without frame) final CardLayout cl = new CardLayout(); final JPanel gui = new JPanel(cl); // remove if no border is needed gui.setBorder(new EmptyBorder(10,10,10,10)); JPanel menu = new JPanel(new GridBagLayout()); JButton playGame = new JButton("Play!"); ActionListener playGameListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { cl.show(gui, "game"); } }; playGame.addActionListener(playGameListener); Insets margin = new Insets(20, 50, 20, 50); playGame.setMargin(margin); menu.add(playGame); gui.add(menu); cl.addLayoutComponent(menu, "menu"); JPanel pipes = new Pipes(); gui.add(pipes); cl.addLayoutComponent(pipes, "game"); JFrame f = new JFrame("Pipes Game"); f.add(gui); // Ensures JVM closes after frame(s) closed and // all non-daemon threads are finished f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // See /sf/ask/17360801/ for demo. f.setLocationByPlatform(true); // ensures the frame is the minimum size it needs to be // in order display the components within it f.pack(); // should be done last, to avoid flickering, moving, // resizing artifacts. f.setVisible(true); } }; // Swing GUIs should be created and updated on the EDT // http://docs.oracle.com/javase/tutorial/uiswing/concurrency SwingUtilities.invokeLater(r); } } class Pipes extends JPanel { Pipes() { setBackground(Color.BLACK); setForeground(Color.WHITE); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("Pipes game appears here..", 170, 80); } @Override public Dimension getPreferredSize() { // adjust to need return new Dimension(500,150); } }
Paul Samsoth.. 5
"我有没有办法将我的GameMenu jpanel添加到我的jframe中,然后用Pipes jpanel替换它?"
正如其他人所建议的那样,你需要一个CardLayout
.这对你来说很简单.就我个人而言,我总是把自己包裹CardLayout
在一个JPanel
而JFrame
不仅仅是习惯的力量中.
你想要做的是有一个mainPanel
,将有CardLayout
CardLayout card = new CardLayout(); JPanel mainPanel = new JPanel();
然后你想将你的面板添加到mainPanel
.什么CardLyaout
确实是分层的面板,使得仅仅一个在同一时间可见.您添加的第一个将在前景中.此外,当您添加面板时,您还需要向它发出一个可以从中调用的键.键,可以是您喜欢的任何字符串.
mainPanel.add(gameMenu, "menu"); mainPnael.add(pipes, "pipe");
现在gameMenu
是唯一显示的面板.要显示pipes
,您所做的就是使用此方法
public void show(Container parent, String name)
- 使用addLayoutComponent 翻转到parent
指定的布局中添加的内容name
.如果不存在这样的组件,则没有任何反应.
所以你要用, card.show(mainPanel, "pipes");
无论你想触发什么pipes
,只需在该事件处理程序中添加该行.您可以添加一个按钮或其他内容GameMenu
,以便移动到Pipes
面板.
解决这个问题的最佳方法是使用a CardLayout
.
一个带有a的按钮ActionListener
远远MouseListener
超过一个矩形.
当鼠标指向该按钮时,该按钮将显示焦点,或者通过键盘将该组件标记为按钮.
该按钮可通过键盘访问.
该按钮具有支持内置多个图标的功能(例如,用于"初始外观",聚焦,按下等)
通过添加一个菜单面板和游戏,在GUI中提供空白区域 EmptyBorder
通过设置边距使按钮变大.
根据需要调整边距,边框和首选尺寸.这些尺寸是由我设定的,以免使截图过大.
在代码注释中查看更多提示.
以下是产生上述屏幕截图的MCTaRE(最小完整测试和可读示例).
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import javax.swing.border.EmptyBorder; public class PipesGame { public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { // the GUI as seen by the user (without frame) final CardLayout cl = new CardLayout(); final JPanel gui = new JPanel(cl); // remove if no border is needed gui.setBorder(new EmptyBorder(10,10,10,10)); JPanel menu = new JPanel(new GridBagLayout()); JButton playGame = new JButton("Play!"); ActionListener playGameListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { cl.show(gui, "game"); } }; playGame.addActionListener(playGameListener); Insets margin = new Insets(20, 50, 20, 50); playGame.setMargin(margin); menu.add(playGame); gui.add(menu); cl.addLayoutComponent(menu, "menu"); JPanel pipes = new Pipes(); gui.add(pipes); cl.addLayoutComponent(pipes, "game"); JFrame f = new JFrame("Pipes Game"); f.add(gui); // Ensures JVM closes after frame(s) closed and // all non-daemon threads are finished f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // See /sf/ask/17360801/ for demo. f.setLocationByPlatform(true); // ensures the frame is the minimum size it needs to be // in order display the components within it f.pack(); // should be done last, to avoid flickering, moving, // resizing artifacts. f.setVisible(true); } }; // Swing GUIs should be created and updated on the EDT // http://docs.oracle.com/javase/tutorial/uiswing/concurrency SwingUtilities.invokeLater(r); } } class Pipes extends JPanel { Pipes() { setBackground(Color.BLACK); setForeground(Color.WHITE); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("Pipes game appears here..", 170, 80); } @Override public Dimension getPreferredSize() { // adjust to need return new Dimension(500,150); } }
"我有没有办法将我的GameMenu jpanel添加到我的jframe中,然后用Pipes jpanel替换它?"
正如其他人所建议的那样,你需要一个CardLayout
.这对你来说很简单.就我个人而言,我总是把自己包裹CardLayout
在一个JPanel
而JFrame
不仅仅是习惯的力量中.
你想要做的是有一个mainPanel
,将有CardLayout
CardLayout card = new CardLayout(); JPanel mainPanel = new JPanel();
然后你想将你的面板添加到mainPanel
.什么CardLyaout
确实是分层的面板,使得仅仅一个在同一时间可见.您添加的第一个将在前景中.此外,当您添加面板时,您还需要向它发出一个可以从中调用的键.键,可以是您喜欢的任何字符串.
mainPanel.add(gameMenu, "menu"); mainPnael.add(pipes, "pipe");
现在gameMenu
是唯一显示的面板.要显示pipes
,您所做的就是使用此方法
public void show(Container parent, String name)
- 使用addLayoutComponent 翻转到parent
指定的布局中添加的内容name
.如果不存在这样的组件,则没有任何反应.
所以你要用, card.show(mainPanel, "pipes");
无论你想触发什么pipes
,只需在该事件处理程序中添加该行.您可以添加一个按钮或其他内容GameMenu
,以便移动到Pipes
面板.