0

I'm making a game for practice and when I hit enter a knife pops up and I want it to look like its flying through air. Right now each time I click enter it skips about an inch and stops.

    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "onEnter");

    am.put("onEnter", new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            // Enter pressed
            throwKnife = true;
            if(move)
            {
                for(int i = 0; i < 10; i++)
                {
                    try
                    {
                        Thread.sleep(10);
                        knifeX += i;
                        repaint();
                    } catch (InterruptedException e1)
                    {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }

                if(knifeX > 1200)
                {
                    throwKnife = false;
                    move = false;
                    knifeX = imageX+100;
                    knifeY = imageY+75;
                }
            }
            throwKnife = true;
        }
    });

This is paired with the following code in my paint component method

    if(throwKnife)
    {
        g.drawImage(knife, knifeX, knifeY, this);
        repaint();
        move = true;
    }
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
Kyle Goertzen
  • 143
  • 1
  • 1
  • 8
  • 1
    `Thread.sleep(10);` is no-go on the main-thread, you need to implement some kind of Timer, that will call your `move` function every 10 ms. – JohnnyAW May 09 '17 at 20:36

2 Answers2

1

Based on the use of the key bindings API and repaint, I'm guessing you're using Swing, in which case you're blocking the event dispatching thread with the Thread.sleep

See Concurrency in Swing for the reason why

Have a look at How to use Swing Timers for a simple solution

I should also point out that the ActionListener will be called repeatedly while the key is held down. A better solution would be to use a flag to indicate when the key is "active" and a "main loop" (like a Swing Timer) to update the state accordingly

Of course, this will require you to detect when the key is released, which can be achieved by binding the key again, but for release. See KeyStroke.getKeyStroke(int, int, boolean) for more details

For example, maybe have a look at

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 1
    Seriously? Why the downvote? `Thread.sleep` is the problem, a Swing `Timer` is a viable solution? Oh, I didn't provide a copy and paste answer, instead I'm encouraging the OP to be pro-active and research the issue and solution themselves, bad me for wanting to make the developer more self relient and self suficent – MadProgrammer May 09 '17 at 20:48
  • `I'm encouraging the OP to be pro-active and research the issue and solution themselves` - totally agree. You have given the OP more help than he deserves considering the he has asked a dozen questions and not once taken the time to "accept" an answer. – camickr May 10 '17 at 00:07
0

Right now each time I click enter it skips about an inch and stops.

I believe that in the part you wrote if(move){...} you actually wanted while(move){...}.

With the while clause you can have it move until it satisfies certain condition (like knifeX > 1200).

So, your code should look like this:

while(move)
{
    for(int i = 0; i < 10; i++)
    {
        try
        {
            Thread.sleep(10);
            knifeX += i;
            repaint();
        } catch (InterruptedException e1)
        {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

    if(knifeX > 1200)
    {
        throwKnife = false;
        move = false;
        knifeX = imageX+100;
        knifeY = imageY+75;
    }
}

Hope it helps.

DarkCygnus
  • 7,420
  • 4
  • 36
  • 59
  • Generally, it won't work any better then the solution the OP has as the `Thread.sleep` will block the EDT, preventing it from updating the UI until the loop is completed – MadProgrammer May 09 '17 at 20:50