Badfitz66
Badfitz66

Reputation: 366

Circle not moving

There's no errors, but when I press any of the buttons, my oval/circle doesn't move at all? Can anyone help? I've been looking up and down the code for about 20 minutes seeing if I typed anything wrong or put something in the wrong place. I can't tell if this is with the way I'm moving it or my thread.

package com.badfitz66.mainpackage;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;

public class Main extends JFrame implements Runnable
{
    int x, y, xDirection, yDirection;
    private Image dbImage;
    private Graphics dbG;

    Font font = new Font("Black Caps", Font.ITALIC | Font.BOLD, 30);

    public void run()
    {
        try
        {
            while(true)
            {
                Move();
                Thread.sleep(5);
            }
        }
        catch(Exception e){
            System.out.println("Error");
        }
    }

    public void Move()
    {
        x += xDirection;
        y += yDirection;

        if (x <= 0)
            x = 0;
        if(x >= 500)
            x = 500;
        if (y <= 50)
            y = 50;
        if (y >= 250)
            y = 250;
    }

    public void setXDir(int xdir)
    {
        xDirection = xdir;
    }

    public void setYDir(int ydir)
    {
        yDirection = ydir;
    }

    public class AL extends KeyAdapter
    {
        public void keyPressed(KeyEvent e)
        {
            int keyCode = e.getKeyCode();
            if(keyCode == e.VK_D)
            {
                setXDir(+1);
            }

            if(keyCode == e.VK_A)
            {
                setXDir(-1);
            }

            if(keyCode == e.VK_W)
            {
                setYDir(-1);
            }

            if(keyCode == e.VK_S)
            {
                setYDir(+1);
            }
        }

        public void keyReleased(KeyEvent e)
        {
            int keyCode = e.getKeyCode();
            if(keyCode == e.VK_D)
            {
                setXDir(0);
            }

            if(keyCode == e.VK_A)
            {
                setXDir(0);
            }

            if(keyCode == e.VK_W)
            {
                setYDir(0);
            }

            if(keyCode == e.VK_S)
            {
                setYDir(0);
            }
        }
    }

    public Main()
    {
        addKeyListener(new AL());
        setTitle("Java game testing");

        setResizable(false);
        setVisible(true);
        setSize(500, 500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBackground(Color.green);
        x = 150; 
        y = 150;
    }

    public void paint(Graphics g)
    {
        dbImage = createImage(getWidth(),getHeight());
        dbG = dbImage.getGraphics();
        paintComponent(dbG);
        g.drawImage(dbImage, 0, 0, this);
    }

    public void paintComponent(Graphics g)
    {
        g.setFont(font);
        g.drawString("Hello world", 125, 50);
        g.setColor(Color.cyan);
        g.fillOval(x, y, 15, 15);

        repaint();
    }

    public static void main(String[] args)
    {
        Main jg = new Main();
        //Threads
        Thread t1 = new Thread();
        t1.start();
    }
}

Upvotes: 0

Views: 89

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347184

  1. You never call repaint from within your Move method
  2. Thread t1 = new Thread(); won't do much, as it will never call any runnable code, in fact it will start and terminate almost immediately, how ever...
  3. Swing is not thread safe and you should never modify the UI or anything the UI relies on from outside the Event Dispatching Thread, this especially important, as a paint cycle could occur at any time. See Concurrency in Swing for more details
  4. You override the paint method of a top level container (JFrame) and then break the paint chain...paint is complex series of method calls chained together to generate the final result, you should always call super.paint first, but as you probably know, JFrame is not double buffered. So instead, you should create another class that extends from JPanel and override it's paintComponent method to perform the actual painting (in fact, for the most part, it should pretty much replace the functionality that the current JFrame is doing)...Swing components are double buffered by default...
  5. Calling repaint from within a paint method...this is bad news and this will immediately schedule another paint cycle, this becomes so fast that it consume all your CPU cycles till you computer stands still
  6. Using KeyListener. KeyListener is notorious for having issues, in particular, it will only ever trigger a key event if the component it is registered to IS FOCUSABLE and HAS FOCUS. A JFrame is made up of the physical window, the JRootPane, which holds the content pane (and a few other components), all of which can get in the way of the frame actually getting focus. Instead, using the previously mentioned JPanel, use the key bindings API, which will allow to control the level of focus required for the key events to be triggered. See How to Use Key Bindings for more details

You should also have a look at...

Upvotes: 2

Related Questions