Java-апплет: перемещение полигона с помощью keylistener - PullRequest
1 голос
/ 04 марта 2012

Кажется, есть проблема при использовании KeyListener на fillPolygon / drawPolygon. Я не могу перемещать полигоны, используя KeyListener, но я могу перемещать другую графику. Вот код Java:

import java.awt.Color;
import java.awt.Graphics;
import java.applet.Applet;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Exer09Laggui extends Applet implements KeyListener {

   int width;
   int height;
   int carLength = 200;
   int carWidth = 75;

   int nPoints = 4;

   // for body
   int body_x = 0;
   int body_y = 0;

   // for front windshield
   // x coordinates
   int frontWS_x1 = 125;
   int frontWS_x2 = 125;
   int frontWS_x3 = 145;
   int frontWS_x4 = 145;
   // y coordinates
   int frontWS_y1 = 62;
   int frontWS_y2 = 10;
   int frontWS_y3 = 5;
   int frontWS_y4 = 67;

   int[] xPoints1 = { frontWS_x1, frontWS_x2, frontWS_x3, frontWS_x4 };
   int[] yPoints1 = { frontWS_y1, frontWS_y2, frontWS_y3, frontWS_y4 };

   public void init() {
      width = getSize().width;
      height = getSize().height;
      setBackground(Color.GRAY);
      addKeyListener(this);
   }

   public void paint(Graphics g) {
      // for the car body
      g.setColor(Color.BLACK);
      // fillRoundRect(int x, int y, int width, int height, int arcWidth, int
      // arcHeight)
      g.fillRoundRect(body_x, body_y, carLength, carWidth, 30, 30);

      // for the front windshield
      // fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
      g.setColor(Color.white);
      g.drawPolygon(xPoints1, yPoints1, nPoints);
      g.setColor(new Color(200, 200, 255));
      g.fillPolygon(xPoints1, yPoints1, nPoints);
   }

   public void keyPressed(KeyEvent e) {
      if (e.getKeyCode() == KeyEvent.VK_DOWN) {
         // for body
         body_y += 5;
         // for front windshield
         frontWS_y1 += 5;
         frontWS_y2 += 5;
         frontWS_y3 += 5;
         frontWS_y4 += 5;
      }
      if (e.getKeyCode() == KeyEvent.VK_UP) {
         // for body
         body_y -= 5;
         // for front windshield
         frontWS_y1 -= 5;
         frontWS_y2 -= 5;
         frontWS_y3 -= 5;
         frontWS_y4 -= 5;
      }
      if (e.getKeyCode() == KeyEvent.VK_LEFT) {
         // for body
         body_x -= 5;
         // for front windshield
         frontWS_x1 -= 5;
         frontWS_x2 -= 5;
         frontWS_x3 -= 5;
         frontWS_x4 -= 5;
      }
      if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
         // for body
         body_x += 5;
         // for front windshield
         frontWS_x1 += 5;
         frontWS_x2 += 5;
         frontWS_x3 += 5;
         frontWS_x4 += 5;
      }
      repaint();
   }

   public void keyReleased(KeyEvent e) {
   }

   public void keyTyped(KeyEvent e) {
   }
}

и вот HTML ... Я не знаю, что не так, пожалуйста, помогите ...

    <html>

<body>

    <applet code   = 'Exer09Laggui.class'
            width  = '1340'
            height = '635'/>
</body>

    </html>

Ответы [ 2 ]

1 голос
/ 04 марта 2012

Значения массива не обновляются автоматически, поскольку они являются примитивами, а не объектами.

Exer09Laggui

// <applet code='Exer09Laggui' width=400 height=200></applet>
import java.awt.Color;
import java.awt.Graphics;
import java.applet.Applet;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Exer09Laggui extends Applet implements KeyListener {

   int width;
   int height;
   int carLength = 200;
   int carWidth = 75;

   int nPoints = 4;

   // for body
   int body_x = 0;
   int body_y = 0;

   // for front windshield
   // x coordinates
   int frontWS_x1 = 125;
   int frontWS_x2 = 125;
   int frontWS_x3 = 145;
   int frontWS_x4 = 145;
   // y coordinates
   int frontWS_y1 = 62;
   int frontWS_y2 = 10;
   int frontWS_y3 = 5;
   int frontWS_y4 = 67;

   int[] xPoints1 = { frontWS_x1, frontWS_x2, frontWS_x3, frontWS_x4 };
   int[] yPoints1 = { frontWS_y1, frontWS_y2, frontWS_y3, frontWS_y4 };

   public void init() {
      width = getSize().width;
      height = getSize().height;
      setBackground(Color.GRAY);
      addKeyListener(this);
      setFocusable(true);
      requestFocusInWindow();
   }

   public void paint(Graphics g) {
      // for the car body
      g.setColor(Color.BLACK);
      // fillRoundRect(int x, int y, int width, int height, int arcWidth, int
      // arcHeight)
      g.fillRoundRect(body_x, body_y, carLength, carWidth, 30, 30);

      // for the front windshield
      // fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
      g.setColor(Color.white);
      g.drawPolygon(xPoints1, yPoints1, nPoints);
      g.setColor(new Color(200, 200, 255));
      g.fillPolygon(xPoints1, yPoints1, nPoints);
   }

   public void keyPressed(KeyEvent e) {
      if (e.getKeyCode() == KeyEvent.VK_DOWN) {
         // for body
         body_y += 5;
         // for front windshield
         frontWS_y1 += 5;
         frontWS_y2 += 5;
         frontWS_y3 += 5;
         frontWS_y4 += 5;
      }
      if (e.getKeyCode() == KeyEvent.VK_UP) {
         // for body
         body_y -= 5;
         // for front windshield
         frontWS_y1 -= 5;
         frontWS_y2 -= 5;
         frontWS_y3 -= 5;
         frontWS_y4 -= 5;
      }
      if (e.getKeyCode() == KeyEvent.VK_LEFT) {
         // for body
         body_x -= 5;
         // for front windshield
         frontWS_x1 -= 5;
         frontWS_x2 -= 5;
         frontWS_x3 -= 5;
         frontWS_x4 -= 5;
      }
      if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
         // for body
         body_x += 5;
         // for front windshield
         frontWS_x1 += 5;
         frontWS_x2 += 5;
         frontWS_x3 += 5;
         frontWS_x4 += 5;
      }
       xPoints1[0] = frontWS_x1;
       xPoints1[1] = frontWS_x2;
       xPoints1[2] = frontWS_x3;
       xPoints1[3] = frontWS_x4;
       yPoints1[0] = frontWS_y1;
       yPoints1[1] = frontWS_y2;
       yPoints1[2] = frontWS_y3;
       yPoints1[3] = frontWS_y4;
      repaint();
   }

   public void keyReleased(KeyEvent e) {
   }

   public void keyTyped(KeyEvent e) {
   }
}
1 голос
/ 04 марта 2012

Это проблема фокуса, и ключ заключается в том, чтобы сфокусироваться на апплете после того, как он виден , а последняя часть - сложная часть, так как просто вызов requestFocus() в методе init() выигралне работаетВы можете сделать это в Swing Timer в init или переопределить setVisible, как показано ниже как kludge 1 или kludge 2:

import java.applet.Applet;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JOptionPane;

public class Exer09Laggui extends Applet implements KeyListener {
   private boolean firstSetVisible = true;

   public void init() {
      addKeyListener(this);

      // kludge one:
      int timerDelay = 400;
      new javax.swing.Timer(timerDelay , new ActionListener() {

         public void actionPerformed(ActionEvent evt) {
            Exer09Laggui.this.requestFocusInWindow();
            ((javax.swing.Timer)evt.getSource()).stop();
         }
      }).start();
   }

   // kludge two
   public void setVisible(boolean b) {
      super.setVisible(b);
      if (firstSetVisible) {
         requestFocusInWindow();
         firstSetVisible = false;
      }
   }

   public void keyPressed(KeyEvent e) {
      if (e.getKeyCode() == KeyEvent.VK_DOWN) {
         JOptionPane.showMessageDialog(this, "down");
      }
      if (e.getKeyCode() == KeyEvent.VK_UP) {
         JOptionPane.showMessageDialog(this, "up");
      }
      if (e.getKeyCode() == KeyEvent.VK_LEFT) {
         JOptionPane.showMessageDialog(this, "left");
      }
      if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
         JOptionPane.showMessageDialog(this, "right");
      }
   }

   public void keyReleased(KeyEvent e) {
   }

   public void keyTyped(KeyEvent e) {
   }
}

Еще одна хитрость при отладке этих типов вещей - максимально упростить ваш кодтак что остаются только основные элементы, необходимые для демонстрации ошибки.Какой код нам легче читать и понимать, ваш код или мой более простой код - и вы поймете, почему это полезно для нас.это также полезно для вас, поскольку вы устраняете вещи, которые могут усложнить проблему и тем самым справиться только с чистой проблемой.

Редактировать
Чтобы переместить «лобовое стекло», необходимо обновитьданные, которые использует лобовое стекло для рисования.Что это за данные?Два массива int [], xPoints1 и yPoints1.Поскольку ваш код не меняет их, то ветровые стекла останутся на месте.Вам нужно добавить что-то вроде:

public void keyPressed(KeyEvent e) {
  if (e.getKeyCode() == KeyEvent.VK_DOWN) {
     // for body
     body_y += 5;
     // for front windshield
     frontWS_y1 += 5;
     frontWS_y2 += 5;
     frontWS_y3 += 5;
     frontWS_y4 += 5;
  }
  if (e.getKeyCode() == KeyEvent.VK_UP) {
     // for body
     body_y -= 5;
     // for front windshield
     frontWS_y1 -= 5;
     frontWS_y2 -= 5;
     frontWS_y3 -= 5;
     frontWS_y4 -= 5;
  }
  if (e.getKeyCode() == KeyEvent.VK_LEFT) {
     // for body
     body_x -= 5;
     // for front windshield
     frontWS_x1 -= 5;
     frontWS_x2 -= 5;
     frontWS_x3 -= 5;
     frontWS_x4 -= 5;
  }
  if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
     // for body
     body_x += 5;
     // for front windshield
     frontWS_x1 += 5;
     frontWS_x2 += 5;
     frontWS_x3 += 5;
     frontWS_x4 += 5;
  }

  // ***** note added code *****
  xPoints1 = new int[]{ frontWS_x1, frontWS_x2, frontWS_x3, frontWS_x4 };
  yPoints1 = new int[]{ frontWS_y1, frontWS_y2, frontWS_y3, frontWS_y4 };

  repaint();
}
...