我正在开发一个Java游戏。我陷入了困境,我需要在GameOver之后重新开始整场比赛。这是我的程序的骨架:
package projectflappy;
import java.awt.*;
public final class TheGame extends JFrame implements MouseListener{
JPanel jp;
//declaration of the varibles
int x_width = 500;
int y_height = 500;
int count = 5 ;
Ellipse2D Ball;
int x_ball;
int y_ball;
int cord_xup1,cord_xdown1;
int cord_xup2,cord_xdown2;
int cord_xup3,cord_xdown3;
int cord_xup4,cord_xdown4;
int cord_xup5,cord_xdown5;
Boolean flag = true;
RoundRectangle2D up1,down1,up2,down2,up3,down3,up4,down4;
Font font = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,40);
Font font1 = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,20);
Font font3 = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,20);
float das[] = {10.0f};
BasicStroke color = new BasicStroke(10,BasicStroke.CAP_ROUND,BasicStroke.JOIN_BEVEL,20.0f,das,0.0f);
GradientPaint gp2 = new GradientPaint(20, 0,
Color.DARK_GRAY, 0, 10, Color.GRAY, true);
GradientPaint gp3 = new GradientPaint(30, 0,
Color.BLACK, 0, 20, Color.GREEN, true);
Toolkit kit = Toolkit.getDefaultToolkit();
//Getting the "background.jpg" image we have in the folder
Image background = kit.getImage("D:\\College\\Programs\\ProjectFLAPPY\\src\\projectflappy\\1.png");
JLabel a = new JLabel("Get Ready ! Click to Start.");
JLabel retry = new JLabel(new ImageIcon("D:\\College\\Programs\\ProjectFLAPPY\\src\\projectflappy\\unnamed.png"));
int score = 0;
//constructor
public TheGame() throws IOException
{
super("Simple Drawing");
setSize(x_width, y_height);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
jp = new DrawingPanel();
add(jp);
addMouseListener(this);
}
ActionListener action = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
update();
repaint();
}
};
Timer t = new Timer(50,action);
public void init()
{
x_ball = 30;
y_ball = 200;
cord_xup1 = 175; cord_xdown1 = 175;
cord_xup2 = 320; cord_xdown2 = 320;
cord_xup3 = 460; cord_xdown3 = 460;
cord_xup4 = 585; cord_xdown4 = 585;
cord_xup5 = 700; cord_xdown5 = 700;
retry.setVisible(false);
retry.setBounds(175,260,46,46);
a.setForeground(Color.YELLOW);
a.setFont(font1);
a.setVisible(true);
a.setBounds(105,200,300,100);
}
@Override
public void mouseClicked(MouseEvent e) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
a.setVisible(false);
if( flag == false)
{
t.stop();
}
else
{
t.start();
}
y_ball = y_ball - 40;
count--;
}
@Override
public void mousePressed(MouseEvent e) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void mouseReleased(MouseEvent e) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void mouseEntered(MouseEvent e) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void mouseExited(MouseEvent e) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
// for drawing on the panel
class DrawingPanel extends JPanel{
private static final long serialVersionUID = 1L;
public DrawingPanel() {
setPreferredSize(new Dimension(300, 300));
setLayout(null);
init();
add(a);
add(retry);
// addMouseListener(this);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D d = (Graphics2D)g;
d.drawImage(background, -270,-30, this);
Ball = new Ellipse2D.Double(x_ball,y_ball,30,30);
d.setColor(Color.green);
d.setFont(font3);
up1 = new RoundRectangle2D.Double(cord_xup1,-5,30,175,20,20);
down1 = new RoundRectangle2D.Double(cord_xdown1,310,30,155,20,20);
up2 = new RoundRectangle2D.Double(cord_xup2,-5,30,200,20,20);
down2 = new RoundRectangle2D.Double(cord_xdown2,310,30,175,20,20);
up3 = new RoundRectangle2D.Double(cord_xup3,-5,30,230,20,20);
down3 = new RoundRectangle2D.Double(cord_xdown3,350,30,135,20,20);
up4 = new RoundRectangle2D.Double(cord_xup4,-5,30,115,20,20);
down4 = new RoundRectangle2D.Double(cord_xdown4,240,30,115,20,20);
d.setPaint(gp2);
d.setStroke(color);
d.fill(up1);
d.fill(down1);
d.fill(up2);
d.fill(down2);
d.fill(up3);
d.fill(down3);
d.fill(up4);
d.fill(down4);
d.setPaint(gp3);
d.setStroke(color);
d.fill(Ball);
d.setColor(Color.BLACK);
d.setFont(font1);
d.drawString(""+score ,200,50);
if( Ball.intersects(up1.getBounds()) || Ball.intersects(down1.getBounds()) || Ball.intersects(up2.getBounds()) || Ball.intersects(down2.getBounds()) || Ball.intersects(up3.getBounds()) || Ball.intersects(down3.getBounds()) || Ball.intersects(up4.getBounds()) || Ball.intersects(down4.getBounds()))
{
t.stop();
flag = false;
d.setColor(Color.red);
d.setFont(font);
d.drawString("Game Over : "+score ,100,250);
retry.setVisible(true);
}
retry.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent event) {
init(); //reset properties
}
//...
@Override
public void mousePressed(MouseEvent e) {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void mouseReleased(MouseEvent e) {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void mouseEntered(MouseEvent e) {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void mouseExited(MouseEvent e) {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
});
}
}
public void update()
{
cord_xdown1 -= 5;
cord_xup1 -= 5;
cord_xdown2 -= 5;
cord_xup2 -= 5;
cord_xdown3 -= 5;
cord_xup3 -= 5;
cord_xdown4 -= 5;
cord_xup4 -= 5;
cord_xdown5 -= 5;
cord_xup5 -= 5;
if( cord_xup1 <=-20)
{
cord_xup1 = 500;
cord_xdown1 = 500;
}
if( cord_xup2 <=-20)
{
cord_xup2 = 500;
cord_xdown2 = 500;
}
if( cord_xup3 <=-20)
{
cord_xup3 = 500;
cord_xdown3 = 500;
}
if( cord_xup4 <=-20)
{
cord_xup4 = 500;
cord_xdown4 = 500;
}
if( cord_xup5 <=-20)
{
cord_xup5 = 500;
cord_xdown5 = 500;
}
if(count >= 0)
{
y_ball = y_ball - 7;
count--;
if( y_ball == y_height)
{
t.stop();
}
}
else
{
y_ball = y_ball + 7;
if( y_ball == y_height-70)
{
t.stop();
}
}
if(cord_xdown1 == x_ball || cord_xdown2 == x_ball || cord_xdown3 == x_ball || cord_xdown4 == x_ball)
{
score = score+1;
}
}
public static void main(String[] args) throws IOException {
new TheGame();
}
}
此处retry
是JLabel
,其中我使用MouseListener
来执行操作。
当我运行时,JPanel
会从JFrame
完全删除,但新的JPanel
似乎无效。但只有一个组件,即a.setVisble(true)
可以工作。
这是玩家离开时的框架。
当玩家点击重试按钮时,此框架。
答案 0 :(得分:3)
新面板未显示的原因是组件层次结构无效。您尝试重新验证,但是在添加面板之前已经这样做了。在将组件添加到已经可见的容器之后,您需要执行此操作。查看invalidate()
:
当任何与布局相关的信息发生变化时,会自动调用此方法(例如,设置组件的边界,或将组件添加到容器)。
因此,您必须在添加组件后进行验证,而不是之前。 revalidate()
无效,然后重新验证组件层次结构。
处理此的正确方法是将游戏恢复为原始状态;只需将一切改回原来的样子。无需创建新面板。
您可以创建一种方法init()
,将您的游戏设置为应该如何:
//Contains the properties that will change during gameplay
void init() {
retry.setVisible(false);
a.setForeground(Color.YELLOW);
//...
}
您可以在创建电路板(在构造函数中)和按重试(在监听器中)时调用:
public DrawingPanel() {
setPreferredSize(new Dimension(300, 300));
setPreferredSize(new Dimension(300, 300));
setLayout(null);
init(); //sets properties
a.setFont(font1);
a.setVisible(true);
a.setBounds(105,200,300,100);
add(a);
retry.setBounds(175,260,46,46);
retry.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent event) {
init(); //reset properties
}
//...
});
add(retry);
}
您不应该在update()
方法中为组件添加侦听器,因为update()
将被多次调用。在构造函数中添加它。
如果retry
是JButton
,则应使用ActionListener
。我不确定,所以我把它当作一个老鼠听众。
您应该避免使用null
布局(absolute positioning)。布局管理器使用特定计算来定位和调整组件,以确保在所有平台上生成的GUI看起来都相同。如教程中所提到的,绝对定位是一种可行的选择有一些用途,但总是最好选择布局管理器。 IMO,null布局是不好的做法,人们使用它的唯一原因是他们不了解布局管理器,这本身就是一个问题。
要了解有关布局管理器的更多信息,请查看Visual Guide to Layout Managers路径。 JDK不仅与布局捆绑在一起,而且您还可以创建自己的布局或使用第三方布局,例如MigLayout
编辑:
将Swing代码发布到Event Dispatch Thread。 Swing事件处理程序(绘图,侦听器)在Event Dispatch Thread上执行。要确保您编写的Swing代码与EDT同步,请使用invokeLater
或invokeAndWait
将任何尚未在EDT上执行的Swing代码发布到EDT。
请勿直接调整框架尺寸。允许框架根据其内部的内容进行调整。您的DrawingPanel(游戏画布)应确定框架的大小。
TheGame
不应展开JFrame
,因为它不是框架本身,而是框架中包含的内容。对它进行扩展JPanel
对您来说会更容易一些(您不会被迫创建一个新类来覆盖paint
方法)。虽然 TheGame
不应该扩展任何内容,但它应该具有这些东西(有关系,而不是a-a)。但是既然你还是初学者,我也不想用一个全新的设计来压倒你,所以我认为TheGame
是真正的游戏画布(事物将被绘制; {{1 }}将扩展TheGame
),因此您不再需要JPanel
。
如前所述,您不应在paint方法中添加侦听器(或执行只需要一次的任何任务)。请记住,绘制方法用于绘制,而不是初始化或设置值。如果可能,您应该尝试将逻辑排除在该方法之外。
保持一致。您使用DrawingBoard
进行&#34; 点击开始!&#34;,然后使用JLabel
进行&#34; 游戏结束&#34 ;.选择一个或另一个。这个选择真的取决于你。对于此示例,我选择使用drawString
,因为它与其他渲染方法(如何绘制背景,球和障碍物)一致
不要在您的绘画方法中创建新对象。您每50毫秒创建一大堆新对象。这不是必需的,会严重影响 批判 的效果。使用drawString
关键字时,可以创建新对象。而不是创建一个新对象来改变它(或将其还原),只需改变它的状态。
利用面向对象。它可以帮助您保持井井有条,并使您能够轻松管理和扩展您的应用程序。不要将一堆变量推到一个类来代表大量不同的东西(new
,cordx_up1
......它绝对不可扩展。)
查看一些cordx_up2
类,例如Adapter
和MouseAdapter
;它们允许您处理事件而无需声明您可能不使用的方法。
使用访问修饰符。如果您不熟悉它们,请了解它们。如果您知道可以提前使用它的位置,它可以使代码管理变得更加容易。
您的路径指向具有特定名称的特定驱动器。不应该是这种情况,因为不是每个人都使用该驱动器和/或文件夹名称。将您的图像打包到您的项目中,然后在本地参考它们。
话虽如此,你还有很多学习要做。
我所做的是创建一个KeyAdapter
类和一个Ball
类,以便更有条理。 Obstacle
和ball_x
现在位于ball_y
类中,以及它的渐变。我们从这个类创建的对象现在将具有这些属性(状态)。我为你的游戏创建了一个球对象。
Ball
类不是为每个极点(cordx_up1
)创建新变量,而是有2 Obstacle
,RoundRectangle2D
和top
,它们是极点你的球应该避免。每个障碍物都有一个渐变,用于bottom
和top
。现在我可以为2个对齐的杆创建1个障碍物。您可以更改障碍物的起始bottom
位置(虽然我不建议允许这样做; x
应根据其他障碍物位置动态设置,以及尺寸适用于x
和top
。我创造了5个障碍物。
为了在使用bottom
代替drawString
时保持游戏标签的组织(按颜色,消息,位置,字体),我创建了JLabel
类。
我将主要方法分成了自己的名为GameLabel
的类,它创建了一个Launcher
并将游戏添加到其中;所有关于事件发送线程:
JFrame
您的public class Launcher {
public static void main(String[] args) throws IOException {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(new TheGame());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
}
}
课程现在扩展Game
,因此您可以覆盖JPanel
方法来渲染游戏。我为你的障碍创建了1 paint
和Ball
。我选择LinkedList
,因为从前/后插入/移除是保证恒定的时间,这意味着无论列表中有多少障碍物,它都会花费相同的时间来移除/插入。当球通过障碍物时,我将其从列表的前面移除并将其添加到后面。列表中的第一个障碍始终是下一个障碍。
我看到了一些字符串是如何被重用的,所以我为它们创建了最终变量,你可以很容易地改变它们。还有LinkedList
和currentlyPlaying
布尔值。当用户第一次点击(开始游戏)时,isAlive
设置为currentlyPlaying
,一旦用户点击重启游戏(失败后),设置为true
。
false
是我用来将鼠标事件转发到readyToJump
方法的标志(从技术上讲是update()
方法,但它仍然是#cen;内置的&#34;在updatePlayerPostion()
方法中。最好将所有逻辑保存在一个地方。如果您不依赖于update()
中的readyToJump = true
,那么timer.start()
将成为您听众方法中唯一的陈述。由于除非计时器已启动,update()
无法启动,mouseEvent
启动计时器,我们仍必须按照听众的方式开始游戏。
@SuppressWarnings("serial")
public final class TheGame extends JPanel implements MouseListener, ActionListener {
public static final int WIDTH = 500, HEIGHT = 500;
private final String START_SCORE = "0",
START_MESSAGE = "Get Ready ! Click to Start.",
BACKGROUND_URL = "/res/flappy.png";
private boolean currentlyPlaying, readyToJump, isAlive = true;
private int score;
private Timer timer;
private Image background;
private GameLabel messageLabel, scoreLabel;
private Collection<Obstacle> obstaclesInOrder;
private LinkedList<Obstacle> obstacles;
private Ball ball;
public TheGame() {
setPreferredSize(new Dimension(WIDTH, HEIGHT));
addMouseListener(this);
timer = new Timer(50, this);
background = loadBackgroundImage();
messageLabel = new GameLabel(START_MESSAGE, 150, 240);
scoreLabel = new GameLabel(START_SCORE, 250, 60);
obstacles = new LinkedList<>();
obstacles.removeAll(obstacles);
obstaclesInOrder = Arrays.asList(new Obstacle(175, 20, 45), new Obstacle(320), new Obstacle(460), new Obstacle(585), new Obstacle(700));
obstacles.addAll(obstaclesInOrder);
ball = new Ball(30, 100);
}
@Override
public void mouseClicked(MouseEvent e) {
if (!currentlyPlaying) {
startGame();
} else if (!isAlive) {
reset();
}
readyToJump = true;
}
private void startGame() {
currentlyPlaying = true;
messageLabel.update("");
timer.start();
}
private void endGame() {
isAlive = false;
scoreLabel.update("");
messageLabel.update("Game Over. Your score was " + Integer.toString(score));
timer.stop();
}
private void reset() {
ball.reset();
for (Obstacle obstacle : obstacles)
obstacle.reset();
messageLabel.update(START_MESSAGE, 150, 240);
scoreLabel.update(START_SCORE, 250, 60);
obstacles.removeAll(obstacles);
obstacles.addAll(obstaclesInOrder);
score = 0;
isAlive = true;
currentlyPlaying = false;
repaint();
}
@Override
public void actionPerformed(ActionEvent ae) {
update();
repaint();
}
private void update() {
if (isAlive) {
updateBallPosition();
updateObstaclePositions();
if(ballOutOfBounds() || playerCollidedWithObstacle()) {
endGame();
} else if(ballPassedObstacle()) {
addToScore();
setupNextObstacle();
}
}
}
private void updateBallPosition() {
if (readyToJump) {
readyToJump = false;
ball.jump();
} else {
ball.fall();
}
}
private void updateObstaclePositions() {
for (Obstacle obstacle : obstacles) {
if (obstacle.getX() <= -obstacle.getWidth()) {
obstacle.moveToBack();
continue;
}
obstacle.moveForward();
}
}
private void addToScore() {
scoreLabel.update(Integer.toString(++score));
}
private void setupNextObstacle() {
obstacles.addLast(obstacles.removeFirst());
}
private boolean ballOutOfBounds() {
return ball.getY() >= HEIGHT || ball.getY() <= 0;
}
private boolean ballAtObstacle() {
Obstacle currentObstacle = obstacles.getFirst();
return ball.getX() + ball.getWidth() >= currentObstacle.getX() && ball.getX() <= currentObstacle.getX() + currentObstacle.getWidth();
}
private boolean ballPassedObstacle() {
Obstacle currentObstacle = obstacles.getFirst();
return ball.getX() >= (currentObstacle.getX() + currentObstacle.getWidth());
}
private boolean playerCollidedWithObstacle() {
boolean collided = false;
if(ballAtObstacle()) {
for (Obstacle obstacle : obstacles) {
RoundRectangle2D top = obstacle.getTop();
RoundRectangle2D bottom = obstacle.getBottom();
if (ball.intersects(top.getX(), top.getY(), top.getWidth(), top.getHeight()) || ball.intersects(bottom.getX(), bottom.getY(), bottom.getWidth(), bottom.getHeight())) {
collided = true;
}
}
}
return collided;
}
private Image loadBackgroundImage() {
Image background = null;
URL backgroundPath = getClass().getResource(BACKGROUND_URL);
if(backgroundPath == null) {
background = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
} else {
try {
background = ImageIO.read(backgroundPath);
} catch (IOException e) {
e.printStackTrace();
}
}
return background;
}
@Override
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Graphics2D g = (Graphics2D) graphics;
g.drawImage(background, 0, 0, null);
ball.paint(g);
for (Obstacle obstacle : obstacles)
obstacle.paint(g);
scoreLabel.paint(g);
messageLabel.paint(g);
}
//...
}
loadBackgroundImage()
加载并返回图像。如果出现问题(图像可能不存在),则会返回黑色图像。
(大部分)游戏逻辑采用update()
方法。虽然它应该全部存在,但由于设计缺陷(来自您使用管理Timer
的{{1}},并且您在监听器中启动计时器,因此我们需要一些逻辑在听众中)。您的逻辑应该易于阅读,并且应该监视每个执行步骤并将其设置为最低优先级。
首先,我检查以确保球没有碰到任何东西或超出范围。如果其中一件事发生,我就结束游戏了。
如果没有,我会检查玩家是否已通过障碍物。如果玩家通过障碍物,我会加入得分:
update()
然后我终于更新了这些职位。
为了避免不断比较玩家的位置和障碍物的位置(看看玩家是否通过了它),我创建了一个private void update() {
if (ballOutOfBounds() || playerCollidedWithObstacle()) {
endGame();
} else if (ballPassedObstacle()) {
addToScore();
setupNextObstacle();
}
updateBallPosition();
updateObstaclePositions();
}
方法,用于检查玩家是否在一个障碍。只有这样才能比较职位:
boolean ballAtObstacle()
private boolean playerCollidedWithObstacle() {
boolean collided = false;
if (ballAtObstacle()) {
for (Obstacle obstacle : obstacles) {
RoundRectangle2D top = obstacle.getTop();
RoundRectangle2D bottom = obstacle.getBottom();
if (ball.intersects(top.getX(), top.getY(), top.getWidth(), top.getHeight()) || ball.intersects(bottom.getX(), bottom.getY(), bottom.getWidth(), bottom.getHeight())) {
collided = true;
}
}
}
return collided;
}
方法调用有点乱。虽然你可以将intersects方法声明为ball.intersects
,但我这样做的形状并不是特定的。
最后,当你跌倒时,我通过提高坠落速度给它一个更加脆弱的鸟类感觉。当你再次跳跃时,它会恢复正常。跳跃的时间越长,你跌得越快。如果你不喜欢这个功能,并且不知道如何删除它,请告诉我,我会告诉你如何。
涉及的其他课程:
GameLabel.java
boolean intersects(Shape shape)
Obstacle.java
public class GameLabel {
private String message;
private Font font;
private Color color;
private int x, y;
public GameLabel(String message, int x, int y, Color color, Font font) {
update(message, x, y, color, font);
}
public GameLabel(String message, int x, int y) {
this(message, x, y, Color.BLACK, new Font("Matura MT Script Capitals", Font.ROMAN_BASELINE, 20));
}
public GameLabel() {
this("", 0, 0);
}
public void setMessage(String message) {
this.message = message;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setColor(Color color) {
this.color = color;
}
public void setFont(Font font) {
this.font = font;
}
public final void update(String message, int x, int y, Color color, Font font) {
this.message = message;
this.x = x;
this.y = y;
this.color = color;
this.font = font;
}
public void update(String message, int x, int y) {
update(message, x, y, color, font);
}
public void update(String message) {
update(message, x, y);
}
public void paint(Graphics2D g) {
g.setFont(font);
g.setColor(color);
g.drawString(message, x, y);
}
public Font getFont() {
return font;
}
public Color getColor() {
return color;
}
public String getMessage() {
return message;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Ball.java
public class Obstacle {
public static final int DEFAULT_TOP_HEIGHT = 175;
public static final int DEFAULT_BOTTOM_HEIGHT = 175;
public static final int DEFAULT_WIDTH = 30;
public static final int DEFAULT_ARCH_WIDTH = 20;
public static final int DEFAULT_ARCH_HEIGHT = 20;
public static final int DEFAULT_TOP_INSET = -5;
public static final int DEFAULT_BOTTOM_INSET = TheGame.HEIGHT + 5;
private RoundRectangle2D top, bottom;
private BasicStroke stroke;
private GradientPaint gradient;
private int initialX, x, width;
public Obstacle(int x, int width, int topHeight, int bottomHeight) {
this.x = initialX = x;
this.width = width;
top = new RoundRectangle2D.Double(x, DEFAULT_TOP_INSET, width, topHeight, DEFAULT_ARCH_WIDTH, DEFAULT_ARCH_HEIGHT);
bottom = new RoundRectangle2D.Double(x, DEFAULT_BOTTOM_INSET-bottomHeight, width, bottomHeight, DEFAULT_ARCH_WIDTH, DEFAULT_ARCH_HEIGHT);
stroke = new BasicStroke(10, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL, 20.0f, new float[] { 10.0f }, 0.0f);
gradient = new GradientPaint(20, 0, Color.DARK_GRAY, 0, 10, Color.GRAY, true);
}
public Obstacle(int x, int topHeight, int bottomHeight) {
this(x, DEFAULT_WIDTH, topHeight, bottomHeight);
}
public void reset() {
x = initialX;
top.setRoundRect(initialX, top.getY(), top.getWidth(), top.getHeight(), top.getArcWidth(), top.getArcHeight());
bottom.setRoundRect(initialX, bottom.getY(), bottom.getWidth(), bottom.getHeight(), bottom.getArcWidth(), bottom.getArcHeight());
}
public Obstacle(int x, int width) {
this(x, width, DEFAULT_TOP_HEIGHT, DEFAULT_BOTTOM_HEIGHT);
}
public Obstacle(int x) {
this(x, DEFAULT_WIDTH);
}
public void moveToBack() {
x = 600;
}
public void moveForward() {
x -= 5;
top.setRoundRect(x, top.getY(), top.getWidth(), top.getHeight(), top.getArcWidth(), top.getArcHeight());
bottom.setRoundRect(x, bottom.getY(), bottom.getWidth(), bottom.getHeight(), bottom.getArcWidth(), bottom.getArcHeight());
}
public RoundRectangle2D getTop() {
return top;
}
public RoundRectangle2D getBottom() {
return bottom;
}
public int getX() {
return x;
}
public int getWidth() {
return width;
}
public void paint(Graphics2D g) {
g.setPaint(gradient);
g.setStroke(stroke);
g.fill(top);
g.fill(bottom);
}
}
答案 1 :(得分:-3)
通过将初始化代码添加到一个方法(resetAll)来重新初始化所有组件,并在您想要重新初始化时调用该方法
以下是一个例子:
import java.awt.*;
import java.awt.event.*;
public class ResetTest extends Frame{
Button b;
TextField tf;
Frame f;
Panel p;
public ResetTest(){
f=this; //intialize frame f to this to have access to our frame in event handler methods
resetAll(); //first time call to resetAll will initialize all the parameters of the frame
f.pack();
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent we){
System.exit(0);
}
});
this.setLayout(new FlowLayout(FlowLayout.CENTER,20,20));
this.setVisible(true);
}
/**
This method will be called on click of button to
reset all the parameters of the frame so that we
get fresh new frame, everything as it was before.
**/
public void resetAll(){
b=new Button("Reset");
p=new Panel(new FlowLayout(FlowLayout.CENTER,20,20));
p.add(b);
tf = new TextField("Edit And Reset");
p.add(tf);
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
remove(p); //remove the panel that contains all our components
resetAll(); // reset all the components
f.pack(); //refreshes the view of frame when everything is reset.
}
});
add(p);
}
}
class NewClass{
public static void main(String[] args) {
ResetTest fReset = new ResetTest();
}
}