ЛАБОРАТОРНЫЕ РАБОТЫ

Игра "Пятнашки". Реализация в виде мидлета

[ Сайт ДонНТУ ]      [ На главную ]

Задание:

Заданием лабораторной работы являлось разроботка приложения на языке Java-мидлета. В моем случае приложение - это игра "Пятнашки". Весь отчет разбит на слеующие части:
->Руководство пользователя
->Руководство программиста
->Листинг программы

Руководство пользователя

!!!Тестирование производилось на телефоне Samsung X100. Все дальнейшее описание будет именно для этой модели телефона!!! После установки игры в телефон, запускаем игру, в следствии чего пользователь должен увидеть следующий экран:

Если игрок нажал Start, тогда

Рассмотрим, управление игрой. С помощью джойстика на телефоне обозначенным меткой 4. Пользователь перемещает курсор по игровому полю. На экране выводится игровое поле отмеченное меткой 1. Счетчик ходов имеет метку 3. Метка 2 указывает, что можно либо вйти из игры, либо обменять местами число с пустой ячейкой. алее следует описать цель и правила игры.
Цель игры состоит в том, чтобы за минимальное число перестановок расставить числовую последовательность от 1 до 15 в порядке возрастания, так чтобы в пустое место на поле оказалось на самой последней позиции.Правило игры одно. Игрок имеет право поменять местами число и пустое поле местами, только в том случае если их разница в позиции не превышает 1. перестановки по диагонали не допускаются.

Руководство программиста

В начале рассмотрим несколько UML диаграмм, которыя я составил для моего приложения.

Эта диаграмма показывает состояния работы любого мидлета. Поясним. Мидлет может находиться в 3 состояниях и переходить из одного в другое. Название этих состояний следующее: PAUSED,DESTROYED,ACTIVE. Что означает, что мидлет может быть приостановлен, либо быть активн, либо может быть уничтожен. И последняя диаграмма имеет следующий вид.

Поясним коротко смысл этой диаграммы. Существуют 3 дорожки.Первая - это игрок, вторая система телефона, и третья - это сама игра. Пользователь активизируется и нажимает кнопку, затем система получает управление и запускает игру, получив управление от системы, игра выполняется и выдает результат системе. Система передает рез-тат игроку. Прямоугольниками обозначен активное действия той или иной дорожки. Ну а теперь, вернемся у рассмотрению программы. Было создано 3 класса:
Board//Класс который дополняет другой класс и в нем происходит основной игровой процесс
fifts//Оболочка игры, меню, помощь, и.т.д
ImageItem//Класс для прикрепления картинок к форме
Все классы находятся в отдельных файлах с расширением java. Давайте рассмотрим каждый класс более подробно.Класс Board. Он содержит следующие важные функции:keyPressed(),setText(),paint(),init(). Фцнкция keyPressed() отлавливает нажатия клавиш и взависимости от нажатой клавиши выполняет то или иное действий.Например при нажатии кнопки влево, курсор перемещается влево на 1 позицию. Функция setText() производит перестановку цифр в таблице и ведеи счет ходов. Функция paint() отрисовывает поле, все его графические элементы. Поле рисовалось при помощи методов: drawLine, drawRect, fillRect, fillArc, drawArc, drawText. Описывать эти функции и их работу не имеет смысла, так как эта информация содержиться в любом справочнике. Более деиально ознакомиться с работой программы вы можете в пункте листинг ррограммы, для этого там приведены комментарии. Далее следует класс ImageItem. Он очень прост.Так как содержит всего один конструктор. Описывть его нет смысла так как там одна строчка super("").И последним классом является класс fifts. Он содержит главные функции startApp(),по которой стартует игра и destroyApp() выход из игры. Примечание: процедуру setText в листинге вы не найдете. Вы можете ее изучить, если скачаете архив с игрой и ее исходниками. Ссылка расположена в конце страницы.

Листинг программы

fifts.java
//Класс fifts является базовым классом мидлета. Название было взято из первого моего созданного мидлета. Класс содержит запуск приложения, выход их него, блок прослушивания комманд. Реакции на нажатия клавиш.
public class fifts extends MIDlet
{
public Form form; //Обьявление главной формы
public Form form2; //Форма помощи
public Form form3; //Форма игры
public Display display; //Класс дисплей!!!
public MyCommandListener cl=new MyCommandListener();
public Command exit; //Кнопки...
public Command o_n;
public Command back;
public Command back2;
public Command s_t;
public ImageItem imageItem;
//Конструктор
public fifts()
{
super();
}
//Выход из приложения
public void destroyApp(boolean destroy)
{
form = null;
notifyDestroyed();
}
//Пауза приложения
public void pauseApp()
{
}
//Процедура выхода
public void quit()
{
destroyApp(true);
notifyDestroyed();
}
//Вывод на экран помощи
public void help()
{
form2=new Form("Help"); //Создаем форму
String msg= "Use joystick to rotate cells try to form all cells in row in minimal turns!!! The winning combination is shown below.";
form2.append(msg); //Прикрепляем к форме сообщение объявленное выше
//Здесь пытаемся прикрепить к форме рисунок если не можем то обработка иск. ситуации
try{
Image image=Image.createImage("/JavaPowered-81.png");
form2.append(new ImageItem(null, image, ImageItem.LAYOUT_CENTER, null));
}
catch (Exception e)
{
e.printStackTrace();
}
back=new Command("BACK",Command.BACK,1);//Кнопка
form2.addCommand(back); //Добавляем кнопку к форме
form2.setCommandListener(cl); //Устанавливаем блок прослушивания комманд
display.setCurrent(form2); //Выводим форму на экран
}
//Начало новой игры...
public void paint1()
{
Board b;
b = new Board(this);
Display.getDisplay(this).setCurrent(b);
}
//Процедура начала приложения
public void startApp()
{
form=new Form("15"); //Главная форма
String msg= "Midlet is written by DMITRY MAZALOV BT-00a!!";
form.append(msg);//Крепим сообщение к форме описанное выше
//Здесь пытаемся прикрепить к форме рисунок если не можем то обработка иск. ситуации
try
{
Image image=Image.createImage("/JavaPowered-8.png");
form.append(new ImageItem(null, image, ImageItem.LAYOUT_CENTER, null));
}
catch (Exception e)
{
e.printStackTrace();
}
//Так как описывать все лень, то дальше идет прикрепление команд и установка блока прослушки а также вывод формы на дисплей
s_t=new Command("Start",Command.SCREEN,1);
form.addCommand(s_t);
o_n=new Command("Help",Command.SCREEN,1);
form.addCommand(o_n);
exit=new Command("Exit",Command.EXIT,1);
form.addCommand(exit);
form.setCommandListener(cl);
display=Display.getDisplay(this);
display.setCurrent(form);
}
//Блок прослушивания комманд
private class MyCommandListener
implements CommandListener
{
public void commandAction(Command c,Displayable d)
{
if (c==s_t) //Если нажали клавишу старт
{
paint1();
}
if (c==o_n) //Если нажали помощь,то показать помощь!!!
{
help();
}
if (c==exit) //Выход из мидлета
{
quit();
}
if (c==back) //Показать главную форму
{
display.setCurrent(form);
}
if (c==back2)
{
display.setCurrent(form); //См. выше
}
}
}
}
ImageItem.java
//Класс служит для отображегий картинок на форме...
public class ImageItemDemo extends Form
{
public ImageItemDemo() throws IOException
{
super("");
}
}
Board.java //Класс Board расширяет класс Canvas
public class Board extends Canvas implements CommandListener {

MIDlet midlet;
Display dpy;//Объект Display

boolean winner=false;//Флаг проверки на выйгрыш
Form form;//Форма
int posx=0;
int posy=0;
int gridw = getHeight()-20;//размер по ширине
int gridh = getHeight()-20;//размер по высоте
int delta=0;
int delta2=0;
int disp=(gridh)/4;
int disp2=(gridw)/4;
int filx=2;
int fily=2;
int filx2=disp-3;
int fily2=disp2-3;
int countclick=0;
int countclick2=0;
int currentX=0;
int currentY=0;
int mymoves=0;//Счетчик кол-ва ходов
String moves="0";
String a="1";

Font font;
String[][] data = new String[4][4];//Матрица стринговых элементов

Command rotate = new Command("Rotate", Command.SCREEN,1);//Кнопка
Command exit = new Command("EXIT", Command.SCREEN,1);//Кнопка выхода

public Board(MIDlet midlet_) {
int i;
init();
midlet = midlet_;
dpy = Display.getDisplay(midlet);
addCommand(rotate);//добавляем команды
addCommand(exit);//
setCommandListener(this);//устанавливаем блок прослушивания команд
}

public void init()
{//Инициализация игрового поля
data[0][0]="1";
data[0][1]=" ";
data[0][2]="2";
data[0][3]="3";
data[1][0]="4";
data[1][1]="5";
data[1][2]="6";
data[1][3]="7";
data[2][0]="8";
data[2][1]="9";
data[2][2]="10";
data[2][3]="11";
data[3][0]="12";
data[3][1]="13";
data[3][2]="14";
data[3][3]="15";
}

public void paint(Graphics g) {//Отрисовка поля и расстановка на нем чисел, установка курсора
font = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_ITALIC|Font.STYLE_BOLD, Font.SIZE_LARGE);
g.setFont(font);
g.setColor(0xFFFFFF);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(0);
g.drawRoundRect(1,1,gridw,gridh,gridw/6,gridh/6);
g.setStrokeStyle(1);
for(int i=1;i<4;i++)
{
g.drawLine(1,disp*i,gridw,disp*i);
g.drawLine(disp2*i,1,disp2*i,gridw);
}
g.setStrokeStyle(0);
g.setColor(0xE0B070);
int oldcolor;
int color=1;
int disp3;
disp3=1;
int disp4=1;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if (data[i][j]==" ") //Вывод содержимого массива на экран
{
g.drawArc(filx+disp3,fily+disp4,filx2,fily2,0,0);
}
else
g.drawArc(filx+disp3,fily+disp4,filx2,fily2,0,360);
g.fillArc(filx+disp3,fily+disp4,filx2,fily2,0,0);
disp3=disp3+disp2;
}
disp3=1;
disp4=disp4+disp;
}
g.drawArc(filx+delta,fily+delta2,filx2,fily2,0,360);
g.fillArc(filx+delta,fily+delta2,filx2,fily2,0,360);
g.setColor(0x111111);
String abc;
int compare;
int dx=0;
int dy=1;
g.drawString(moves,gridh-10,gridw, Graphics.TOP | Graphics.LEFT);//Выводим кол-во ходов
g.drawString("Moves:",1,gridw, Graphics.TOP | Graphics.LEFT);
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
abc=data[i][j];
compare=abc.length();
if (compare>1)
{
dx=dx+3;
dy=dy+3;
g.drawString(data[i][j], dx, dy, Graphics.LEFT|Graphics.TOP);
dx=dx+disp2;
dy=dy-3;
dx=dx-3;
}
else
{
dx=dx+7;
dy=dy+3;
g.drawString(data[i][j], dx, dy, Graphics.LEFT|Graphics.TOP);
dx=dx+disp2;
dy=dy-3;
dx=dx-7;
}
}
dy=dy+disp;
dx=1;
}
}

public void wins()
{//Проверяем выйгрышную комбинацию и если выйграли, то выводим картинку и текст
if ((data[0][0]==" ")&(data[0][1]=="1")&(data[0][2]=="2")&(data[0][3]=="3")&
(data[1][0]=="4")&(data[1][1]=="5")&(data[1][2]=="6")&(data[1][3]=="7")&
(data[2][0]=="8")&(data[2][1]=="9")&(data[2][2]=="10")&(data[2][3]=="11")&
(data[3][0]=="12")&(data[3][1]=="13")&(data[3][2]=="14")&(data[3][3]=="15"))
{
removeCommand(rotate);
repaint();
winner=true;
form=new Form("WINNER!!!!!!!!");
String msg= "Congratulation you win the game in " + moves +" move(s)";
form.append(msg);
try
{
Image image=Image.createImage("/wins.png");
form.append(new ImageItem(null, image, ImageItem.LAYOUT_CENTER, null));
}
catch (Exception e)
{
e.printStackTrace();
}
form.addCommand(exit);
form.setCommandListener(this);
dpy.setCurrent(form);
}
}

public void setText()
{//Здесь мы обмениваем местами элементы массива и увеличиваем счетчик ходов
if ((currentX==0)&(currentY==0))
{
if (data[currentY][currentX+1]==" ")
{
data[currentY][currentX+1]=data[currentY][currentX];
data[currentY][currentX]=" ";
mymoves++;
moves="1".valueOf(mymoves);
wins();
repaint();
}
}


public void keyPressed(int code) {//реакция на нажатия клавиш
int game = getGameAction(code);
switch (game) {
case Canvas.UP:
countclick2--;
if (currentY==0)
currentY=0;
else
currentY--;
if (countclick2<1)
{
delta2=0;
countclick2=1;
break;
} delta2=delta2-disp2;
break;

case Canvas.DOWN:
countclick2++;
if (currentY==3)
{
currentY=3;
}
else
currentY++;
if (countclick2>3)
{
delta2=3*disp;
countclick2=4;
break;
}
delta2=delta2+disp2;
break;

case Canvas.LEFT:
countclick--;
if (currentX==0)
{
currentY=0;
}
else
currentX--;
if (countclick<1)
{
delta=0;
countclick=1;
break;
}
delta=delta-disp;
break;

case Canvas.RIGHT:
countclick++;
if (currentX==3)
{
currentX=3;
}
else
currentX++;
if (countclick>3)
{
delta=3*disp;
countclick=4;
break;
}
delta=delta+disp;
break;
}
repaint();
}

public void commandAction(Command c, Displayable d) {//Что выполнять если нажали одну из клавиш на дисплее
if (c==exit)
{
midlet.notifyDestroyed();
}
if (c==rotate)
{
if(data[currentY][currentX]==" ")
{ mymoves=mymoves;}
repaint();
setText();
repaint();
}
}
}

Игра "Пятнашки" с исходниками


[ Сайт ДонНТУ ]      [ На главную ]
Пишите письма на Mixali4@ua.fm
Обновлено 07.01.2005 



Rambler's Top100