0

Graphics2D 动画,无法理解为什么paintComponent 只绘制一次形状然后停止。我也无法理解为什么我的计时器计数器变量没有增加。我已经为此努力了一个多小时,有人可以将我推向正确的方向吗?

俄罗斯方块

package Tetris;
import javax.swing.JLabel;
import java.util.ArrayList;
public class Tetri {

private int xCoords= (int)(Math.random()*10);
private int yCoords=0;
private int shapeType;
private int orientation=0;

public Tetri(int shapeT){
    shapeType = shapeT;

}
public int getOrient(){
    return orientation;
}
public void setOrient(int orient){
    orientation = orient;
}
public void setXCoords(int coords){
    xCoords = coords;

}
public int getXCoords(){

    return xCoords;
}
public void setYCoords(int coords){
    yCoords = coords;
}
public int getYCoords(){

    return yCoords;
}

public int getShape(){

    return shapeType;
}



}

移动矩形

package Tetris;
import javax.swing.JFrame;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JPanel;
import java.awt.Color;
import javax.swing.Timer;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
public class MovingRectangle {

public static void main(String[] args){
    new MovingRectangle();
}

public MovingRectangle() {
    EventQueue.invokeLater(new Runnable(){
        @Override
        public void run(){
            JFrame frame = new JFrame("Tetris");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new GridLayout(0,1));
            frame.add(new TestPane(Color.RED));
            frame.setSize(1000,800);
            frame.setVisible(true);

        }

    });
}

测试窗格

public class TestPane extends JPanel {

    private Graphics g0;
    private int unit = 50;
    private ArrayList<Tetri> shapeList = new ArrayList<Tetri>();
    int timercount =1;

    public TestPane(Color foreground){
        setForeground(foreground);
        this.setBackground(Color.BLUE);
        Timer timer = new Timer(2000,new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e){
            System.out.println("timercount :"+timercount);
            timercount = timercount++;
            shapeList.add(new Tetri((int)(Math.random()*2)));
            System.out.println("shapeList size : "+shapeList.size());
            repaint();
            }
        });
        timer.start();

    }
    @Override
    public void paintComponent(Graphics g){
        g0 = g;
        super.paintComponent(g);
        if(shapeList.size()>0){

        Tetri current = shapeList.get(0);

            if(current.getShape()==0){
                                                             createShape0(current.getXCoords(),current.getYCoords(),current.getOrient());
            }
            if(current.getShape()==1){
                createShape1(current.getXCoords(),current.getYCoords(),current.getOrient());
            }
            current.setYCoords(current.getYCoords()+50);
        }
        else{shapeList.add(new Tetri((int)(Math.random()*2)));}


    }
    public void createShape0(int xc,int yc,int orien){
        int yPixel= yc*50;
        int xPixel= xc*50;

        Graphics2D g2d = (Graphics2D) g0.create();
        g2d.setColor(Color.RED);
        if(orien==0){
            g2d.drawRect(xPixel, yPixel, unit*4, unit);
        }
        if(orien==1){
            g2d.drawRect(xPixel, yPixel, unit, unit*4);
        }



    }
    public void createShape1(int xc,int yc, int orien){
        int yPixel= yc*50;
        int xPixel= xc*50;

        Graphics2D g2d = (Graphics2D) g0.create();
        g2d.setColor(Color.GREEN);
        if(orien==0){
        g2d.drawRect(xPixel, yPixel, unit*3, unit);
        g2d.drawRect(xPixel+50, yPixel+50,unit,unit);
        }
        if(orien==1){
        g2d.drawRect(xPixel+50, yPixel-50, unit, unit*3);
        g2d.drawRect(xPixel, yPixel,unit,unit);
        }
        if(orien==2){
            g2d.drawRect(xPixel, yPixel, unit*3, unit);
            g2d.drawRect(xPixel+50, yPixel-50,unit,unit);
        }
        if(orien==3){
            g2d.drawRect(xPixel+50, yPixel-50, unit, unit*3);
            g2d.drawRect(xPixel+100, yPixel,unit,unit);
        }
    }

}
}
4

1 回答 1

1

我有一个清单,但让我们从最明显的开始。

你的“运动”计算很遥远。

int yPixel = yc * 50;
int xPixel = xc * 50;

这导致您的形状“跳跃”预期更大的距离......事实上,我根本找不到任何理由让您“修改”这些值。简单地让它们读作......

int yPixel = yc;
int xPixel = xc;

形状移动得很好...

代码审查

  • 不要维护对您未创建的任何图形上下文的任何引用。这些引用可以在其他 UI 组件之间共享,并且不能保证引用在一个绘制周期中,在下一个绘制周期中会相同。如果要绘制到图形上下文,请将其作为参数传递给需要进行绘制的方法。
  • 如果您创建了一个图形上下文 ( Graphics2D g2d = (Graphics2D) g.create();),那么您有责任在g2d.dispose()完成后处理它 ( )。否则你会慢慢消耗系统资源,直到你的应用程序崩溃(从经验来看——这是一个很难找到的错误;))

你似乎正在艰难地处理这个过程。Shape您应该根据Tetri知道如何“绘制”自身的知识为每个创建一个类。这样你就可以在你的绘画循环中简单地将图形上下文传递给它,而不用关心。这使得随着时间的推移添加新部件变得更加容易。

如果您将这些部分中的每一个都基于 a java.awt.Shape,则转换形状和旋转它们会变得非常容易。

看看2D Graphics,特别是Working with Geometry

于 2013-03-08T01:20:26.323 回答