Java [1242]

Zapisz się
Dodaj kartkę Dodaj bana
Powód wlepienia kartki
Wybierz wątek docelowy z listy lub wpisz jego ID
  • Liść

    Po wielu perypetiach udało mi się stworzyć poruszającą się po ekranie kropkę. Całość może niezbyt przejrzyście wygląda ale działa tzn. kropka porusza się w ustalonym kierunku. Problem pojawia się kiedy chcę nią sterować. Dodaje sobie KeyListenera który zmienia odpowiednie zmienne itd. ale KeyListener nie reaguje... Próbowałem dodawać go do różnych komponentów i nic... MouseListener działa prawidłowo (w tym wypadku startuje i zatrzymuje kropkę). Nie wiem też co zrobić żeby było widać JPanel title. Graphics2D zdaje się przysłaniać wszystko a nawet jak próbuję ustawić to od pewnego miejsca wszystkie panele i tak są zasłonięte. Proszę pomóżcie. A może ktoś miałby pomysł jak to inaczej zrobić bo Java2D to póki co nowość dla mnie i poruszam się tu z lekka po omacku.

    public class Test4 extends JPanel implements Runnable {

    int x=0;
    int y=30;
    JTextField t = new JTextField(1);
    JLabel t2 = new JLabel("SUPPPA SNAKE");
    public JPanel title = new JPanel();
    public static int dirx = 0;
    public static int diry = 0;

    private Thread thread;

    Ellipse2D el = new Ellipse2D.Double(x,y,5,5);
    RectangularShape bg = new Rectangle2D.Double(0,30,700,47 0);

    public void init(){
    setBackground(Color.red);
    title.setPreferredSize(new Dimension(700,30));
    title.setBackground(Color.pink );
    title.add(t2);
    title.addKeyListener(new MoveListener());
    this.add(title);
    this.addKeyListener(new MoveListener());

    this.addMouseListener(new Mouse());
    }

    public Test4(){
    this.setPreferredSize(new Dimension(700,500));
    }
    public void step(int a,int b){
    x+=a;
    y+=b;
    }
    public void paint(Ellipse2D e,RectangularShape b, Graphics2D g2){
    g2.setColor(Color.red);
    g2.draw(b);
    g2.fill(b);
    g2.setColor(Color.black);
    g2.fill(e);
    g2.draw(e);
    step(dirx,diry);
    e.setFrame(x,y,5,5);
    g2.dispose();
    g2.clearRect(0,30,700,500);
    //repaint();
    }

    public void paintComponent(Graphics g){
    Graphics g1 = g.create(0,30,700,470);
    Graphics2D g2 = (Graphics2D)g.create(0,30,700, 470);
    paint(el,bg,g2);
    }
    public void start(){
    thread = new Thread(this);
    thread.setPriority(Thread.MIN_ PRIORITY);
    thread.start();
    }
    public void run() {
    Thread me = Thread.currentThread();
    while(thread == me){
    repaint();
    try{
    thread.sleep(10);
    }catch(InterruptedException e){break;}
    }
    thread=null;
    }

    public synchronized void stop(){
    thread=null;
    }

    class MoveListener implements KeyListener{
    @Override
    public void keyPressed(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    // TODO Auto-generated method stub
    }
    public void keyTyped(KeyEvent e) {
    System.out.println("hit");
    switch(e.getKeyChar()){
    case 'w':
    dirx = 0;
    diry = -1;
    System.out.println("x:" + dirx + " y:" + diry);
    break;
    case 's':
    dirx = 0;
    diry = 1;
    System.out.println("x:" + dirx + " y:" + diry);
    break;
    case 'a':
    dirx = -1;
    diry = 0;
    System.out.println("x:" + dirx + " y:" + diry);
    break;
    case 'd':
    dirx = 1;
    diry = 0;
    System.out.println("x:" + dirx + " y:" + diry);
    break;
    }

    }
    }

    class Mouse implements MouseListener{


    public void mouseClicked(MouseEvent e) {
    dirx=1;
    diry=0;
    if (e.getClickCount()==2){
    dirx=0;
    }
    }

    }
    public static void main(String argv[]) {

    final Test4 f = new Test4();
    f.init();
    JFrame frame = new JFrame("Cos");
    frame.setSize(700,500);
    frame.setDefaultCloseOperation (3);
    frame.add(f.title);
    frame.add(f);
    frame.setVisible(true);
    //f.addKeyListener(new MoveListener());
    f.start();
    }
    }
  • Liść

    Pogrzebałem trochę i już działa :) Kropka chodzi tam gdzie trzeba. A co do widoczności JPaneli to trzeba było się trochę doedukować na temat metody paintComponent. Teraz już rozumiem większość więc mogę brnąć dalej w pisanie Snake'a w wersji sieciowej. Pewnie niedługo znów na czymś utknę więc temat wciąż otwarty :)
  • boska renia

    public void run() {
    Thread me = Thread.currentThread();
    while(thread == me){
    repaint();
    try{
    ....


    Powyżej pojawia się dosyć zasadniczy błąd związany z jednowątkowym modelem Swinga. Wszelkie operacje na obiektach swinga/awt wykonywane z innego wątku powinny być kolejkowane do wątku Swinga poprzez wywołanie:

    SwingUtilities.invokeLater(new Runnable(){
    @Override
    public void run() {
    // operacje na obiektach Swinga

    }
    };

    ..co spowoduje dodanie do kolejki Swinga obiektu typu Runnable i wywołanie metody run w odpowiednim momencie. Brak synchronizacji jak powyżej jest zasadniczym błędem i może skutkować niedeterministycznym sypaniem Exceptionami przez obiekty Swinga a nawet deadlockiem (okno może przestać odpowiadać).

    pzdr
  • Liść

    Akurat ten fragment jest wzięty żywcem z jakiegoś tutoriala na sun.com i prawdę mówiąc nie do końca rozumiem co się w nim dzieje a rzeczy o których piszesz nie pojawiły się... Okno odpowiadało na kliknięcia myszą a na klawisze już nie. Trochę to przerobiłem, dodałem KeyListenera gdzie trzeba (wcześniej dodawałem go do paneli i pewnie przez grzebanie w wątku Swinga wyszło jak wyszło) tj. do całego JFrame'a i jest ok. Nie wiem na ile to poprawne ale działa. Nawet zrobiłem już całego węża nie tylko jedną kropkę :). Jutro (w sumie to dziś) będę robił wąż vs wąż przez gniazda i dopiero się zacznie xD.

    Dzięki za pomoc; )
  • Liść

    A może jakieś rady co przesyłania czegoś przez gniazda? Co nieco już pisałem ale gubię się w tych wszystkich "BufferedStreamReader'ach i PrintWriterach" co znajdę jakiś przykład to coś innego jest użyte. A to co stworzyłem działało mi dość hmmm losowo... Chodzi mi o wielokrotne i jak najszybsze przesłanie tablicy int'ów i pojedynczych String'ów.