在Java中有一种方法可以使标签在没有用户干预的情况下移动吗?

huangapple go评论60阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年2月24日 04:45:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75550153.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定