Программирование игр под J2ME: Начнем с GameCanvas

Июль 1st, 2010 от Abizan Оставить ответ »

Эта статья является продолжением цикла статей по программированию игр на платформе J2ME. В ней показано, как написать простенькое приложение с использованием класса GameCanvas.

Класс GameCanvas является потомком класса Canvas. GameCanvas специально оптимизирован для игр. В нем есть поддержка буфера, в котором выполняются все операции рисования. Когда рисование в буфере закончено, вызывается метод flushGraphics(), который рендерит содержимое буфера на экран. Система двойного буфера дает нам возможность не перерисовывать экран заново, если необходимо только добавить на него что-либо. Размеры буфера такие же, как у экрана. У каждого GameCanvas только один буфер.

У класса GameCanvas появился новый механизм обработки нажатий на клавиши. Этот механизм позволяет легко отслеживать, какие клавиши были нажаты и сколько раз. Функция getKeyStates() возвращает битовое представление состояния клавиатуры. Если перевести это число целого типа в двоичный вид, то получим нолики и единички. Каждая цифра соответствует какой-то кнопке на клавиатуре и описывает ее состояние: 1 – нажата, 0 – не нажата. В J2ME предустмотрены следующие состояния: DOWN_PRESSED, UP_PRESSED, RIGHT_PRESSED, LEFT_PRESSED, FIRE_PRESSED, GAME_A_PRESSED, GAME_B_PRESSED, GAME_C_PRESSED, and GAME_D_PRESSED

Ниже приведен код класса, расширяющего GameCanvas. Его реализация соответствует теории из первой статьи. В MyGameCanvas загружается картинка (троллфейс), которая двигается в зависимости от нажатой клавиши.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;
import java.io.IOException;

/**
 *
 * @author http://truecoder.ru
 */

public class MyGameCanvas extends GameCanvas implements Runnable {

    boolean keeprunning = false;
    // картинка троллфейс
    private Image trollFace;

    // координаты троллфейса
    private int trollFaceX;
    private int trollFaceY;

    // длина шага
    private int dx = 1;

    // центр экрана
    public final int CENTER_X = getWidth()/2;
    public final int CENTER_Y = getHeight()/2;


    public MyGameCanvas() {
        super(true);
        keeprunning = true;
    }

    public void start() {
        try {

            // Создаем и загружаем изображение,
            trollFace = Image.createImage("/trollfaceLol.png");
            trollFaceX = CENTER_X;
            trollFaceY = CENTER_Y;

        } catch(IOException ioex) { System.err.println(ioex); }

        Thread runner = new Thread(this);
        runner.start();
    }

    public void run() {
        // Объект Graphics для текущего GameCanvas
        Graphics g = getGraphics();

        while(keeprunning) { // бесконечный цикл

            // Проверяем, достигла ли игра определенного состояния
            // Или просто какие-то условия
            verifyGameState();

            // Получаем пользовательский ввод
            // Обновляем значения переменных, описывающих игровые объекты
            checkUserInput();

            // обновляем экран
            updateGameScreen(getGraphics());

            // даем другим потокам повыполняться и задерживаем игру
            try {
                Thread.currentThread().sleep(30);
            } catch(Exception e) {}

        }
    }

    private void verifyGameState() {
        // пока ничего не делает
    }

    private void checkUserInput() {

        // получаем состояние клавиатуры
        int keyState = getKeyStates();

        // Вычисляем положение троллфейса
        calculateFaceCoord(keyState);

    }

    private void updateGameScreen(Graphics g) {

        // Заливаем экран белым цветом
        g.setColor(0xffffff);
        g.fillRect(0, 0, getWidth(), getHeight());

        // рисуем троллфейс в нужных координатах
        g.drawImage(
        trollFace, trollFaceX,
            trollFaceY, Graphics.HCENTER | Graphics.BOTTOM);

        // Этот оператор отрисует содержимое буфера на экране
        flushGraphics();

    }

    private void calculateFaceCoord(int keyState) {

        // определяем, в какую сторону изменить
        // координату X
        if((keyState & LEFT_PRESSED) != 0) {
            trollFaceX -= dx;
        }
        else if((keyState & RIGHT_PRESSED) != 0) {
            trollFaceX += dx;
        }
        // определяем, в какую сторону изменить
        // координату Y
        if((keyState & DOWN_PRESSED) != 0) {
            trollFaceY += dx;
        }
        else if((keyState & UP_PRESSED) != 0) {
            trollFaceY -= dx;
        }

    }

}

Думаю тут все понятно по комментариям в коде. Если нет, спрашивайте! :)

А вот код мидлета:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import javax.microedition.midlet.*;
import javax.microedition.lcdui.Display;

/**
 * @author http://truecoder.ru
 */

public class Game extends MIDlet {

    private MyGameCanvas gCanvas;
    private Display display = Display.getDisplay(this);


    public Game() {
        gCanvas = new MyGameCanvas();
    }

    public void startApp() {
        gCanvas.start();
        display.setCurrent(gCanvas);
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
        display.setCurrent(null);
        notifyDestroyed();
    }
}

Скачать проект с исходниками этого примера

Реклама

3 комментариев

  1. Витя:

    здраствуйти мне очень нужна помащ я написал програму на телефон игра 4 в линию у меня такая проблема я не очень понел как при выгреше мне заменить рисунок на даске победителя на другова цвета рисунок дапустим в игре ктота победил уменя в игре пишет плейр 1 или 2 выграл но на даске игры надо искать победу я хотел бы чтоб там где был выгрыш обозночалось другим цветом я магу вам послать сваю програму мне если можно памагите очь нужна помащь

  2. Витя:

    Вот сылка на маю игру http://ifolder.ru/22638611
    игру строил в netbeans 6.9.1 или 6.5.1
    если вазможно мне нужен ответ севодня
    вот сылка на игру где мне нада будет и какую строчьку в писать в моей програме чтоб она выделяла на даске игры победителя

  3. RS8:

    Полезные статьи на старте, спасибо. Единственное что, если (а там есть такое) используется ссылка на объект из соседней статьи (например загруженную картинку) неплохо было бы на нее и ссылку тут же поставить, дабы меньше искать.

Добавить комментарий

Копирование материалов сайта допускается только с разрешения администрации сайта.