在多线程中使用 awt Paint

发布于 2024-09-27 11:14:53 字数 2306 浏览 2 评论 0原文

我有一个学校项目,我想把这个献给新年,我提出的项目是一个文本烟花,我使用字符和符号作为爆炸粒子,并不断改变它们在 Paint 中的 X 和 Y 位置( )。 我对如何一起使用 Paint 和 Thread 感到困惑。问题是它没有在屏幕上绘画或者线程可能没有启动。 (我真的不能告诉,对不起)。问题是我没有收到任何错误,它只是不起作用:(

我认为代码有点长,谢谢您阅读它。

它应该如何工作:当用户点击时, Firework 线程将在鼠标位置启动, 这个 Firework 类有一个绘制循环,用于重新创建增量爆炸。所以基本上,我希望用户创建多个爆炸,这就是我将其设为线程的原因。

这是主小程序:

public class TBFireworks extends Applet implements MouseListener
{
    public void init()
    {
        setBackground( Color.black );
        addMouseListener( this );
    }

    public void mouseEntered( MouseEvent e ) { }
    public void mouseExited( MouseEvent e ) { }
    public void mousePressed( MouseEvent e ) { }
    public void mouseReleased( MouseEvent e ) { }
    public void mouseClicked( MouseEvent e ) 
    {
        new Firework( e.getX(),e.getY(), this);
    }
}

和 Firework Thread 类:

class Firework extends Thread
{
    Point center = new Point(0,0);
    int blastRadius = 10;
    Point posIncrement = new Point(0,0);
    Applet applet;

    public Firework(int positionX, int positionY, Applet apple)
    {
        center.x = positionX;
        center.y = positionY;
        applet = apple;
        new Thread(this).start();
    }

    public void run()
    {
        while(blastRadius > 0)
        {
            applet.paint(applet.getGraphics());

            try {
                this.sleep(1000/20);
            } catch (InterruptedException e) { ; }
        }
    }

    public void paint(Graphics g)
    {
        if(blastRadius > 0)
        {
            Point[] fakeFire = {new Point(20,20),new Point(20,30),new Point(30,20)};
            ApplyNextPos(fakeFire,posIncrement);

            g.setColor(Color.red);
            for(int xaa=1; xaa<5; xaa++) // draw the formation
            {
                for(int zaa=0;zaa<fakeFire.length;zaa++)
                {
                    fakeFire[zaa] = GetQuadrant(xaa,center,fakeFire[zaa]);
                }

                for(int yaa=0;yaa<fakeFire.length;yaa++)
                {
                    g.drawString("*",fakeFire[yaa].x,fakeFire[yaa].y);
                }
            }
            posIncrement.incrementPos(5);
            blastRadius--;
        }
    }
}

I have a school project and i want to dedicate this for New Year, the project that i came up is a Text-Firework, i am using characters and symbols as the Explosion particles, and just constantly changing their X and Y position inside Paint().
I am confused on how to use Paint and Thread together. The problem is it's not painting on the screen or maybe the thread is not starting. (i cant really tell, im sorry). the problem is i dont get any error, it just doesn't work :(

the code is a little bit long i think, thank you for reading it.

How it should Works: When a user click, a Firework Thread will be started on the mouse position,
this Firework class has a paint loop for recreating the incremental explosion. so basically, i want the user to create multiple explosions thats why i made it a Thread.

here is the main applet:

public class TBFireworks extends Applet implements MouseListener
{
    public void init()
    {
        setBackground( Color.black );
        addMouseListener( this );
    }

    public void mouseEntered( MouseEvent e ) { }
    public void mouseExited( MouseEvent e ) { }
    public void mousePressed( MouseEvent e ) { }
    public void mouseReleased( MouseEvent e ) { }
    public void mouseClicked( MouseEvent e ) 
    {
        new Firework( e.getX(),e.getY(), this);
    }
}

and the Firework Thread class:

class Firework extends Thread
{
    Point center = new Point(0,0);
    int blastRadius = 10;
    Point posIncrement = new Point(0,0);
    Applet applet;

    public Firework(int positionX, int positionY, Applet apple)
    {
        center.x = positionX;
        center.y = positionY;
        applet = apple;
        new Thread(this).start();
    }

    public void run()
    {
        while(blastRadius > 0)
        {
            applet.paint(applet.getGraphics());

            try {
                this.sleep(1000/20);
            } catch (InterruptedException e) { ; }
        }
    }

    public void paint(Graphics g)
    {
        if(blastRadius > 0)
        {
            Point[] fakeFire = {new Point(20,20),new Point(20,30),new Point(30,20)};
            ApplyNextPos(fakeFire,posIncrement);

            g.setColor(Color.red);
            for(int xaa=1; xaa<5; xaa++) // draw the formation
            {
                for(int zaa=0;zaa<fakeFire.length;zaa++)
                {
                    fakeFire[zaa] = GetQuadrant(xaa,center,fakeFire[zaa]);
                }

                for(int yaa=0;yaa<fakeFire.length;yaa++)
                {
                    g.drawString("*",fakeFire[yaa].x,fakeFire[yaa].y);
                }
            }
            posIncrement.incrementPos(5);
            blastRadius--;
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小苏打饼 2024-10-04 11:14:53

首先,您似乎没有在 FireWork 线程中使用您的绘制方法,而是调用小程序的绘制方法。

我对 applet 和 AWT 的东西有点不感兴趣,但如果它是 Swing(我想它没有那么不同),我会建议另一种方法。绘画应该(可以?)仅在 EDT(事件调度线程)中完成。当用户单击时,您将创建一个与 FireWork 类似的对象,并将其添加到列表中。然后你启动一个线程(如果尚未启动,它会在某个面板上连续调用重绘。然后在面板的绘制方法中,你循环所有烟花的列表并绘制它们。

这也将提高内存效率,因为你只需要使用一个线程。

First, you seem not to be using your paint-method in the FireWork thread, you call the applet's paint method instead.

I'm a bit rosty in the applet and AWT stuff, but if it were Swing (I guess it not that different), I would suggest another approach. Painting should (can?) only be done in the EDT (Event Dispatch Thread). When the user clicks, you create a similar object to FireWork, and add that to a list. Then you start ONE thread (if not already started, that continously calls repaint on some panel. Then in the paint-method of your panel you loop the list of all fireworks and draw them.

This will also be more memory efficient, since you only use one thread.

情话已封尘 2024-10-04 11:14:53

paint 方法(通常)应该仅在相应的组件或部分需要(重新)绘制时由 GUI 调用。应用程序不应调用它(如果不是从另一个 Paint 方法内部调用)。

调用 paint 方法来绘制组件的实际状态。状态应该由另一个方法/线程更改。通过调用repaint强制组件的重新绘制。

一个不完整、未经测试的示例:

public class Animation extends Canvas {

    private final List<Firework> fireworks = new ArrayList<Firework>(); 

    public void start() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    step();
                    Thread.sleep(STEP_TIME);  // InterruptedException ?
                }
            }
        });
        t.start();
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        for (Firework fw : fireworks)
            fw.draw(g);  // draw the Firework
    }

    private void step() {
        for (Firework fw : fireworks) 
            fw.step();  // update/move the Firework
        repaint();
    }

    // methods for adding/deleting Fireworks, synchronization?
}

The paint method should (normaly) only be called by the GUI when the corresponding component or part of it needs to be (re-)painted. It should not be called by the application (if not from inside another paint method).

The paint method is called to draw the actual state of the component. The state should be changed by another method/thread. The repainting of the component is forced by calling repaint.

An incomplete, untested example:

public class Animation extends Canvas {

    private final List<Firework> fireworks = new ArrayList<Firework>(); 

    public void start() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    step();
                    Thread.sleep(STEP_TIME);  // InterruptedException ?
                }
            }
        });
        t.start();
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        for (Firework fw : fireworks)
            fw.draw(g);  // draw the Firework
    }

    private void step() {
        for (Firework fw : fireworks) 
            fw.step();  // update/move the Firework
        repaint();
    }

    // methods for adding/deleting Fireworks, synchronization?
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文