В прошлом подавляющее большинство игр для телефонов использовали меню на основе форм - базового интерфейса телефона. Эти
"менюшки" смотрелись убого и явно выбивались из игрового дизайна. Сейчас требования к играм существенно возросли, и пользователи требуют интересных графических решений. В этой статье я хочу рассказать, как можно реализовать графическое меню на основе
Сanvas.
Класс
Canvas является
абстрактным. Чтобы его использовать, вы должны организовать его подклассы. Ваш конкретный подкласс описывает новый компонент с поведением по обработке команд и событий и с помощью класса
Graphics определяет свой собственный внешний вид.
Для начала давайте посмотрим как выглядит типичный
Canvas:
import javax.microedition.lcdui.*;
public class MyCanvas extends Canvas implements Runnable {
private static boolean running;
public MyCanvas() { // Конструктор
}
public void run(){
try {
while (running) {
//Главный игровой цикл
}
}
catch(InterruptedException ie) { System.out.println(ie.toString()); }
}
protected void paint(Graphics g){ /* code */ }
synchronized void start() {
running = true;
}
synchronized void stop() {
running = false;
}
public void keyPressed(int keyCode) { /* code */ }
}
Создадим класс
GMenu. Он осуществляет все те же функции, что и приведенный выше код.
import javax.microedition.lcdui.*;
public class GMenu extends Canvas implements Runnable {
private static boolean running;
/* Меню */
private String mString[] = {
"Новая игра","Опции", "Авторы", "Выход"};
private int xPos; // X координата пункта меню
private int yPos; // Y координата пункта меню
private int widthMenu; // Ширина пункта меню
private int heightMenu; // Высота пункта меню
private int spaceMenu; // Расстояние между пунктами меню
private int index; // Индекс текущего пункта меню
/* Экран */
private int width; // Ширина экрана
private int height; // Высота экрана
public GMenu() {
/*
Без вызова super() ваши экземпляры
Canvas не смогут действовать как настоящие Canvas. Они не будут
отображаться правильно, они не будут отрисовываться должным образом и они
не смогут обрабатывать события.
*/
super();
/* Экран */
width = getWidth(); //Определяем ширину экрана
height = getHeight(); //Определяем высоту экрана
/* Меню */
spaceMenu = height/8; // Устанавливаем расстояние между пунктами меню (Ширина экрана / 8)
xPos = width/2; // Устанавливаем Y координату пункта меню (Ширина экрана / 2)
yPos = height/8; // Устанавливаем Y координату пункта меню (Ширина экрана / 8)
widthMenu = 80; //Устанавливаем ширину пункта меню
heightMenu = 20; //Устанавливаем высоту пункта меню
index = 0;
}
public void run(){
try {
while (running) {
Thread.sleep(20L);
}
}
catch(InterruptedException ie) { System.out.println(ie.toString()); }
}
protected void paint(Graphics g){
g.setColor(255, 255, 255); // Задаем цвет (Белый)
g.fillRect(0, 0, getWidth(), getHeight()); // Очистка экрана
g.setColor(0, 0, 0); //Задаем цвет (Черный)
for(int i=0; i<mString.length; i++){ // Рисуем все пункты меню
g.drawRect(xPos - widthMenu/2, yPos + spaceMenu * i, widthMenu, heightMenu);
g.drawString(mString[i], xPos, yPos + spaceMenu * i, g.TOP | g.HCENTER);
}
g.setColor(255, 0, 0); // Задаем цвет (Красный)
g.drawRect(xPos - widthMenu/2, yPos + spaceMenu * index, widthMenu, heightMenu); // Рисуем прямоугольник
repaint(); //Перерисовываем изменения
}
synchronized void start() {
running = true;
Thread thread = new Thread(this); //Создаем новый поток
thread.start();
}
synchronized void stop() {
running = false;
}
public void keyPressed(int KeyCode) {
switch(KeyCode){
case -2: // Вверх (Up)
if(index < mString.length - 1)
index++;
break;
case -1: // Вниз (Down)
if(index > 0)
index--;
break;
case -5: // Огонь (Fire)
//
break;
}
}
}
В следующих статьях мы реализуем поддержку изображений и дополним функциональность нашего меню.
Скачать исходный код к статье (WTK) Вы не можете скачивать файлы с нашего сервера