Kilka pytań odnośnie poruszania obiektu i wielkości okna

0

Napisałem program poruszający za pomocą strzałek kwadratem. Jest jednak kilka rzeczy z którymi nie potrafię sobie poradzić i proszę o pomoc;
1.Czy można po kliknięciu danego przycisku zablokować jego ponowne kliknięcie ? (efekt przyśpieszania po kliknięciu tego samego przycisku dwukrotnie i więcej) ,
2.Chciałbym aby poruszał się on zgodnie z kwadratowymi polami 25 na 25 , by w efekcie wyglądało by to jakby przeskakiwał z jednego kwadratu na drugi,
3.Czy da się usunąć opcję powiększania okienka by zostało ono zawsze (w tym wypadku) 800 na 700,

Poniżej kod:
P.S.: Wiem że w oczach lepszych programistów kod może wydawać się chaotycznie napisany, ale jest to pierwszy większy projekt na którym pracuję. Prosiłbym więc również o porady odnośnie porządkowania kodu i ewentualną poprawę. Dzięki !

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class MovingBall extends JPanel implements ActionListener , KeyListener{

	public static final int Width=800, Height=800;
	double x=400, y=350,xVel=0,yVel=0;
	Timer time = new Timer(10,this);
	
	
	public MovingBall(){
		
        setPreferredSize(new Dimension(Width,Height));
        setBackground(new Color(40,40,40));
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
        time.start();
       }
	
	public void bars(Graphics g){
			g.setColor(Color.LIGHT_GRAY);
        
        	for(int i=0; i<=Width; i++){
        		g.drawLine(i*25,0,i*25, Height);
        		}
        	for(int i=0; i<=Height; i++)
        		{
        		g.drawLine(0,i*25,Width,i*25);
        		}
			}
	
	
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		g.setColor(Color.white);
		bars(g);
		
		Graphics2D g2 = (Graphics2D)g;
		Rectangle2D rectangle = new Rectangle2D.Double(x,y,25,25);
		g2.setColor(Color.RED);
		g2.fill(rectangle);
		
	}

	public void keyPressed(KeyEvent e) {
		int code = e.getKeyCode();
		if (code == KeyEvent.VK_UP){
			xVel = 0;
			yVel += -1.5;
		}
		else if (code == KeyEvent.VK_DOWN){
			xVel = 0;
			yVel += 1.5;
		}
		else if (code == KeyEvent.VK_LEFT){
			xVel += -1.5;
			yVel = 0;
		}
		else if (code == KeyEvent.VK_RIGHT){
			xVel += 1.5;
			yVel = 0;
		}
	}
	public void keyReleased(KeyEvent arg0) {}
	public void keyTyped(KeyEvent arg0) {}

	
	public void actionPerformed(ActionEvent e) {
		if (x < 0 )
		x = Width;
		
		else if (x > Width )
		x = 0;
		
		if (y < 0)
		y= Height;
		
		else if (y > Height)
		y= 0;
			
		y += yVel ;
		x += xVel ;
		repaint();
	}

	public static void main(String[] args){
		JFrame frame = new JFrame("Shnek");
		MovingBall ball = new MovingBall();
		frame.add(ball);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
		frame.setSize(Width, Height);
		frame.pack();
	}
	
} 
1

Ad.1. tak można np. poprzez stworzenie dodatkowej zmiennej typu boolean i ustawiać ją np. po wciśnięciu klawisza a kasować gdy jest puszczony np.

 private boolean pressed = false;

//...

public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();
        if (code == KeyEvent.VK_UP && !pressed){
            pressed = true;
            xVel = 0;
            yVel += -1.5;
        }
}

i ustawiać tą zmienną pressed na false w sytuacji kiedy ma zostać odblokowana możliwość wciskania danego klawisza.

ten problem można jeszcze rozwiązać zmieniając podejście do poruszania (chodzi mi o wyeliminowanie efektu przyśpieszania) a mianowicie zamiast dodawać za każdym razem do xVel 25, można ustawiać xVel na 25 xVel = 25;

Ad.2. wystarczy że zmienisz wartość xVel i yVel z wartości 1.5 na 25

Ad.3. tak da się zablokować wywołując metodę frame.setResizable(true);

0

Rozwiązanie pierwsze nie działa ponieważ po kliknięciu przycisku wartość zostajetrue i nie zmienia się. Ale przy pomocy tego pomysłu zrobiłem:

     private boolean pressedUP = false;
	 private boolean pressedDOWN = false;
	 private boolean pressedLEFT = false;
	 private boolean pressedRIGHT = false;

 public void keyPressed(KeyEvent e) {
		int code = e.getKeyCode();
		if (code == KeyEvent.VK_UP && pressedUP==false){
			pressedUP = true;
			xVel = 0;
			yVel += -1.5;
			pressedLEFT = false;
			pressedRIGHT = false;
            pressedDOWN = false;
		}
		else if (code == KeyEvent.VK_DOWN && pressedDOWN==false){
			pressedDOWN = true;
			xVel = 0;
			yVel += 1.5;
			pressedUP = false;
			pressedLEFT = false;
			pressedRIGHT = false;
		}
		else if (code == KeyEvent.VK_LEFT && pressedLEFT==false){
			pressedLEFT = true;
			xVel += -1.5;
			yVel = 0;
			pressedDOWN = false;
			pressedUP = false;
			pressedRIGHT = false;
		}
		else if (code == KeyEvent.VK_RIGHT && pressedRIGHT==false){
			pressedRIGHT = true;
			xVel += 1.5;
			yVel = 0;
			pressedDOWN = false;
			pressedLEFT = false;
			pressedUP = false;
		}
	}

Rozwiązanie drugie nie działa, próbowałem tego wcześniej :/
A w trzecim wartość powinna być false, ale komenda działa !

1

dlaczego Ad.2. nie działą? hmm u mnie działa...

 package Rozdzial4.jdbc.page250;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class MovingBall extends JPanel implements ActionListener , KeyListener{

    public static final int Width=800, Height=800;
    double x=400, y=350,xVel=0,yVel=0;
    Timer time = new Timer(10,this);

    public MovingBall(){

        setPreferredSize(new Dimension(Width,Height));
        setBackground(new Color(40,40,40));
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
        time.start();
    }

    public void bars(Graphics g){
        g.setColor(Color.LIGHT_GRAY);

        for(int i=0; i<=Width; i++){
            g.drawLine(i*25,0,i*25, Height);
        }
        for(int i=0; i<=Height; i++)
        {
            g.drawLine(0,i*25,Width,i*25);
        }
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.setColor(Color.white);
        bars(g);

        Graphics2D g2 = (Graphics2D)g;
        Rectangle2D rectangle = new Rectangle2D.Double(x,y,25,25);
        g2.setColor(Color.RED);
        g2.fill(rectangle);

    }

    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();
        if (code == KeyEvent.VK_UP){
            xVel = 0;
            yVel = -25;
        }
        else if (code == KeyEvent.VK_DOWN){
            xVel = 0;
            yVel = 25;
        }
        else if (code == KeyEvent.VK_LEFT){
            xVel = -25;
            yVel = 0;
        }
        else if (code == KeyEvent.VK_RIGHT){
            xVel = 25;
            yVel = 0;
        }
    }
    public void keyReleased(KeyEvent e) {

    }

    public void keyTyped(KeyEvent arg0) {}

    public void actionPerformed(ActionEvent e) {
        if (x < 0 )
            x = Width;

        else if (x > Width )
            x = 0;

        if (y < 0)
            y= Height;

        else if (y > Height)
            y= 0;

        y += yVel ;
        x += xVel ;

        yVel = 0;
        xVel = 0;
        repaint();
    }

    public static void main(String[] args){
        JFrame frame = new JFrame("Shnek");
        MovingBall ball = new MovingBall();
        frame.add(ball);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setResizable(false);
        frame.setSize(Width, Height);
        frame.pack();
    }

}

nie wiem czy o taki efekt Ci chodzi ale u mnie on działa.

Co do Ad.3. sorki za błąd:)

0

Rzeczywiście po prostu myślałem o innych zmiennych.
Potrzebuje jeszcze sprawić aby kwadrat poruszał się za stałą prędkością np (1 kwadrat na x ms) a tylko zmieniał kierunek (zamierzam stworzyć z tego grę Snake).

1

poczytaj o Timer z pakietu np. javax.swing.Timer;

0

Doczytałem i wystarczyło że zmieniłem wartość Timer time = new Timer(100,this); z 5 na 100. Dziękuje za pomoc i pozdrawiam !

1 użytkowników online, w tym zalogowanych: 0, gości: 1