简体   繁体   English

Java Swing游戏板

[英]Java Swing Game Board

I'm working on a large Monopoly game as a project in school and ran into a pretty big performance issue. 作为学校的一个项目,我正在开发大型Monopoly游戏,但遇到了相当大的性能问题。 Right now I have a paint method that is drawing the entire board everytime it gets called... this is a big problem because the board only needs to be drawn once in the beggining and only whenever someone buys a house or something. 现在,我有一种绘制方法,每次调用它时都在绘制整个木板...这是一个大问题,因为该木板仅在开始时需要绘制一次,并且仅在有人购买房屋或东西时才绘制一次。 The only components I want to be painted a lot are the players because they are the ones that move around the most and need to be painted. 我想要绘画的唯一组件是玩家,因为它们是移动最频繁的组件,需要绘画。

Here is the paint method of my board: 这是我的木板的涂漆方法:

public void paint(Graphics g){
        super.paint(g);
        Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //Draw all the spots
        for(int i = 0; i < spots.length; i++){
            g2d.setColor(Color.white);
            g2d.fill(spots[i].getRect());
            if(spots[i] instanceof Property){
                if(i < 10){
                    g2d.setColor(spots[i].getColor());
                    Rectangle temp = new Rectangle(spots[i].getRect().x,spots[i].getRect().y,spots[i].getRect().width,spots[i].getRect().height/3);
                    g2d.fill(temp);
                    g2d.setColor(Color.black);
                    g2d.drawString(((Property)spots[i]).getName(), spots[i].getRect().x, spots[i].getRect().height);
                }else if(i >= 10 && i < 20){
                    g2d.setColor(spots[i].getColor());
                    Rectangle temp = new Rectangle(spots[i].getRect().x+spots[i].getRect().width-spots[i].getRect().width/3,spots[i].getRect().y,spots[i].getRect().width/3,spots[i].getRect().height);
                    g2d.fill(temp);
                }else if(i >= 20 && i < 30){
                    g2d.setColor(spots[i].getColor());
                    Rectangle temp = new Rectangle(spots[i].getRect().x,spots[i].getRect().y+spots[i].getRect().height-spots[i].getRect().height/3,spots[i].getRect().width,spots[i].getRect().height/3);
                    g2d.fill(temp);
                    g2d.setColor(Color.black);
                    g2d.drawString(((Property)spots[i]).getName(), spots[i].getRect().x, spots[i].getRect().y);
                }else if(i >= 30 && i < 40){
                    g2d.setColor(spots[i].getColor());
                    Rectangle temp = new Rectangle(spots[i].getRect().x,spots[i].getRect().y,spots[i].getRect().width/3,spots[i].getRect().height);
                    g2d.fill(temp);
                }
            }else if(spots[i] instanceof Railroad){
                if(i == 5)
                    g2d.drawImage(imgTrain3, spots[i].getRect().x, spots[i].getRect().y+spots[i].getRect().height/4, null);
                else if(i == 15)
                    g2d.drawImage(imgTrain4, spots[i].getRect().x+spots[i].getRect().width/4, spots[i].getRect().y, null);
                else if(i == 25)
                    g2d.drawImage(imgTrain1, spots[i].getRect().x, spots[i].getRect().y+spots[i].getRect().height/4, null);
                else if(i == 35)
                    g2d.drawImage(imgTrain2, spots[i].getRect().x+spots[i].getRect().width/4, spots[i].getRect().y, null);
            }else if(spots[i] instanceof Chance){
                if(i == 7)
                    g2d.drawImage(imgChance2, spots[i].getRect().x, spots[i].getRect().y, null);
                else if(i == 22)
                    g2d.drawImage(imgChance2, spots[i].getRect().x, spots[i].getRect().y+spots[i].getRect().height/3, null);
                else if(i == 36)
                    g2d.drawImage(imgChance3, spots[i].getRect().x, spots[i].getRect().y, null);
            }else if(spots[i] instanceof Community){
                if(i == 2)
                    g2d.drawImage(imgComm1, spots[i].getRect().x, spots[i].getRect().y+spots[i].getRect().height/3, null);
                else if(i == 17)
                    g2d.drawImage(imgComm2, spots[i].getRect().x, spots[i].getRect().y, null);
                else if(i == 33)
                    g2d.drawImage(imgComm3, spots[i].getRect().x+spots[i].getRect().width/3, spots[i].getRect().y, null);
            }else{
                g2d.setColor(spots[i].getColor());
                g2d.fill(spots[i].getRect());
            }
        }
        //Draw the outline of every spot
        g2d.setColor(Color.black);
        for(Spot index : spots)
            g2d.draw(index.getRect());
        //Draw the outline of the whole board
        g2d.drawRect(newX, newY, boardSize, boardSize);
        //Draw the Players location
        for(Player index : players)
             g2d.drawImage(index.getImage(), index.getLoc().x, index.getLoc().y, null);
    }

Basically a ton of text to represent the board, and this is being done everytime the board repaints. 基本上,一吨文字代表了电路板,并且每次电路板重新粉刷时都会这样做。 Any advice? 有什么建议吗?

Bonus question: I also just started working on the move animation for the players after they roll (currently just jump to the destination). 奖励问题:我也刚开始为玩家滚动后的移动动画制作(当前只是跳到目的地)。 I created a timer that takes 1 second per roll (ex: if you roll a 5 it takes 5 seconds to move). 我创建了一个计时器,每滚动需要1秒(例如:如果滚动5,则移动需要5秒钟)。 Only problem is that I don't really have a good idea for how to show the slow moving of the player piece from the starting location to end. 唯一的问题是,我对如何显示播放器从起始位置到结束的缓慢移动并没有真正的好主意。 Just need someone to give me a basic idea so I can head in the right direction. 只要有人给我一个基本的想法,我就可以朝正确的方向前进。

Paint the board to a BufferedImage . 画板到BufferedImage In the paint method, draw the image of the board, then draw the pieces over the top. 在绘画方法中,绘制木板的图像,然后在顶部绘制碎片。

BTW - when using Swing, don't paint in top-level containers, instead use a JComponent or JPanel . 顺便说一句-使用Swing时,请勿在顶层容器中绘制,而应使用JComponentJPanel For the latter two, override paintComponent(Graphics) rather than paint(Graphics) . 对于后两个,请重写paintComponent(Graphics)而不是paint(Graphics)

You can avoid redrawing the whole surface with: jComponent.repaint(someRectangle) . 您可以避免使用jComponent.repaint(someRectangle)重绘整个表面。 See also this example . 另请参见本示例

However, you have to figure yourself the rectangle (or rectangles) that needs updating between each moves. 但是,您必须弄清楚自己需要在每次移动之间进行更新的矩形(或多个矩形)。 You not only need the rectangles where new things appear, but also where things disappear. 您不仅需要出现新事物的矩形,还需要消失的矩形。

For animations in Swing, look at this tutorial . 有关Swing中的动画,请参阅本教程 You'll notice both the examples I linked in this post are from the official Swing tutorial . 您会注意到我在本文中链接的两个示例均来自Swing官方教程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM