简体   繁体   English

Java Swing Applet:如何在不减慢整个程序的情况下减慢或延迟paint()

[英]Java Swing Applet: How to slow or delay paint() without slowing down the entire program

I'm creating a whack a mole game on java swing applet but I am having trouble with timing the moles to come up. 我正在用Java swing applet创建一个a鼠游戏,但是我很难安排timing鼠上来的时间。 I can't seem to avoid paint () looping on me and thus randomizing the coordinates of the mole too fast. 我似乎无法避免paint()在我身上循环,从而使痣的坐标随机化得太快。 How can I delay the moles to come up and stay for a while and go down if they were not hit? 如果痣没有被击中,我该如何延迟痣的停留并停留一段时间呢? How can I create this delay without delaying the entire program? 如何在不延迟整个程序的情况下创建此延迟?

please help 请帮忙

import java.awt.*;
import java.awt.event.*;
import java.util.*;

import javax.swing.*;
import javax.swing.Timer;

public class Game extends JApplet
{

    boolean titleScreen = true;
    boolean gameBegin = false;

    // /////////////////////////////////
    // ///// IMAGE /////////
    // /////////////////////////////////

    Dimension dim;
    Image offscreen;
    static Graphics bufferGraphics;
    static Image h1, h2, bg, gamebg, button1a, button1b, button2a, button2b;
    static Image m1, m1a, m1b, m2a, m2b;
    static Image[] mk = new Image [9];

    // /////////////////////////////////
    // ///// MOUSE /////////
    // /////////////////////////////////

    Cursor c;
    boolean myButtonPressed = false;
    boolean myButtonEntered = false;
    int myMouseX = 0, myMouseY = 0;
    int myRow = -1, myCol = -1;

    // /////////////////////////////////
    // / GAME VARIABLES ///
    // /////////////////////////////////

    private static final int[] mX = {5, 170, 335, 5, 170, 335, 5, 170, 335};
    private static final int[] mY = {5, 5, 5, 170, 170, 170, 335, 335, 335};
    int rand, randm;

    static int[] t = new int [9];

    static boolean mhhit = false;
    static boolean[] mhit = {false, false, false, false, false, false, false, false, false};
    private int[] respawnCounter = {0, 0, 0, 0, 0, 0, 0, 0, 0};
    private int[] removeCounter = {0, 0, 0, 0, 0, 0, 0, 0, 0};

    static int score = 0;

    public JFrame window;
    // /////////////////////////////////
    // ///// BUTTON /////////
    // /////////////////////////////////

    GameScreen g1 = new GameScreen ();
    Timer repaintTimer = null;
    // GameTime m1 = new GameTime (t[]);
    // GameTime m2 = new GameTime (t[]);
    // GameTime m3 = new GameTime (t[]);
    // GameTime m4 = new GameTime (t[]);
    // GameTime m5 = new GameTime (t[]);
    // GameTime m6 = new GameTime (t[]);
    // GameTime m7 = new GameTime (t[]);
    // GameTime m8 = new GameTime (t[]);
    // GameTime m9 = new GameTime (t[]);

    public Game ()
    {
        window = new JFrame ("Monkeying Around");
        window.setResizable (false);
        window.setSize (800, 400);
        window.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

    }


    public void init ()
    {
        // /////////////////////////////////
        // ///// IMAGE /////////
        // /////////////////////////////////
        dim = getSize ();
        setBackground (Color.white);
        offscreen = createImage (dim.width, dim.height);
        bufferGraphics = offscreen.getGraphics ();

        // Getting all the images
        m1a = getImage (getCodeBase (), "m1a.gif");
        m1b = getImage (getCodeBase (), "m1b.gif");
        m1 = getImage (getCodeBase (), "m1.gif");

        h1 = getImage (getCodeBase (), "hammer.gif");
        h2 = getImage (getCodeBase (), "hammer2.gif");
        bg = getImage (getCodeBase (), "mainbg.gif");
        gamebg = getImage (getCodeBase (), "gbg.gif");
        button1a = getImage (getCodeBase (), "button1a.gif");
        button1b = getImage (getCodeBase (), "button1b.gif");
        button2a = getImage (getCodeBase (), "button2a.gif");
        button2b = getImage (getCodeBase (), "button2b.gif");

        for (int mnum = 0 ; mnum < 9 ; mnum++)
        {
            mk [mnum] = m1;
        }
        ///////////////////////
        /////// MOUSE /////////
        ///////////////////////

        Toolkit tk = Toolkit.getDefaultToolkit ();
        c = tk.createCustomCursor (tk.getImage (""), new Point (0, 0), "invisible");
        setCursor (c);

        addMouseListener (new MyMouseListener ());
        addMouseMotionListener (new MyMouseMotionListener ());

        repaintTimer = new Timer (500, new RepaintAction (this));
        // start the timer.

    } // end init method


    public void start ()
    {
    }


    public Image getMouseImage ()
    {
        if (myButtonPressed)
        {
            return h2;
        }
        return h1;
    }


    public void handleMouseEvents ()
    {
        int nCol = myMouseX - 50;
        int nRow = myMouseY - 50;
        if (!myButtonEntered) // assumed to be: if myButtonEntered is
            // not = true i.e. false
            nCol = nRow = -1;
        if (nCol != myCol || nRow != myRow)
        {
            myRow = nRow;
            myCol = nCol;
        }

        repaint ();
    } // end handleMouseEvents method


    /////////////////////////////////////
    /////// MOUSELISTENER CLASS /////////
    /////////////////////////////////////

    public class MyMouseListener implements MouseListener
    {
        public void mousePressed (MouseEvent me)
        {
            myButtonPressed = true;
            myMouseX = me.getX ();
            myMouseY = me.getY ();
            handleMouseEvents ();
        }

        public void mouseReleased (MouseEvent me)
        {
            myButtonPressed = false;
            myMouseX = me.getX ();
            myMouseY = me.getY ();
            handleMouseEvents ();
        }

        public void mouseEntered (MouseEvent me)
        {
            myButtonEntered = true;
            myMouseX = me.getX ();
            myMouseY = me.getY ();
            handleMouseEvents ();
        }

        public void mouseExited (MouseEvent me)
        {
            myButtonEntered = false;
            myMouseX = me.getX ();
            myMouseY = me.getY ();
            handleMouseEvents ();
        }

        public void mouseClicked (MouseEvent me)
        {
            myMouseX = me.getX ();
            myMouseY = me.getY ();
            handleMouseEvents ();
        }
    } // end MyMouseListener class


    public class MyMouseMotionListener implements MouseMotionListener
    {
        public void mouseMoved (MouseEvent me)
        {
            myMouseX = me.getX ();
            myMouseY = me.getY ();
            handleMouseEvents ();
        } // end mouseMoved method

        public void mouseDragged (MouseEvent me)
        {
            myMouseX = me.getX ();
            myMouseY = me.getY ();
            handleMouseEvents ();
        } // end mouseDragged method
    } // end MyMouseListener class


    public void mouse ()
    {
        // logic to render mouse...
        if (myRow != -1 && myCol != -1)
        { // if you do not hit co-ordinates -1
            // (out of bounds) then
            Image mouseImage = getMouseImage ();
            bufferGraphics.drawImage (mouseImage, myCol, myRow, 100, 100, null, this);
        } // end if
    }


    public void paint (Graphics g)
    {
        bufferGraphics.clearRect (0, 0, dim.width, dim.height);
        repaint ();
        if (titleScreen == true)
        {
            // System.out.println("drawing the main screen");
            mainScreen ();
        }
        if (gameBegin == true)
        {
            game (g);
        }
        mouse ();
        g.drawImage (offscreen, 0, 0, this);
    } // end Paint method


    public void update (Graphics g)
    {
        paint (g);
    }


    public void mainScreen ()
    {
        bufferGraphics.drawImage (bg, 0, 0, 600, 500, Color.red, this);
        bufferGraphics.drawImage (button1a, 427, 384, 159, 49, Color.red, this);
        bufferGraphics.drawImage (button2a, 427, 440, 159, 49, Color.red, this);
        mouse ();
        if (myButtonPressed == true)
        {
            if (myRow > (384 - 50) && myRow < (433 - 50) && myCol > (427 - 50)
                    && myCol < (586 - 50))
            {
                titleScreen = false;
                gameBegin = true;
            }
            else if (myRow > (340 - 50) && myRow < (489 - 50)
                    && myCol > (427 - 50) && myCol < (586 - 50))
            {
                titleScreen = false;
            }
        }
    }





    public void game (Graphics g)
    {
        // new ReminderBeep (5);
        bufferGraphics.drawImage (gamebg, 0, 0, 600, 500, Color.red, this);
        for (int i = 0 ; i < 9 ; i++)
        {
            bufferGraphics.drawImage (mk [i], mX [i], mY [i], 160, 160, Color.red, this);
        }

        g.drawString ("har", 520, 140);
    }


    public void monkeyhit ()
    {
        if (myButtonPressed == true)
        {
            for (int hit = 0 ; hit < 9 ; hit++)
                if (mhit [hit] == true && myRow > (mY [hit] - 50) && myRow < (mY [hit] + 160 - 50)
                        && myCol > (mX [hit] - 50) && myCol < (mX [hit] + 160 - 50))
                {
                    mk [hit] = m1b;
                    mhhit = true;
                    mhit [hit] = false;
                    score += 10;
                }
        }
        // reset ();
    }


    public void run ()
    {
        monkey ();
    }


    // public void reset ()
    // {
    //     mhhit = false;
    //     for (int x = 0 ; x < 9 ; x++)
    //     {
    //         mk [x] = m1;
    //         mhit [x] = false;
    //
    //     }
    //
    // }


    public void monkey ()
    {
        rand = ((int) (Math.random () * 100000000)) + 10000000;
        randm = ((int) (Math.random () * 100));


        if (randm <= 8)
        {
            for (int a = 0 ; a < 9 ; a++)
            {
                if (randm == a)
                {
                    mhit [randm] = true;
                    mk [randm] = m1a;
                }
                else if (randm != a)
                {
                    mhit [a] = false;
                    mk [a] = m1;
                }
            }

            for (int i = 0 ; i < rand * 100 ; i++)
            {
                monkeyhit ();
                if (mhit [randm] = false)
                    mk [randm] = m1;
                break;
            }
        }
    }



    // Timer
    class GameTime
    {
        Toolkit toolkit;
        Timer timer;

        public GameTime (int seconds)
        {
            toolkit = Toolkit.getDefaultToolkit ();
            timer = new Timer (seconds, new MTask ());
            timer.start ();
        }


        /*
        public void delay(int seconds) {
                toolkit = Toolkit.getDefaultToolkit();
                timer = new Timer();
                timer.schedule(new Mdelay(), seconds * 1000);
        }
        */

        class MTask implements ActionListener
        {
            public void actionPerformed (ActionEvent ae)
            {
                /*
                for (int tsec = 0; tsec < 9; tsec++) {
                        t[tsec] = ((int) (Math.random() * 11)) * 5;
                }
                */

            }
        }
    }


    class RepaintAction implements ActionListener
    {
        Game game;
        public RepaintAction (Game game)
        {
            this.game = game;
        }


        public void actionPerformed (ActionEvent e)
        {
            game.repaint ();
        }
    }
}

In your painting method (or methods called from there), you should only do painting, nothing else (like checking where the mouse is and such). 在您的绘画方法(或从那里调用的方法)中,您只应该绘画,而不能做其他事情(例如检查鼠标的位置等等)。

Everything else should be done separately. 其他所有操作均应单独进行。 For example, calculating (randomizing) the positions of the moles (or monkeys?) should not be done here, but in the timer method, for example. 例如,在此处不应该计算(随机化)痣(或猴子?)的位置,而应使用计时器方法。

Your applet needs to have a model, which will be modified by the user interaction and random events. 您的小程序需要有一个模型,该模型将通过用户交互和随机事件进行修改。 The paint method then looks at this model, and paints according to this. 然后,绘制方法将查看此模型,并根据此模型进行绘制。

Never Don't override update() and paint(). 从不 不要覆盖update()和paint()。 That is old AWT code which is not used in Swing. 那是旧的AWT代码,Swing中没有使用。

In Swing custom painting is done by overriding the paintComponent() method of JPanel or JComponent. 在Swing中,通过覆盖JPanel或JComponent的paintComponent()方法来完成自定义绘制。 Then you add the component to the content pane of the applet (or frame or dialog or window). 然后,将组件添加到小程序的内容窗格(或框架,对话框或窗口)。

Read the section from the Swing tutorial on Custom Painting for more information and examples. 阅读Swing教程上有关自定义绘画的部分,以获取更多信息和示例。

Also, in Swing you would never invoke repaint() from within a painting method as this would cause in infinite loop. 另外,在Swing中, 您永远不会从绘画方法中调用repaint(),因为这会导致无限循环。

How would I create this model? 我将如何创建该模型?

Here's a very simple game that may guide your design. 这是一个非常简单的游戏 ,可以指导您的设计。 It illustrates the separation between model and view; 它说明了模型和视图之间的分离; it also links to related examples. 它还链接到相关示例。 A model having a List<Mole> with each Mole having a javax.swing.Timer seems apt. 具有List<Mole>且每个Mole具有javax.swing.Timer似乎很合适。 The model would notify the view when a mole changes state, and the view could query the model for mouse hit-testing. 当痣改变状态时,模型将通知视图,并且视图可以查询模型以进行鼠标命中测试。

You could create a Mole class with a startTime, upTime, and coordinates and have an ArrayList of moles in your main game class. 您可以创建一个具有startTime,upTime和坐标的Mole类,并在您的主游戏类中拥有一个moles的ArrayList。 Then, in your paint loop, check if any of the moles have been up for their allocated up time, and if so, remove them. 然后,在涂漆循环中,检查是否有任何痣在分配的正常工作时间内已经用完,如果是,则将其除去。 To keep a fairly uniform number of moles at all times, you could create a new mole to replace each mole that is destroyed with a random start time (based on current time), up time, and coordinates. 为了始终保持相当数量的痣,您可以创建一个新的痣,以随机开始时间(基于当前时间),正常运行时间和坐标替换每个被销毁的痣。

for(Mole mole : this.moles) {
    if(System.currentTimeMillis() - mole.getStartTime() >= mole.getUpTime()) {
        this.moles.remove(mole); 
    }
}

Threading could also be a suitable, but much more complex alternative. 线程也可能是合适的方法,但是要复杂得多。

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

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