Как перемещать шар

Давайте начнем с очень простого шага. Мы будем программировать апплет, в котором шар будет перемещаться справа налево. Я знаю, что в этом нет ничего особенного, но если вы хотите научиться программировать игры, то, возможно, это наиболее важная вещь для того, чтобы понять, как анимировать объекты!
Вначале мы должны написать нашу основную структуру апплета, но плюс к этому добавим пару маленьких вещей. Наш апплет должен реализовывать интерфейс Runnable и соответствующий метод run(), чтобы анимировать объект. Структура апплета будет выглядеть так:

import java.applet.*;
import java.awt.*;

public class BallApplet extends Applet implements Runnable
{

    public void init() { }

    public void start() { }

    public void stop() { }

    public void destroy() { }

    public void run () { }

    public void paint (Graphics g) { }

}

Чтобы передвинуть объект, нам нужен другой объект - экземпляр класса Thread, мы объявляем в методе start нашего апплета:

Потоки исполнения (threads)

Поток исполнения - это кусок программы, которая делает возможным запуск параллельно с другими частями программы (multithreading). Потоки реализуются классом Thread, интерфейс Runnable, метод run(), мы уже реализовали те две вещи шагом ранее. Важные методы класса Thread следующие:

Thread.start(): запускает поток
Thread.stop(): останавливает поток
Thread.sleep(время в миллисекундах): останавливает thread на определенный промежуток времени

Другие функции класса Thread вы можете найти в Java API.

А теперь перейдем к коду.

public void start ()
{

    // определяем новый поток
    Thread th = new Thread (this);
    // start this thread
    th.start ();
}

Теперь этот поток запущен в методе run() нашего апплета. Каждый раз, когда любой метод... вызывается в методе, мы останавливаем gпоок исполнения на коротокое время. Ваш метод должен выглядеть так:

public void run ()
{

    // низкий приоритет потока
    Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

    // выполняется, пока (true) - в нашем случае это значит всегда
    while (true)
    {
      // перерисовываем апплет
      repaint();

      try
      {
        // Останавливаем поток на 20 миллисекунд
        Thread.sleep (20);
      }
      catch (InterruptedException ex)
      {
        // не делаем ничего
      }

      // меняем приоритет потока (ThreadPriority) на максимум
      Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    }
}

Что мы имеем ... Бесконечный цикл, который выполнеят все внутри себя, останавливается на 20 миллисекунд, и выполняет все снова и снова. Но как мы можем двигать круг, который нарисован в апплете?
Вот очень простая идея: наш круг имеет x- и y-позицию. Если мы добавим 1 к позиции x каждый раз, когда запускается поток, шар должен двигаться вдоль апплета, потому что он прорисовывается в разной позиции x.

А теперь давайте нарисуем круг. Добавьте эти строки в метод paint:

public void paint (Graphics g)
{

    // задаем цвет
    g.setColor (Color.red);

    // рисуем цветной круг
    g.fillOval (x_pos - radius, y_pos - radius, 2 * radius, 2 * radius);
}

Нам нужны следующие экземпляры переменных в заголовке программы

int x_pos = 10;
int y_pos = 100;
int radius = 20;

Чтобы передвинуть шар, мы меняем значение переменной x_pos каждый раз, когда запускается thread. Наш метод run должен выглядеть так:

public void run ()
{
...

    while (true)
    {
      // изменение x-позиции шара/круга
      x_pos ++;

      ...
    }
}

Если вы добавите этот апплет в HTML-документ, как мы это делали в предыдущей главе, красный шар единожды пересечет апплет.

Скачать исходный код апплета
Запустить апплет

Следующая глава:
Двойная буферизация

Fabian Birzele, 2001-2003.
перевод и веб-дизайн: В.Мурзагалин, 2004.