当前位置: 首页 > 知识库问答 >
问题:

在不创建新变量的情况下显示多个图像 [已关闭]

汪欣德
2023-03-14

有关您编写的代码问题的问题必须在问题本身中描述特定问题,并包含有效的代码来重现它。有关指导,请参阅 SSCCE.org。

我正在用java制作一个程序来模拟一副基本的纸牌;没有特定的游戏,只是一副很好的旧牌,你可以四处移动并自由翻转(当然,总共有52张牌的限制)。这是我当前的代码:

package cards;
import java.awt.Color;
import java.awt.Graphics;
import java.util.List;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
public class DeckOfCards extends JPanel{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    static final int SIZE = 500;
    public static String side = "back";
    static final int xSize = 73;
    static final int ySize = 98;
    static int x = SIZE - xSize;
    static int y = 0;
    static int i, j = 0;
    static int inDeck = 52;
    public boolean flipped = false;
    static final DeckOfCards m = new DeckOfCards();
    static final Color rgb = new Color(0, 180, 10);
    static final JFrame frame = new JFrame();
    static List<Integer> yList = new ArrayList<Integer>();
    static List<Integer> xList = new ArrayList<Integer>();
    Random random = new Random();
    int randX = random.nextInt(13) * xSize; 
    int randY = random.nextInt(4) * ySize;
    int xRand = randX;
    int yRand = randY;
    public static void main(String[] args){
        frame.setTitle("Virtual Cards");
        frame.add(m);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(SIZE, SIZE);
        frame.setResizable(false);
        m.setBackground(rgb);
        frame.setVisible(true);
    }
    public void mouseClick(){
        addMouseListener(new MouseAdapter(){
            @Override
            public void mouseClicked(MouseEvent e){
                if(((e.getX() >= x && e.getX() <= (x + xSize)) && (e.getY() >= y && e.getY() <= (y + ySize))) && (flipped == false)){
                    flipped = true;
                    side = "front";
                }else if(((e.getX() >= x && e.getX() <= (x + xSize)) && (e.getY() >= y && e.getY() <= (y + ySize))) && (flipped == true)){
                    flipped = false;
                    side = "back";
                }else if((e.getX() >= SIZE - xSize && e.getX() <= SIZE) && (e.getY() >= 0 && e.getY() <= SIZE - (SIZE - ySize)) && inDeck > 0){
                    randCardFace(random);
                    inDeck--;
                    side = "back";
                    x = SIZE - xSize;
                    y = 0;
                }
            }

        });
    }
    public void mouseMove(){
        addMouseMotionListener(new MouseMotionAdapter(){
            @Override
            public void mouseDragged(MouseEvent e){
                if(((e.getX() >= x && e.getX() <= (x + xSize)) && (e.getY() >= y && e.getY() <= (y + ySize)))){
                    x = e.getX() - (xSize / 2);
                    y = e.getY() - (ySize / 2); 
                }
            }
        });
    }
    public DeckOfCards(){
        mouseClick();
        mouseMove();
    }
    public void randCardFace(Random random){
            randX = random.nextInt(13) * xSize;
            randY = random.nextInt(4) * ySize;
    }
    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        paint(g);
    }
    public void paint(Graphics g){
        try{
            if(inDeck > 0){
                g.drawImage(ImageIO.read(getClass().getResource("images/deck.png")), SIZE - xSize, 0, null, null);
            }
            BufferedImage image = ImageIO.read(getClass().getResource("images/"+side+".png"));
            if(side != "back"){
                image = image.getSubimage(randX, randY, xSize, ySize);
            }
            g.drawImage(image, x, y, xSize, ySize, null, null);
        }catch(IOException e){
            e.printStackTrace();
        }
        m.repaint();
    }
}

但是,该程序一次只能让我拿出一张牌,直到我单击右上角的牌组并重新洗牌(使用随机数生成器重新定义要读取的图像区域)。我想做的是,通过单击套牌,能够在任何给定时间从0和52中拿出任何数量的牌,而无需为其他卡牌创建51个新变量(仅供参考,我已经为我想要的内容编写了一些代码,但到目前为止,它除了引起问题之外什么也没做,所以我决定从头开始并询问专家我应该做什么)。

编辑:

问了这个问题后才意识到,这是一个比我想发布的代码稍旧的代码,可能还有很多其他问题。请忽略这些,因为它们已经修复。

共有2个答案

通奕
2023-03-14

有两种基本方法,两种方法都遵循相同的基本概念…

生成图像列表并绘制它们。。。

创建一个自定义组件,专门负责绘制一张卡片。这样做的好处是,它通常易于管理,并且可以使用现有的资源。

缺点是,你需要负责版面管理(一点点)。

你可以从一个< code>LayredPane开始,它将允许你(虚拟地)上下推动卡片,并允许它们被放置在你想要的地方。

就我个人而言,我会创建一个单独的< code > MouseListener /< code > MouseMotionListener 并将其注册到每个“卡片面板”,这将允许轻松地控制与< code>LayeredPane相关的卡片(例如,当它们被单击时将它们移动到顶部)

另一种选择是加载每个卡图像并将其放入列表中。然后,基本上,您只需在“油漆组件”方法中通过简单地迭代列表来绘制它们。

问题是,你突然开始负责z-order的整个管理,并检查点击了什么。

自定义图像的绘制(例如添加边框)变得有点麻烦,因为您需要为每个图像执行此操作并决定何时执行。如果它们是自定义组件,这会更容易

    < li >小心过度使用< code>static变量,这可能会使您在尝试确定实际引用的内容时很快陷入问题区域 < li >不要从< code>paintComponent调用< code>paint。< code>paint实际上调用< code>paintComponent本身,这可能会产生堆栈溢出错误 < li >不要从可能调用< code>repaint的< code>paintXxx方法中调用任何方法,因为绘制的工作方式只会导致EDT继续绘制您的组件,最终会消耗您的CPU...

详细了解在AWT和Swing中执行自定义绘画和绘画,了解更多详情

宦兴朝
2023-03-14

你发布的代码有很多问题,所以请允许我给你一些建议。如果代码不正确,请更正:

    < li >您应该覆盖JPanel的paintComponent方法,而不是它的paint方法,除非您需要更改组件的子组件和边框如何绘制它们自己的行为(您不需要)。 < li >切勿在paint或paintComponent中读入图像,因为这会降低渲染速度,从而降低程序对爬行的响应速度。 < li >永远不要从paint或paintComponent中调用< code>repaint()。 < li >您正在从paintComponent内部调用paint,这可能会导致可怕的递归,因为paint调用paintComponent。千万不要这样。 < li >您的代码过度使用了静态。这将阻止它的可扩展性,并限制它的可修改性。 < li >您在构建GUI时没有先创建一个合适的模型。Card程序已经很好地描述了公共模型。这些包括Java版本的使用枚举,一个枚举用于套装,一个枚举用于等级。在处理他们的图像对应物之前,先把卡片、卡片组、玩家、游戏的抽象概念和类弄下来。

链接到我关于纸牌游戏的其他一些答案和代码:

    < li >带有可拖放卡片图像的小程序 < li >卡模型概念 < li >使用一副卡片
 类似资料:
  • 我不熟悉svg。我有一个图像,我想旋转。我已经使用旋转变换旋转了图像,并给了它一个角度和我想要旋转图像的点的坐标。 我的要求是,当我在旋转后拖动图像时,我想检查左上角是否在边界区域内。这在旋转之前起作用。但在旋转后,似乎在将此变换应用于图像后,我的坐标系也以相同的角度旋转。这给我带来了一些问题。 有没有办法在不旋转原始坐标系的情况下旋转图像?此外,若旋转图像,图像的x和y属性也不会更新。

  • 我的javaFX项目中有一辆汽车,当空间被挤压时,汽车(节点)的位置应该改变(汽车应该平滑地跳跃)。所以我使用了一个事件处理程序来调用一个名为< code>moveUp()的方法 这创建了一个新的线程,其中汽车的速度以75毫秒的间隔改变10次。 如果我不使用其他线程,GUI线程将被冻结,如果我不使用Thread.sleep(),汽车将突然跳跃(不顺利)。这段代码做得很好。但是我了解到 并不能保证线

  • 问题内容: 我想用Python(不是数组)中的一个创建10个变量。像这样: 我想创建的变量名,在这种情况下: ,,,…, 我不想一个数组 我有一个坐标图(640 x 480)。我正在确定像素颜色为白色的坐标。地面上有3个球,我想获取每个球的中心坐标,因此,如果要评估的坐标距离最后一个球很近,则x和y坐标将被平均(如果该坐标属于a)新球的坐标将属于新坐标组。 问题答案: 您不应该这样做,但是如果您真

  • 我正在处理一个简单的Docker映像,其中包含大量环境变量。你能像docker-compose一样导入环境变量文件吗?我在docker文件留档中找不到任何相关信息。 Dockerfile 我想重新表述这个问题的一个好方法是:如何在Dockerfile中高效地加载多个环境变量?如果无法加载文件,则无法将docker文件提交到GitHub。

  • 我有一个dockerfile来启动Tomcat。我想从那个dockerfile创建而不运行图像,这样在docker图像中我就可以看到图像了。docker run-it将我登录到容器,但我不想创建容器并登录到它。 我可以通过哪个命令来实现这一点?

  • 问题内容: 我在JSF页面中有这3个字段 我也有一个具有以下属性的后备豆: 我希望在将某些值插入字段val1和val2中而不刷新页面时,outputText元素自动更改其值。结果变量应以这种方式计算(它正在计算百分比):(val1 * val2)/ 100 您能帮我解决我的一些疑问吗?: 我知道为此,我需要javascript或AJAX之类的东西。您认为最好的方法是什么? 我很想知道我如何使用AJ