Ruch obrazka

0

Witam!
Jestem bardzo zielony w programowaniu, ale postanowiłem zrobić prostą interakcje (bo to jeszcze nie gra). Ma ona polegac na tym że gdy wciśnie sie strzałkę w jakimś kierunku ,np. w prawo to obrazek który jest na środku zostanie przemalowany o 5 pikseli w prawo. Inaczej mówiąc, po prostu animacja ruchu w zalezności od wciśnietego klawisza. No i "coś" już stworzyłem tylko jest mały problem, bo gdy naciskam klawisze w lewo i go góry to obrazek porusza się tak jak powinien ale jak naciskam strzałki w prawo i w dół to jakoś ma opory... Pomóżcie proszę początkującemu. Z góry wielkie dzięki :-)

public class Main2 extends Applet implements  KeyListener

{
	public int x=100;
	public int y=100;
	public int stan = 0;
	Image obrazek;
	
	public void init ()
	  { 
	    addKeyListener   (this);
	    obrazek=getImage(getDocumentBase(), "Image2.jpg");
	  }
	
	
	public void keyPressed(KeyEvent e) {
		
		if(e.getKeyCode( ) == KeyEvent.VK_UP)
		{ 
			y=-5;
			stan=1;
			repaint();
		}
		
		if(e.getKeyCode( ) == KeyEvent.VK_DOWN)
		{ 
			y=+5;
			stan=2;
			repaint();
		}
		
		if(e.getKeyCode( ) == KeyEvent.VK_LEFT)
		{ 
			x=-5;
			stan=3;
			repaint();
		}
		
		if(e.getKeyCode( ) == KeyEvent.VK_RIGHT)
		{ 
			x=+5;
			stan=4;
			repaint();
		}
	}

	
	public void keyReleased(KeyEvent e) {
	getGraphics().drawImage(obrazek, x, y, this);
	}
	
	public void paint (Graphics g)
	{
		g.setColor(Color.blue);
		
		switch(stan)
        {
              case 1:
              g.drawString("Wcisnąłeś strzałkę do góry", 20, 20);
              g.drawImage(obrazek, x, y, this);
              break;

              case 2:
              g.drawString("Wcisnąłeś strzałkę na dół", 20, 20);
              g.drawImage(obrazek, x, y, this);
              break;

              case 3:
              g.drawString("Wcisnąłeś strzałkę w lewo", 20, 20);
              g.drawImage(obrazek, x, y, this);
              break; 
              
              case 4:
              g.drawString("Wcisnąłeś strzałkę w prawo", 20, 20);
              g.drawImage(obrazek, x, y, this);
              break; 
              
              default:
              g.drawString("Używaj strzałek do kierowania", 20, 20);  
              g.drawImage(obrazek, x, y, this);
              break;
              
        } 

	}
}
0
  1. po co ten switch na stanie? Po co stan? Stan jest przetrzymywany w obrazku.
  2. wywal switcha będzie działać lepiej
0

No ok, wywaliłem stan i switch ale i tak problem sie nie zmienił. Coś chyba źle robię, bo jak pokazuję wartości x i y to po jednym kliknieciu zmieniają się na 5 lub -5 i juz tak pozostaje. Proszę o dalsze wskazówki dla żółtodzioba.

public class Main2 extends Applet implements  KeyListener

{
	public int x=100;
	public int y=100;
	Image obrazek;
	
	public void init ()
	  { 
	    addKeyListener   (this);
	    setSize(300,300);
	    setVisible(true);
	    obrazek=getImage(getDocumentBase(), "Image2.jpg");
	  }
	
	
	public void keyPressed(KeyEvent e) {
		
		if(e.getKeyCode( ) == KeyEvent.VK_UP)
		{ 
			y=-5;
			getGraphics().drawString("Wcisnąłeś strzałkę do góry", 20, 20);
			getGraphics().drawImage(obrazek, x, y, this);
			repaint();
		}
		
		if(e.getKeyCode( ) == KeyEvent.VK_DOWN)
		{ 
			y=+5;
			getGraphics().drawString("Wcisnąłeś strzałkę na dół", 20, 20);
			getGraphics().drawImage(obrazek, x, y, this);
			repaint();
		}
		
		if(e.getKeyCode( ) == KeyEvent.VK_LEFT)
		{ 
			x=-5;
			getGraphics().drawString("Wcisnąłeś strzałkę w lewo", 20, 20);
			getGraphics().drawImage(obrazek, x, y, this);
			repaint();
		}
		
		if(e.getKeyCode( ) == KeyEvent.VK_RIGHT)
		{ 
			x=+5;
			getGraphics().drawString("Wcisnąłeś strzałkę w prawo", 20, 20);
			getGraphics().drawImage(obrazek, x, y, this);
			repaint();
		}
		else
		{
			getGraphics().drawString("Używaj strzałek do kierowania", 20, 20);  
			getGraphics().drawImage(obrazek, x, y, this);
		}
	}

	
	public void keyReleased(KeyEvent e) {
	getGraphics().drawImage(obrazek, x, y, this);
	}
	
	public void paint (Graphics g)
	{
		g.setColor(Color.blue);
		g.drawString("Wartość x: " +x, 20, 250);
		g.drawString("Wartość y: " +y, 20, 260);

	}
}
0

To co pisałem tutaj: http://4programmers.net/Forum/viewtopic.php?id=139096

należy podzielić odpowiedzialność poszczególnych klas. Wiem, że uczyli inaczej, ale nie od tego jest czacha by nosiła hełm.

public class Main2 extends Applet{
	private static final long serialVersionUID = 1L;
	private Obrazek obrazek;
	private Painter painter;

	public void init() {
		try {
			obrazek = new Obrazek(new URL("http://musicbox24.pl/"),
					"image.php?mode=band_image&band_id=1588&width=50", 100, 100);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		painter = new Painter(obrazek, this);
		addKeyListener(new Sterowanie(obrazek, this));
		setSize(300, 300);
		setVisible(true);
		repaint();
	}

	public void paint(Graphics g) {
		painter.paint(g);
	}
}

class Painter{
	
	private Obrazek obrazek;
	private Image image;

	public Painter(Obrazek obrazek, Main2 main2) {
		super();
		this.obrazek = obrazek;
		image = main2.getImage(obrazek.url, obrazek.name);
	}

	public void paint(Graphics g){
		g.setColor(Color.blue);
        g.drawString("Wartość x: ", 20, 250);
        g.drawString("Wartość y: ", 20, 260);
        g.drawImage(image, obrazek.x, obrazek.y, null);
	}
}

class Sterowanie extends KeyAdapter {

	private Obrazek obrazek;
	private Main2 main2;
	
	public Sterowanie(Obrazek obrazek, Main2 main2) {
		super();
		this.obrazek = obrazek;
		this.main2 = main2;
	}

	@Override
	public void keyPressed(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_UP) {
			obrazek.y += 5;
			main2.repaint();
		}
		if (e.getKeyCode() == KeyEvent.VK_DOWN) {
			obrazek.y -= 5;
			main2.repaint();
		}
		if (e.getKeyCode() == KeyEvent.VK_LEFT) {
			obrazek.x += 5;
			main2.repaint();
		}
		if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
			obrazek.x -= 5;
			main2.repaint();
		}
	}

}

class Obrazek {
	public URL url;
	public String name;
	public int x;
	public int y;

	public Obrazek(URL url, String name, int x, int y) {
		this.url = url;
		this.name = name;
		this.x = x;
		this.y = y;
	}
}

Chyba bardziej przejrzyste?
Obrazek wzięty z netu.

0

Wow :-)
Super działa, tylko że ja jestem jeszcze cienki i chyba mi troche czasu zajmie połapanie się w tym co gdzie jest robione:) A mógłbyś mi szybko napisać jak poprawić kod który wstawiłem wcześniej aby działało? W ten sposób nauczyłbym się czegoś więcej ;-)
A tak poza tym to wielkie dzięki [browar]

0

Po pierwsze. W programowaniu jak w miłości nie da się wszystkiego naraz mieć. Dlatego należy stosować zasadę jedna klasa - jedna odpowiedzialność. Twój program rozszerza klasę Applet i implementuje interfejs. To zdecydowanie za dużo jak na jedną klasę. Oczywiście nie można mieć wszystkiego. Klasy główne zazwyczaj są nieźle namącone i mają dość szeroki zakres odpowiedzialności. Nie jest to u nich złe o ile nie przesadzasz :) Popatrz w mój kod. Wydzieliłem poszczególne elementy w pewien logiczny sposób. Oddzielnie jest klasa Obrazek, która przechowuje informacje o tylko i wyłącznie o obrazku. Oddzielnie jest implementacja KeyListenera (za pomocą adaptera, bo tak jest mniej kodu). Oddzielnie jest rysowanie.

Twój kod to wszystko na raz. Fakt, że wtedy masz dostęp do wszystkiego od ręki, ale nie o to chodzi.

Twój kod poprawiłem, bo nie myśl, że pisałem coś od nowa :) Poddałem go tylko refaktoringowi. Najpierw wyrzuciłem na zewnątrz informacje o obrazku. Następnie wyekstrahowałem metody związane z obsługą klawiszy. Na koniec przeniosłem rysowanie do osobnego obiektu.
Kolejnym krokiem było spięcie poszczególnych obiektów. Jako, że wiedziałem jak ma mniej więcej wyglądać flow programu (kwestia wyrobienia się i doświadczenia) to dodałem tylko odpowiednie pola i konstruktory.

Jak chcesz zrobić coś takiego z następnym programem to:

  1. Pisząc program zachowuj kolejność w jakiej chciałbyś by był wykonywany. Najpierw ładowanie danych, potem nasłuchiwanie użytkownika, obliczenia,rysowanie.
  2. Napisz program w całości, ale jak sam zobaczysz mając zachowaną pewną logikę od razu będzie można część kodu przesunąć do oddzielnych klas czy metod.
  3. Sprawdź czy program jest przejrzysty. Czy łatwo patrząc na kod go narysować. Jeżeli coś jest zagmatwane lub w ramach jakiegoś fragmentu wykonywane jest za dużo operacji rozbij ten fragment. I tak do skutku.
0

Dzięki wielkie jeszcze raz :-)
Jak się uczyc to od najlepszych. [browar]

0

Witam ponownie!

Troche posiedziałem i przeanalizowałem kod (tzn. dalej sie uczac na bledach) i chcialem go troche zmodyfikowac, żeby moj obrazek byl wczytywany z dysku o nazwie "Image2.jpg". Probowalem jak zwykle czytac go getImage() ale chyba cos jeszcze poknocilem :-/

import java.awt.*;
import java.applet.*;
import java.awt.event.*; 
import java.net.*;


public class Main2 extends Applet{
        private static final long serialVersionUID = 1L;
        private Obrazek obrazek;
        private Painter painter;

        public void init() {
                        
        		obrazek = new Obrazek("Nazwa obrazka", 100, 100);
                painter = new Painter(obrazek);
                addKeyListener(new Sterowanie(obrazek, this));
                setSize(300, 300);
                setVisible(true);
                repaint();
        }

        public void paint(Graphics g) {
                painter.paint(g);
        }
}

class Painter{
       
        private Obrazek obrazek;


        public Painter(Obrazek obrazek) {
                super();
                this.obrazek = obrazek;
                obrazek = getImage(getDocumentBase(),"Image.jpg");          //TUTAJ MAM BŁĄD
        }

        public void paint(Graphics g){
        g.setColor(Color.blue);
        g.drawString("Wartość x: " +obrazek.x, 20, 250);
        g.drawString("Wartość y: " +obrazek.y, 20, 260);
        g.drawImage(obrazek, obrazek.x, obrazek.y, null);                      // I TUTAJ MAM BŁĄD
        }
}

class Sterowanie extends KeyAdapter {

        private Obrazek obrazek;
        private Main2 main2;
       
        public Sterowanie(Obrazek obrazek, Main2 main2) {
                super();
                this.obrazek = obrazek;
                this.main2 = main2;
        }

        public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_UP) {
                        obrazek.y -= 5;
                        main2.repaint();
                }
                if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                        obrazek.y += 5;
                        main2.repaint();
                }
                if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                        obrazek.x -= 5;
                        main2.repaint();
                }
                if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                        obrazek.x += 5;
                        main2.repaint();
                }
        }

}

class Obrazek {
        public String name;
        public int x;
        public int y;

        public Obrazek( String name, int x, int y) {
                this.name = name;
                this.x = x;
                this.y = y;
        }
}

Mam tez pytanie po co stworzyles obiekt klasy Main2 o nazwie main2? Co on wlasciwie robi?

0

Czy ktoś pomoże początkującemu?

0

Aplet nie ma dostępu do dysku. Przynajmniej domyślnie. Dwie drogi. Prosta zainstalować sobie serwer apache i uruchamiać applet "jak w internecie". Druga podpisać aplet.

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