显示多个图像而不创建新变量 [英] Displaying multiple images without creating new variables

查看:58
本文介绍了显示多个图像而不创建新变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Java编写一个程序来模拟一副基本的纸牌.无需考虑任何特定的游戏,而只是一堆不错的旧纸牌,您可以随意移动和翻转(当然,总共52张纸牌的限制).这是我当前的代码:

I'm making a program in java to emulate a basic deck of cards; no specific game in mind, just a good old deck of cards that you can move around and flip over freely (of course, with the limit of 52 total cards). Here is my current code:

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个新变量(仅供参考,我为我编写了一些代码)想要,但是到目前为止它什么也没做,只会引起问题,所以我决定从头开始,并询问专家我应该怎么做.

However, this program will only let me have one card out at a time until I click on the deck in the top right corner and reshuffle(redefine the area of the image to be read with a random number generator). What I would like to do is be able to have any amount of cards from 0 and 52 out at any given time by clicking the deck without creating 51 new variables for the other cards(fyi I have written out some of the code for what I want, but so far it's done nothing but cause problems so I decided to start from scratch and ask the experts what I should do).

在问了这个之后才意识到,这是一个比我想发布的代码稍旧的代码,并且可能还有很多其他问题.由于它们已经修复,请忽略它们.

just realized after asking this, this is a slightly older code than I wanted to post, and has probably has plenty of other problems as well. Please ignore those, as they are already fixed.

推荐答案

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

There are two basic approaches, the both kind of follow the same basic concept...

生成图像列表并绘制图像...

Generate a list of images and paint them...

创建一个自定义组件,该组件单独负责绘制单个卡.这样做的好处是,它通常易于管理和使用现有功能.

Create a custom component which is singularly responsible for painting a single card. The benefit of this is that it's generally easy to manage and uses what is already available.

缺点是,您需要负责布局管理(一点点).

The draw back is, you're going to need take charge the the layout management (a little).

您将从 LayredPane 开始将允许您(虚拟地)上下推卡,并将其放置在您想要的位置.

You would start with a LayredPane, which will allow you to push cards up and down (virtually) as well as allow them to be placed where you want them.

个人而言,我将创建一个单独的MouseListener/MouseMotionListener并将其注册到每个卡面板",这将允许轻松地相对于LayeredPane控制卡(将它们移动到顶部)例如当它们被点击时)

Personally, I would create a single MouseListener/MouseMotionListener and register it to each of the "Card Panels", this will allow to easily control the cards with relation to the LayeredPane (moving them to the top when they are clicked for example)

另一种选择是加载每个卡图像并将其放入List中.然后,基本上,您只需在列表中简单地遍历列表,就可以在paintComponent方法中使用它们进行绘制.

The other choice would be to load each of the card images and place them into List. Then basically, you would then simply paint them with in the paintComponent method by simply iterating through the list.

问题是,您突然变得对z顺序的整个管理负责,并检查单击的内容.

The problem is, you suddenly become responsible for the entire management of the z-order and checking what is clicked.

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

Customising the painting of the images (such as adding borders) becomes a little cumbersome, as you need to do this for each image and decide when. This would be easier if they were a custom component

  • 当心过度使用static变量,这可能会迅速导致您进入问题区域并试图确定实际引用的内容
  • 请勿从paintComponent呼叫paint. paint实际上会调用paintComponent本身,这可能会产生堆栈溢出错误
  • 请勿在可能调用repaintpaintXxx方法中调用任何方法,由于绘画的工作方式,这只会导致EDT仅继续绘画您的组件,最终将消耗您的CPU. ..
  • Beware of the over use of static variables, this can quickly lead you into problem areas with trying to do determine what is actually being referenced
  • Don't call paint from paintComponent. paint actually calls paintComponent itself, which could produce a stack overflow errors
  • Don't call any method from within a paintXxx method that might call repaint, because of the way painting works, this will simply cause the EDT to simply keep painting your component, which will eventually consume your CPU...

仔细研究执行自定义绘画在AWT和Swing中绘画以获取更多详细信息

Take a closer look at Performing Custom Painting and Painting in AWT and Swing for more details

这篇关于显示多个图像而不创建新变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆