Select your language:

Home Главная | Registration Регистрация | Login Вход

Menu Меню сайта
Statistics Статистика

Total online: Онлайн всего: 1
Guests: Гостей: 1
Members: Пользователей: 0
Study entry Форма входа
Логин:
Пароль:
Забыл пароль | Регистрация

Ссылки:

Перемещение объекта с помощью клавиш НИМ ШШЛ

191

можно применить оператор switch и тогда метод keyPressed ( ) может принять следующий вид:

protected void keyPressed(int keyCode) {

// получаем игровые события

int act = getGameAction(keyCode) ;

// обработка событий

switch(act)

{

case Canvas. LEFT:

/ / движение влево

break; case Canvas . RIGHT;

/ / движение вправо

break; case Canvas. UP:

// движение вверх

break; case Canvas. DOWN:

/ / движение вниз

break; default -. break; }

} }

Код обработки для клавиш зависит от того, что именно вы желаете сделать с объектом. Давайте возьмем за основу код из листинга 7.5, где был нарисован квадрат, и модернизируем его. Выведем синий квадрат на экран, для этого создадим две переменные positionX и positionY, отвечающие за точку вывода квадрата на экран и присвоим им значения близкие к центру экрана.

int positionX = getWidth()/2; int positionY = getHeight

При нажатии клавиш можно воспользоваться значениями переменных positionX и positionY для перемещения квадрата по экрану, увеличивая или уменьшая значения этих двух переменных. Значение, на которое вы будете увеличивать или уменьшать переменные, фактиче ски будет обозначать скоро сть пе -ремегцения квадрата по экрану. В листинге 7.8 дается полный код программы перемещения элемента по экрану с помощью клавиш, который можно также найти на компакт-диске в папке \Code\Listing7_8\src.

Листинг .7. 8

Класс Main и класс Draw */

import j avax.microedition.lcdui.*; import javax.microedition.midlet.*;

public class Main extends MIDlet implements CommandListener .

{

// команда выхода из программы

private Command exitMidlet = new Command («Выход», Command.EXIT, 0);■

public void StartAppO {

// создаем объект класса Draw Draw dr = new Draw();

// запускаем поток dr.start() ,-

// добавляем команду выхода dr.addCommand(exitMidlet); dr.setCommandListener(this);

Display .getDisplay (this) .SetCurrent(dr) ,-

)

public void pauseApp() {}

public void destroyApp(boolean unconditional){}

public void commandAction(Command c, Displayable d) {

if (c == exitMidlet)

{ *

destroyApp(false); .notifyDestroyed();

}

класс Draw определен в файле Draw.Java

передвижение квадрата с помощью клавиш телефона V

import javax.microedition.lcdui,* ;

Перемещение объекта с помощью клавиш

public class Draw extends Canvas irnplements Runnabl {

// устанавливаем квадрат в центр экрана int positionX = getWidtM > 12; 11 устанавливаем квадрат в центр экрана int positionY = geCHeight ( ) 12; I/ конструктор public Draw () {.super() ; }

public void start () {

♦// создаем и запускаем поток Thread t = new Thread (this ) ; t .start () ;

}

// метод run интерфейса Runnable public void run

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

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

// останавливаем цикл на 20 миллисекунд try { Thread, sleep (20) ■; }

catch (java.lang.InterruptedException zxz) {} }

}

public void paint (Graphics g)

{

// вычисляем область для перерисовки экрана

int х = g.getClipWidthO ;

int у = g.getClipHeight { ) ;

// устанавливаем белый цвет фона

g. setColor(0xffffff ),-

// назначаем перерисовку всему экрану g.fillRect(0,0,x,y);

// устанавливается зеленный цвет квадрату g. setColor(0, О, 200);

// рисуем квадрат

g. fillRect(positionX, positionY, 20, 20);

BZI^IHHUIII Программирование графики

}

protected void keyPressed (int keyCode) {

// скорость передвижения

int speed = 3;

// получаем игровые события

int act = getGameAction(keyCode> ,-

// обработка событий

switch(act)

// движение влево case Canvas.LEFT:

i positionX -= speed; break;

// движение вправо case Canvas . RIGHT :

positionX - = speed;

break; // движение вверх case Canvas.UP:

positionY -= speed;

break; // движение вниз case Canvas.DOWN:

positionY += speed;

break; default: break; }

}

В следующей главе рассматриваются игровые классы, доступные в профиле -MIDP 2.0 и значительно упрощающие создание игрового цикла, а также игровой графики.

Глава 8. Техника создания игр

Рынок мобильных телефонов развивается стремительными темпами. Все больше телефонов имеют поддержку технологии Java. Веянье игровой индустрии захватило и мобильные телефоны, поэтому платформа Java 2 ME позиционируется в большей степени как игровая платформа для мобильных телефонов. При разработке игр под профиль MIDP 1.0 программист сталкивается с массой проблем в виде написания большого количества собственных классов для создания игрового процесса, рисование графики, уровней и так далее. В профиль MIDP 2.0 добавлено пять игровых классов, значительно упрощающих создание мобильных игр, это: ,

□ Game Canvas — абстрактный класс, содержащий основные элементы игрового интерфейса;

□ Layer - абстрактный класс, отвечающий за уровни представляемые в игре;

□ LayerManager - менеджер уровней;

□ Sprite - представляет на экране спрайтовое изображение;

□ TiledLayer— отвечает за создание фоновых изображений.

Все вышеперечисленные классы доступны только в профиле MIDP ZO. Также можно воспользоваться этими классами и в программировании телефонов Siemens под профиль MIDP 1.0, импортировав пакет com.siemens.mp.color_j*ame. Компания Siemens входит в экспертную группу MIDP Expert Group и, по всей видимости, на базе уже имеющихся игровых классов от компании Siemens были созданы игровые классы для профиля MIDP 2.0.

^ При использовании игровых классов профиля MIDP Z0, построение мобильной игры основано на системе уровней. Формируя игру, программист создает необходимое ему количество уровней. Каждый из уровней содержит набор графических элементов, например, можно создать уровень с фоновым изображением, уровень с препятствиями, уровень с игровыми бонусами, уровень с главным персонажем игры. После этого все имеющиеся уровни компонуются воедино, накладываются один уровень на другой и прорисовываются на экране телефона. Контроль над всеми уровнями, осуществляется при помощи класса LayerManager -менеджера уровней. Обилие методов предоставляемых игровыми классами позволяет отслеживать всевозможные столкновения, перемещения, анимацию и множество других функций, что значительно упрощает процесс создания мобильных игр.

В этой главе, сначала вы познакомитесь с устройством всех игровых классов, а затем будет создан ряд примеров иллюстрирующих работу и взаимодействие игровых классов профиля MIDP ZO.

8-1. Класс GameCanvas

Абстрактный класс GameCanvas составляет основу интерфейса всей создаваемой игры. Этот класс отвечает за прорисовку экрана, улучшая механизм работы игрового цикла и не используя при этом входные системные потоки. Весь игровой процесс может быть сосредоточен в одном цикле метода run С) интерфейса Runhable.

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

* public voidrun() {

. Graphics g = getGraphics () while (true)

{

// метод, обрабатывающий нажатия клавиш с телефона 1 inputKey();

// метод, прорисовывающий графику GameGraphicsO; ■

// копирует графические элементы на экран из .

внеэкранного буфера flushGraphicsO ;

}

Система прорисовки игровой графики построена на использовании двойной буферизации, без которой невозможно создать ни одной хорошей компьютерной игры. Смысл механизма двойной буферизации заключается в использовании внеэкранного буфера. Вся игровая графика рисуется во вторичном или внеэкран-. ном буфере и только после полного цикла отрисовки, копируется непосредственно на экран с помощью метода f lushGraphics ( ) . При этом улучшается качество самой графики и, что самое главное, до тех пор, пока игровой процесс не обновится, обработка собьпий с клавиш телефона является недоступной.

Сама же обработка событий с клавиш упрощена с помощью метода getKey-State () . Вы просто определяете нажатую клавишу и описываете соответствующие игровые действия для нее. Изменены некоторые названия констант для клавиш телефона. Обработка событий с клавиш телефона происходит с помощью следующих констант:

□ static int DOWN_PRESSED - движение вниз;

□ static int FIRE_PRE£SED-реализует стрельбу из оружия;

Класс Layer

Q static int Game_a_pressed - игровая клавиша A; Q static int GAME_B_PRESSEt) - игровая клавиша В; Q static int GAME_c_PRESSED - игровая клавиша С; Q static int GAME_d_pressed - игровая клавиша D; Q static int LEFT_PRESSED - движение влево; Q static int RIGHT_PRESS'ED - движение вправо; Q static int UP_PRESSED - движение вверх.

Использование констант значительно упрощает, работу с объектом, а с помощью метода getKeyStates (1 класса GameCanvas, можно определить, какая именно клавиша нажата в данный момент. Проанализируем методы класса GameCanvas:

□ void flushGraphics () - копирует изображение из внеэкранного буфера на экран;

□ void flushGraphics (int х, int у, int width, int height) -копирует изображение из внеэкранного буфера на экран в заданный по размеру прямоугольник;

□ protected Graphics getGraphics ^ ■ - получает графические элементы для представления их в последствии классом GameCanvas;

□ int getKeyStates () - определяет какая из клавиш нажата;

G void paint (Graphics g) — рисует графические элементы, представленные классом GameCanvas.

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

8.2. Класс Layer

Абстрактный класс Layer задает основные свойства для всех созданных уровней игры.

Класс Layer имеетдва подкласса Tile dLayer и Sprite. При созданиилю-бых других подклассов класса Layer необходимо реализовать метод paint () в этих классах, чтобы иметь возможность рисовать созданные уровни на экране телефона, представляемом классом Graphics. С помощью методов класса Layer можно задаватъразмер и позицию уровня.

□ int getHeight () - получает высоту экрана; О int getwidth() - получает ширину экрана;

□ int getx() - получает горизонтальную координату уровня;

□ int getY () - получает вертикальную координату уровня;

□ void move (int dx, int dy) - перемещаетуровеньнаdxиdyкоординаты;

Q abstract void paint (Graphics g) — рисует уровень;

□ void setPosition (int x, int у) - устанавливает уровень в позицию, обозначенную в координатах х и у.

ствляет представление любого количества уровней на игровом поле. Для создания объекта нужно воспользоваться конструктором класса LayerManager. G LayerManager () - создает уровень.

А чтобы добавить уровни в игру необходимо использовать следующие методы: О void append (Layer 1) - добавляет уровень в менеджер уровней; Q Layer getLayerAt (int index) - получает уровень с заданным индексом;

Техника создания игр

□ int getSize ()-получает общее количество уровней;

□ void insert (Layer 1, int index) - подключает новый уровень в заданный индекс;.

□ void paint (Graphics g, int x, int у)— представляет текущий менеджер уровней в заданных координатах;

□ void remove (Layer 1) - удаляет уровень из менеджера уровней.

Предположим, у вас имеется четыре уровня: фон, игрок, препятствия и артефакты. Для того чтобы связать все четыре уровня воедино, создается объект класса LayerManager и вызывается метод append \ Например:

La'yerManager lm = new LayerManager (); lm.append(fon); lm.append(igrok) lm.append(prep); , lm.append(artf);

И все! Четыре перечисленных уровня отражается на игровом поле.

8.5. Класс Sprite

Механизм работы с объектом класса Sprite идентичен модели работы с классом TiledLayer. Но если класс TiledLayer в основном отвечает за фоновое изображение, то с помощью класса Sprite рисуются на экране основные анимированные герои, космические корабли, машины, люди, звери, артефакты и так далее. Изображение, загружаемое в игру, может быть выполнено в виде анимационной последовательности. Количество рисунков в анимационной последовательности неограниченно, а отсчет происходит от нуля. Располагаться рисунки могут как в виде столбца, так и в виде колонки, в зависимости от ваших предпочтений. Каждый рисунок анимационной последовательности называется фреймом. Фрейм может быть любого размера по ширине и высоте, но все фреймы должны быть одинаковых размеров. Размер фрейма должен быть известен, потому что он используется при создании объекта класса Sprite. Есть три конструктора класса Sprite каждый из которых можно использовать при создании объекта класса Sprite.

□ Sprite (Image image) - создает не анимированный спрайт;

□ Sprite(Image image, int frameWidth, int frameHeight)- создает анимационный спрайт, взятый из заданного фрейма;

О Sprite(Sprite s) - создает спрайт из другого спрайта. Для перехода по фреймам исходного изображения, а также определения столкновения между объектами используются методы класса Sprite.

□ boolean collidesWith(Sprite s, boolean pixelLevel) - определяет столкновение между спрайтами;

□ boolean collidesWith(TiledLayer t, boolean pixelLevel)-. определяет столкновение между спрайтом и препятствием, нарисованным при помощи KnaccaTiledLayer;

8.3. Класс TiledLayer

С помощью класса TiledLayer создается фон игровой сцены. Фоновое изображение выполняется в виде одинаковых по размеру ячеек как показано на рис. 8.1.

Создание фонового изображения

□ int getFrame ') - получает текущий фрейм;

□ void nextFrame () - осуществляет переход на следующий фрейм;

□ void paint (Graphics g) - рисует спрайт;

□ void prevFrame () - осуществляет переход, на предыдущий фрейм;

О void setFrame(int sequencelndex) - устанавливает заданный фрейм; Q void setFrameSequence (int [ ] sequence) - устанавливает определенную фреймовую последовательность; О void setlmage(Image img, int frameWidth, int frameHeight)-■ н-изменяетизображение спрайта на новое изображение; О void setTransf orm (int transform) - производит трансформацию спрайта.

Q public void def ineReferencePixel (int x, int у)- изменяет опорную позицию спрайта, перенося ее в точку с координатами х и у.

Метод defineRef erencePixel () изменяет опорную позицию спрайта, но для чего это нужно? Опорная позиция для спрайта задается левым верхним углом, но не всегда это удобно, поэтому опорную позицию можно перенести, в центр спрайта. Например, если спрайт сделан в виде машины, то при вращении вокруг своей оси, если опорная позиция перенесена в центр, вращение будет правдоподобным. Но если не переопределить позицию, то вращение произойдет в точке левого верхнего угла спрайта и выглядеть это будет не вполне естественно, как будто у машины пробито одно из колес. Для этого вызывается метод defineRef erencePixel () с заданными координатами и переопределяет опорную позицию, например в центр спрайта:

■I

defineReferencePixel(frameWidth / 2, frameHeight / 2);

' Me/nodsetTransf orm () производит трансформацию спрайта, вращая или зеркально отображая спрайт вокруг своей оси с помощью следующих констант:

□ static int TRANS_MIRROR;

□ static int TRANS_MIRROR_ROT180;

□ static int TRANS_MIRROR_ROT270; •

□ static int TRANS_MIRRQR_RQT90;

□ static int TRANS_NONE;

a static int TRANS_ROTl80; D static int TRANS_ROT270; D static int TRANSROT90.

Посмотрите на рис. 8.2, где очень привлекательно показаны константы для различных состояний спрайта.

Рассмотрев классы GameCanvas, Layer, Sprite, TiledLayer и Layer-Manager, перейдем к практическим занятиям этой главы.

8.6. Создание фонового изображения

С помощью класса Ti led Layer можно создавать любое количество уровней, накладывая их друг на друга, а с помощью менеджера уровней, представленного

4 ±

■ I I

TBANS_NONE TRANS R0T180

Г 4

TRANS.HIRROR TRANS_HIRROR_ROT180 TRANS R0T9O TRANS_HIRROR ROTSO

* iK

TRANS_HIRR0R_R0T270 TRANS_R0T270

Рис. 8.2. Константы трансформации

public class MainGame extends MIDlet implements CommandListener

{

// команда выхода

private Command exitMidlet = new Command("Выход',

Command.EXIT, 0) ;

// объект класса MyGameCanvas

private MyGameCanvas mr;

public void startAppO {

// обрабатываем исключительную ситуацию try{

// инициализируем объект класса MyGameCanvas mr = new MyGameCanvas();

// запускаем поток mr.start () ;

// добавляем команду выхода mr.addCommand(exitMidlet); mr.setCommandListener(this);

// отражаем текущий дисплей

Display.getDisplay(this).setCurrent(mr);

}catch (java.io.IOExceptipn zxz) {};

}

классом LayerManager, отслеживать все имеющиеся уровни. В качестве примера будет создан фон на основе элементов разметки игрового поля. Фоновое изображение загружается из файла fon.png. Само изображение выполнено в виде шести ячеек размером 15x15 пикселей.

В листинге 8.1 находится код примера создающего фоновое изображение. Ознакомьтесь с листингом, а потом мы перейдем к анализу этого примера.

/**

листинг 8.1 класс MainGame

*/

import

javax.microedition.lcdui.*;

import

javax.microedition.midlet.*;


Для перехода к следующей странице статьи перейдите по вы подающему меню


Basket Корзина
Your basket is empty Ваша корзина пуста
'); $(el).append(g); $(g).show(); } _uPostForm('',{type:'POST',url:'/shop/basket',data:{'mode':'clear'}}); return false; } function removeBasket(id){ if(lock_buttons) return false; else lock_buttons = 1; $('#basket-item-'+id+' .sb-func').removeClass('remove').addClass('myWinLoadS').attr('title',''); _uPostForm('',{type:'POST',url:'/shop/basket',data:{'mode':'del', 'id':id}}); return false; } function add2Basket(id,pref){ if(lock_buttons) return false; else lock_buttons = 1; var opt = new Array(); $('#b'+pref+'-'+id+'-basket').attr('disabled','disabled'); $('#'+pref+'-'+id+'-basket').removeClass('done').removeClass('err').removeClass('add').addClass('wait').attr('title',''); $('#'+pref+'-'+id+'-options').find('input:checked, select').each(function(){ opt.push(this.id.split('-')[3]+'-'+this.value);}); _uPostForm('',{type:'POST',url:'/shop/basket',data:{'mode':'add', 'id':id, 'pref':pref, 'opt':opt.join(':'), 'cnt':$('#q'+pref+'-'+id+'-basket').attr('value')}}); return false; } function buyNow(id,pref){ if(lock_buttons) return false; else lock_buttons = 1; var opt = new Array(); $('#b'+pref+'-'+id+'-buynow').attr('disabled','disabled'); $('#'+pref+'-'+id+'-buynow').removeClass('done').removeClass('err').removeClass('now').addClass('wait').attr('title',''); $('#'+pref+'-'+id+'-options').find('input:checked, select').each(function(){ opt.push(this.id.split('-')[3]+'-'+this.value);}); _uPostForm('',{type:'POST',url:'/shop/basket',data:{'mode':'add', 'id':id, 'pref':pref, 'opt':opt.join(':'), 'cnt':$('#q'+pref+'-'+id+'-basket').attr('value'), 'now':1}}); return false; } //-->
Search Поиск
Calendar Календарь
«  March Март 2011  »
Mon Пн Tues Вт Wed Ср Thurs Чт Fri Пт Sat Сб Sun Вс
  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
Archive records Архив записей

Ссылки:

Rambler's Top100 Все для дома - Бытовая техника, опубликовать информацию о фирме
QLE 88x31

раскрутка сайта в интернете Рейтинг сайтов Товары / Услуги

Copyright MyCorp © 2011 Создать сайт бесплатно

Copyright MyCorp © 2011