java - 在背景上设置对象/图像的位置
问题描述
我目前正在开发 Ludo/Dude 不要生气的游戏版本,我遇到了一些问题,其中一个较大的问题是我无法将令牌放置在我想要的位置。我需要在开始时将标记设置在某些位置,并且需要一种方法来计算它们在屏幕上的移动位置,代码如下:
public class Ludo extends JFrame{
private BackgroundPanel imagePanel=null;
private JLabel jlTokenBlue1=null;
private JLabel jlTokenBlue2=null;
...
public Ludo(){
try{
//Creating background panel
imagePanel = new BackgroundPanel("ludoBoard.png");
add(imagePanel);
//create tokens for play
BufferedImage imageTokenBlue1 = ImageIO.read(new File("blue1.png"));
jlTokenBlue1 = new JLabel(new ImageIcon(imageTokenBlue1));
BufferedImage imageTokenBlue2 = ImageIO.read(new File("blue2.png"));
jlTokenBlue2 = new JLabel(new ImageIcon(imageTokenBlue2));
BufferedImage imageTokenBlue3 = ImageIO.read(new File("blue3.png"));
jlTokenBlue3 = new JLabel(new ImageIcon(imageTokenBlue3));
BufferedImage imageTokenBlue4 = ImageIO.read(new File("blue4.png"));
jlTokenBlue4 = new JLabel(new ImageIcon(imageTokenBlue4));
BufferedImage imageTokenRed1 = ImageIO.read(new File("red1.png"));
jlTokenRed1 = new JLabel(new ImageIcon(imageTokenRed1));
BufferedImage imageTokenRed2 = ImageIO.read(new File("red2.png"));
jlTokenRed2 = new JLabel(new ImageIcon(imageTokenRed2));
BufferedImage imageTokenRed3 = ImageIO.read(new File("red3.png"));
jlTokenRed3 = new JLabel(new ImageIcon(imageTokenRed3));
BufferedImage imageTokenRed4 = ImageIO.read(new File("red4.png"));
jlTokenRed4 = new JLabel(new ImageIcon(imageTokenRed4));
imagePanel.add(jlTokenBlue1);
imagePanel.add(jlTokenBlue2);
imagePanel.add(jlTokenBlue3);
imagePanel.add(jlTokenBlue4);
imagePanel.add(jlTokenRed1);
imagePanel.add(jlTokenRed2);
imagePanel.add(jlTokenRed3);
imagePanel.add(jlTokenRed4);
jlTokenRed1.setLocation(250,500);
}//End of try
catch(IOException ioe){
System.out.println("The background image cannot be loaded...");
}catch(NullPointerException npe){
npe.getMessage();
}
.
.
.
class BackgroundPanel extends JPanel
{
Image image;
public BackgroundPanel(String imageName)
{
try
{
image = javax.imageio.ImageIO.read(new java.net.URL(getClass().getResource(imageName), imageName));
}
catch (Exception e) { /*handled in paintComponent()*/ }
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if (image != null)
g.drawImage(image, 0,0,this.getWidth(),this.getHeight(),this);
}
}
我尝试使用 setLocation 和 repaint,但无法将令牌设置为我想要的位置。我想将令牌以各自的颜色放入白色字段中,非常感谢任何帮助和/或建议。下面是它现在的样子的图片。如果您想自己检查文件,这里是包含所有内容的驱动器的链接。drive.google.com/open?id=1xap_xz2K3SF37XQfRN3Y_LHoTHg0HNox !
解决方案
我已经为你的游戏开始了一些代码。您必须完成代码。
这是我创建的 GUI。
我做的第一件事是使用模型/视图/控制器模式。通过分离游戏的逻辑功能,我可以一次专注于一个部分。
这是我创建的模型。它不完整,但我想你可以看到我想要做的事情。我把他的类放在它自己的模型包中。
package com.ggl.ludo.model;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class LudoModel {
private final BufferedImage gameBoard;
private final BufferedImage[] imageTokenBlue;
public LudoModel() {
imageTokenBlue = new BufferedImage[4];
imageTokenBlue[0] = getImage("blue1.png");
imageTokenBlue[1] = getImage("blue2.png");
imageTokenBlue[2] = getImage("blue3.png");
imageTokenBlue[3] = getImage("blue4.png");
gameBoard = getImage("ludoBoard.png");
}
public BufferedImage getGameBoard() {
return gameBoard;
}
public BufferedImage[] getImageTokenBlue() {
return imageTokenBlue;
}
private BufferedImage getImage(String fileName) {
try {
return ImageIO.read(getClass().getResourceAsStream("/" + fileName));
} catch (IOException e) {
return null;
}
}
}
所有这些代码都会读取图像,并最终创建游戏的逻辑模型。它根本不关心视图或控制器代码。
我创建的下一个类是 DrawingPanel 类。此类绘制游戏板,并最终在板上绘制棋子。零件信息的位置进入模型。
package com.ggl.ludo.view;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;
import com.ggl.ludo.model.LudoModel;
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
private LudoFrame frame;
private LudoModel model;
public DrawingPanel(LudoFrame frame, LudoModel model) {
this.frame = frame;
this.model = model;
int width = model.getGameBoard().getWidth();
int height = model.getGameBoard().getHeight();
this.setPreferredSize(new Dimension(width, height));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(model.getGameBoard(), 0, 0, this);
// Your piece drawing code goes here
}
}
接下来,我创建了一个类来保存 JFrame。可以删除 JScrollPane 代码。我的旧笔记本电脑无法显示和你一样大的游戏板。如果您希望其他人玩此游戏,请记住一些事情。
我把菜单代码放在它自己的方法中。我喜欢把不同的东西分开。我虚弱的头脑无法同时处理太多的进程。
package com.ggl.ludo.view;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import com.ggl.ludo.model.LudoModel;
public class LudoFrame {
private DrawingPanel drawingPanel;
private LudoModel ludoModel;
public LudoFrame(LudoModel ludoModel) {
this.ludoModel = ludoModel;
generateGUIControl();
}
private void generateGUIControl() {
JFrame frame = new JFrame("Ludo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(createMenu());
drawingPanel = new DrawingPanel(this, ludoModel);
JScrollPane scrollPane = new JScrollPane(drawingPanel);
scrollPane.setPreferredSize(new Dimension(400, 400));
frame.add(scrollPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JMenuBar createMenu() {
JMenuBar ludoMenuBar = new JMenuBar();
JMenu ludoMenuFirst = new JMenu("Information");
ludoMenuBar.add(ludoMenuFirst);
JMenuItem jmiDescription = new JMenuItem("Description");
JMenuItem jmiHelp = new JMenuItem("Help");
JMenuItem jmiRestart = new JMenuItem("Restart");
JMenuItem jmiExit = new JMenuItem("Exit");
ludoMenuFirst.add(jmiDescription);
ludoMenuFirst.add(jmiHelp);
ludoMenuFirst.add(jmiRestart);
ludoMenuFirst.add(jmiExit);
ludoMenuBar.add(ludoMenuFirst);
return ludoMenuBar;
}
}
最后是启动整个过程的驱动类。您必须在事件调度线程 (EDT) 上启动 Swing 应用程序。对 SwingUtilities invokeLater 的调用可确保您的应用程序在 EDT 上启动。
package com.ggl.ludo;
import javax.swing.SwingUtilities;
import com.ggl.ludo.model.LudoModel;
import com.ggl.ludo.view.LudoFrame;
public class Ludo implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Ludo());
}
@Override
public void run() {
new LudoFrame(new LudoModel());
}
}
我希望这对你有所帮助。至于控制器,我建议您使用鼠标监听器并在游戏板上绘制游戏块。
请记住,有关游戏棋子位置的信息会进入模型。视图绘制代码从模型中的信息中提取。
推荐阅读
- c - 检查值是否在未定义的枚举中?
- excel - 如果日期重复但数据是唯一的,如何匹配日期然后将相应数据从一个电子表格复制到另一个电子表格?
- python - 返回满足熊猫数据框中条件的数据框位置的第一个值的位置
- sql - 需要帮助加入 2 个表并使用 BigQuery SQL 以独特的方式汇总它们
- reporting-services - 第一个新手问题:SSRS Tablix 可见性参数
- python - Knn 预测在 y_test 上达到 100%
- python - 无法拆分字符串
- python - 删除 CSV 文件中的方括号
- python - 是否可以结合热键和鼠标单击来选择菜单项?
- c# - 从组合框中获取价值?