英文:
Is there a way in Java to make labels move without user influence?
问题
以下是您提供的代码的翻译部分:
我正在尝试开发一个应用程序,用户可以在屏幕底部将一个罐头来回移动,以尝试捕捉下落的蜜蜂。我已成功使罐头的移动工作,但卡在了蜜蜂的移动上。在我的当前阶段,我导入了一个蜜蜂,我希望它从屏幕顶部掉落到底部,但当运行时,它只停留在屏幕顶部。我在这里遇到了一个错误:
`beeTimer.stop();`
错误消息:可能未初始化局部变量beeTimer
以下是它被初始化的地方:
```java
try {
Timer beeTimer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("蜜蜂在移动!");
beeY[0] += beeSpeed;
beeLabel.setLocation(beeX, beeY[0]);
if (beeY[0] + 106 > (frame.getContentPane().getHeight() - 200)) {
beeTimer.stop();
}
}
});
beeTimer.start();
} finally{}
这是我迄今为止的整个代码:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import javax.swing.*;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
//让罐头可以被鼠标拖动
class DraggableLabel extends JLabel implements MouseListener, MouseMotionListener {
private Point mouseOffset;
public DraggableLabel(ImageIcon icon) {
super(icon);
addMouseListener(this);
addMouseMotionListener(this);
}
public void mousePressed(MouseEvent e) {
mouseOffset = e.getPoint();
}
public void mouseDragged(MouseEvent e) {
Point newMousePos = e.getLocationOnScreen();
newMousePos.translate(-mouseOffset.x, -(newMousePos.y - getLocation().y));
setLocation(newMousePos);
}
// 不需要拖动的以下方法,但必须实现,因为我们实现了MouseListener和MouseMotionListener接口。
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
}
class App{
public static void main(String[] args){
//声明游戏的窗口
JFrame frame = new JFrame("游戏");
//声明图像变量
ImageIcon can = null;
ImageIcon bee = null;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
//加载罐头图像文件
try {
File canFile = new File("assets/can.png");
BufferedImage originalCan = ImageIO.read(canFile);
if (originalCan == null) {
throw new IOException("无法读取图像文件:" + canFile.getName());
}
int canWidth = 75;
int canHeight = 136;
Image icon = originalCan.getScaledInstance(canWidth, canHeight, Image.SCALE_SMOOTH);
can = new ImageIcon(icon);
} catch (IOException e) {
e.printStackTrace();
}
//加载蜜蜂图像文件
try {
File beeFile = new File("assets/bee.png");
BufferedImage originalBee = ImageIO.read(beeFile);
if (originalBee == null) {
throw new IOException("无法读取图像文件:" + beeFile.getName());
}
int beeWidth = 40;
int beeHeight = 61;
Image icon = originalBee.getScaledInstance(beeWidth, beeHeight, Image.SCALE_SMOOTH);
bee = new ImageIcon(icon);
} catch (IOException e) {
e.printStackTrace();
}
//导入蜜蜂图像
Image beeImage = bee.getImage();
ImageIcon beeFall = new ImageIcon(beeImage);
JLabel beeLabel = new JLabel(beeFall);
//设置蜜蜂的生成位置
int beeX = (screenSize.width - bee.getIconWidth()) / 2;
final int[] beeY = {0};
beeLabel.setBounds(beeX, beeY[0], 60, 106);
frame.getContentPane().add(beeLabel);
//蜜蜂下落行为
int beeSpeed = 5;
try {
Timer beeTimer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("蜜蜂在移动!");
beeY[0] += beeSpeed;
beeLabel.setLocation(beeX, beeY[0]);
if (beeY[0] + 106 > (frame.getContentPane().getHeight() - 200)) {
beeTimer.stop();
}
}
});
beeTimer.start();
} finally{}
//导入可拖动的罐头图像
DraggableLabel label = new DraggableLabel(can);
frame.getContentPane().setLayout(null);
label.setSize(can.getIconWidth(), can.getIconHeight());
frame.getContentPane().add(label);
//将罐头在水平方向居中放置,垂直方向略高于底部
int x = (screenSize.width - can.getIconWidth()) / 2;
int y = screenSize.height - can.getIconHeight() - 175; // 在底部上方50像素
label.setLocation(x, y);
//使窗口可见
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
如果您有任何其他问题或需要进一步的帮助,请随时告诉我。
英文:
I am trying to develop an application where the user moves a can back and forth on the bottom of the screen to try to catch bees as they fall. I have successfullly gotten the can movement working, but I am stuck on the bees' movement. In my current phase, I have a single bee imported that I want to fall from the top of the screen to the bottom, but it just stays at the top of the screen when it runs. I get an error here:
beeTimer.stop();
The error message: The local variable beeTimer may not have been initialized
Here is where it was initialized:
try {
Timer beeTimer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("bee movin!");
beeY[0] += beeSpeed;
beeLabel.setLocation(beeX, beeY[0]);
if (beeY[0] + 106 > (frame.getContentPane().getHeight() - 200)) {
beeTimer.stop();
}
}
});
beeTimer.start();
} finally{}
and here is my entire code up to now:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import javax.swing.*;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
//let the can be draggable by the mouse
class DraggableLabel extends JLabel implements MouseListener, MouseMotionListener {
private Point mouseOffset;
public DraggableLabel(ImageIcon icon) {
super(icon);
addMouseListener(this);
addMouseMotionListener(this);
}
public void mousePressed(MouseEvent e) {
mouseOffset = e.getPoint();
}
public void mouseDragged(MouseEvent e) {
Point newMousePos = e.getLocationOnScreen();
newMousePos.translate(-mouseOffset.x, -(newMousePos.y - getLocation().y));
setLocation(newMousePos);
}
// The following methods are not needed for dragging, but must be implemented because we implement the MouseListener and MouseMotionListener interfaces.
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
}
class App{
public static void main(String[] args){
//declare the frame, or window of the game
JFrame frame = new JFrame("Game");
//declare the image variables
ImageIcon can = null;
ImageIcon bee = null;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
//load the can image file
try {
File canFile = new File("assets/can.png");
BufferedImage originalCan = ImageIO.read(canFile);
if (originalCan == null) {
throw new IOException("Unable to read image file: " + canFile.getName());
}
int canWidth = 75;
int canHeight = 136;
Image icon = originalCan.getScaledInstance(canWidth, canHeight, Image.SCALE_SMOOTH);
can = new ImageIcon(icon);
} catch (IOException e) {
e.printStackTrace();
}
//load the bee image file
try {
File beeFile = new File("assets/bee.png");
BufferedImage originalBee = ImageIO.read(beeFile);
if (originalBee == null) {
throw new IOException("Unable to read image file: " + beeFile.getName());
}
int beeWidth = 40;
int beeHeight = 61;
Image icon = originalBee.getScaledInstance(beeWidth, beeHeight, Image.SCALE_SMOOTH);
bee = new ImageIcon(icon);
} catch (IOException e) {
e.printStackTrace();
}
//import the bee image
Image beeImage = bee.getImage();
ImageIcon beeFall = new ImageIcon(beeImage);
JLabel beeLabel = new JLabel(beeFall);
//set bee spawn location
int beeX = (screenSize.width - bee.getIconWidth()) / 2;
final int[] beeY = {0};
beeLabel.setBounds(beeX, beeY[0], 60, 106);
frame.getContentPane().add(beeLabel);
//bee falling behavior
int beeSpeed = 5;
try {
Timer beeTimer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("bee movin!");
beeY[0] += beeSpeed;
beeLabel.setLocation(beeX, beeY[0]);
if (beeY[0] + 106 > (frame.getContentPane().getHeight() - 200)) {
beeTimer.stop();
}
}
});
beeTimer.start();
} finally{}
//import the can image as draggable
DraggableLabel label = new DraggableLabel(can);
frame.getContentPane().setLayout(null);
label.setSize(can.getIconWidth(), can.getIconHeight());
frame.getContentPane().add(label);
// Position can in the center horizontally and just above the bottom vertically
int x = (screenSize.width - can.getIconWidth()) / 2;
int y = screenSize.height - can.getIconHeight() - 175; // 50 pixels above the bottom
label.setLocation(x, y);
//make frame visible
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Any suggestions would be greatly appreciated!
答案1
得分: 0
不要使用 Swing 标签或按钮来制作您的游戏。相反,创建一个组件(例如继承自 JPanel)并覆盖 paintComponent() 方法。
使用 Swing 定时器来触发“自动”操作,使用鼠标和键盘事件来触发用户触发的操作。计算状态,然后使用 repaint() 来告诉 Swing 需要渲染该组件。Swing 会在它感觉合适的时候进行渲染。
要获取更多提示和库,只需使用正确的 StackOverflow 搜索:
https://stackoverflow.com/search?q=java+game+programming
英文:
For your game do not use swing labels or buttons at all.
Instead, create one component (derived from e.g. JPanel) and override the paintComponent() method.
Use Swing Timers to trigger 'automatic' actions, use Mouse and Keyboard Events to trigger user triggered actions. Calculate the state, then use repaint() to tell Swing it needs to render the component. Swing will do it as soon as it 'feels like'.
For more hints/libraries just use the correct StackOverflow search:
https://stackoverflow.com/search?q=java+game+programming
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论