OrionXL

Реализация игры пятнашки на Flash

Роман Иванов @ 16:43 03.04.2011

В данной статье Вы узнаете как написать или создать игру пятнашки online с помощью action script в формате flash для публикации в сети интернет. Для успешного знакомства с этим материалом Вам необходимы первичные представления о языке программирования action script (очень похож на C#) , а так же опыт работы с Adobe Flash или другими инструментальными средствами.

Наконец то Мы приступил к написанию серии статей о разработке и создании игр, после непродолжительного перерыва. И так приступим...

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

Этап первый. Создадим проект и в нем укажем класс MainApp.as, который будет у нас основным. Для каждого класса в action script создается соответствующий файл обернутый в package:

Package
{
// импорт различных библиотек
Import flash.events.event;
import flash.events.Event;
import flash.display.Sprite;
import flash.display.Graphics;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import cell;
        Public class MainApp extends MovieClips // наш класс наследующий основные свойства от класса MovieClips (Кинокадров)
        {
               // тело нашего класса
        }
}

И еще создадим второй класс и назовем его cell.as. В этом классе опишем свойства игровой кости (ячейки) всего их у нас 15 :-)

Этап второй. Создадим два кадра. Первый кадр будет у нас игровым, на котором расположено игровое поле (доска для пятнашек), кнопка «новая игра» и текстовое поле для отображения счетчика ходов. Для их создания перетащите, расположите (и нарисуйте) из панели инструментов текстовое поле, прямоугольник...

 Рис. 1 Первый кадр с основным игровым полем

Рис. 1 Первый кадр с основным игровым полем

На втором кадре все тоже самое, только добавим надпись «Вы Выиграли». Можно еще создать. Необходимости создания третьего кадра с надписью «Вы проиграли» нет необходимости.

Кадр информирующий игрока об успешном решении головоломки

Рис.2 Кадр информирующий игрока об успешном решении головоломки

Этап третий. Рассмотрим алгоритм создания игры на action script. И так алгоритм:

1. Мы должны нарисовать игровое поле и заполнить его пятнашками. Для этого создадим два массива размером в 16 элементов. Один эталонный и второй игровой (текущий). В эталонном будут храниться элементы соответствующие правильному (по порядку) расположению фишек.

2. Затем Мы должны перемешать игровой массив. Учтите, что простое перемешивание с помощью рандомной функции (Randomize) в данном случае на подойдет, т.к. можно создать такую комбинацию, что ее решение будет невозможно. Почему? Если Вы хотите узнать ответ на этот вопрос, то смотрите предыдущую статью. Перемешивание будет заключаться в произвольном перемещении пятнашек из начального (правильного положения) в конечное игровое.

3. Мы должны отследить нажатие левой клавиши мыши, определить игровую фишку и переместить ее на место пустой клетки в зависимости от игрового положения.

Алгоритм перемещения костяшки

Рис. 3 Алгоритм перемещения костяшки

4. После перемещения нам необходимо проверить на окончание игры, т.е. победы. Для этого необходимо сравнить эталонный массив с текущим и при совпадении всех его элементов вернуть результат равный истине.

Этап четвертый. Написание исходного кода.

Объявим в классе MainApp три глобальных элемента:

private var field:Array=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];  // игровое поле сохраняющее текущую комбинацию
private var field_mask:Array=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]; // эталонное поле, можно типа const (маска)
private var steps:Number=0; // счетчик числа шагов

Конструктор нашего класса:

public function MainApp()
{
       shake_board(); // перемешаем игровые фишки
       Create(); // создадим визуальные элементы (графическое представление костяшек)
       this.addEventListener(MouseEvent.CLICK,addetClikHandler); // обработчик нажатия кнопки мышки
       this.gotoAndStop(1); // установим 1-й кадр
}

Функция создания графического представления костяшек (пятнашек, фишек). В этой функции нам необходимо создать пятнадцать костяшек + одно пустое поле. Присвоим каждой название как конкатенация строк: “cell_”+индекс ячейки –> (cell_1,…,cell_16)

private function Create()
{
       var tmp:cell;
       var x0,y0,dx0,dy0:Number;
       dx0=board.width/4.0;
       dy0=board.height/4.0;
       for(y0=0;y0<4;y0++)
       {
              for(x0=0;x0<4;x0++)
              {
                     tmp = new cell();
                     tmp.x=x0*dx0+2;
                     tmp.y=y0*dy0+2;
                     tmp.name="cell_"+field_mask[y0*4+x0];
                     tmp.gotoAndStop(field[y0*4+x0]);
                     board.addChild(tmp);
              }
       }
}

Функция обработки нажатия кнопки мышки:

// По событию нажатия кнопки
private function addetClikHandler(event:MouseEvent):void
{
       var str:String = event.target.name;
       update_board_elements();  // переместим фишки если необходимо
       if(str.substr(0,5)=="cell_") // если игрок нажал на одну из 15 игровых фишек, увеличим число ходов
       steps++;
       this.txt_step.text="Steps: "+steps;
       if(event.target.name=="new_game") // если игрок нажал на кнопку «новая игра»
       {
              this.gotoAndStop(1);
              reinit();
       }
}

Функция проверки на успешное решение головоломки. Простое сравнение двух массивов:

private function check_win():Boolean
{
       for(var i:Number=0;i<15;i++)
              if(field[i]!=field_mask[i])
                     return false;
       return true;
}

Функция обработки игрового нажатия мышки и перемещения пятнашки на пустое пространство. Заметьте, что эта функция не была оптимизирована для более простого и наглядного ее понимания :-)

При успешной проверки на перемещение пятнашки, мы меняем элементы игрового массива fields местами. Пустому полю у нас соответствует число 16, следовательно, если соседняя ячейка содержит это число, то эти костяшки можно поменять местами. На рис. 3 показана идея алгоритма.

// переместим пятнашки (exchange fithting)
private function update_board_elements():void
{
       var x0,y0,dx0,dy0:Number;
       // преобразуем координаты мыши к координатам сетки
       dx0=board.width/4;
       dy0=board.height/4;
       x0=Math.floor((stage.mouseX-board.x)/dx0);
       y0=Math.floor((stage.mouseY-board.y)/dy0);
 
       // теперь проверим есть ли рядом пустое поле и сдвинем его туда
       // если нужно сдвинуть вправо?
       if(x0<3) 			
       { 				
              if(field[x0+1+y0*4]==16) // ячейка пустая? 				
              { 					
                     field[x0+1+y0*4]=field[x0+y0*4]; 					
                     field[x0+y0*4]=16; 					
                     refresh_display_elements(1,x0,y0); // теперь перерисуем эти две фишки на игровом поле 				
              } 			
       } 			
       // в лево? 			
       if(x0>0)
       {
              if(field[x0-1+y0*4]==16)
              {
                     field[x0-1+y0*4]=field[x0+y0*4];
                     field[x0+y0*4]=16;
                     refresh_display_elements(0,x0,y0);
               }
       }
       // может вверх?
       if(y0>0)
       {
              if(field[x0+(y0-1)*4]==16)
              {
                     field[x0+(y0-1)*4]=field[x0+y0*4];
                     field[x0+y0*4]=16;
                     refresh_display_elements(2,x0,y0);
              }
       }
       // или все таки вниз?
       if(y0<3)
       {
              if(field[x0+(y0+1)*4]==16)
              {
                     field[x0+(y0+1)*4]=field[x0+y0*4];
                     field[x0+y0*4]=16;
                     refresh_display_elements(3,x0,y0);
              }
       }
       if(check_win()==true) // проверим на окончание игры (решение головоломки)
       {
              this.gotoAndStop(2); // покажем кадр завершения игры
       }
}

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

private function refresh_display_elements(type,x0,y0:Number):void
{
        var cell_1:cell;
        var cell_0:cell;
        var pos_1,pos_0:Number;
        switch(type) // тип перемещения
        {
             case 0:
                pos_1=x0+y0*4+1;
                pos_0=x0-1+y0*4+1;
                cell_1=cell(board.getChildByName("cell_"+pos_1));
                cell_0=cell(board.getChildByName("cell_"+pos_0));
                cell_1.gotoAndStop(field[pos_1-1]);
                cell_0.gotoAndStop(field[pos_0-1]);
                break;
             case 1:
                pos_1=x0+y0*4+1;
                pos_0=x0+1+y0*4+1;
                cell_1=cell(board.getChildByName("cell_"+pos_1));
                cell_0=cell(board.getChildByName("cell_"+pos_0));
                cell_1.gotoAndStop(field[pos_1-1]);
                cell_0.gotoAndStop(field[pos_0-1]);
                break;
             case 2:
                pos_1=x0+y0*4+1;
                pos_0=x0+(y0-1)*4+1;
                cell_1=cell(board.getChildByName("cell_"+pos_1));
                cell_0=cell(board.getChildByName("cell_"+pos_0));
                cell_1.gotoAndStop(field[pos_1-1]);
                cell_0.gotoAndStop(field[pos_0-1]);
                break;
             case 3:
                pos_1=x0+y0*4+1;
                pos_0=x0+(y0+1)*4+1;
                cell_1=cell(board.getChildByName("cell_"+pos_1));
                cell_0=cell(board.getChildByName("cell_"+pos_0));
                cell_1.gotoAndStop(field[pos_1-1]);
                cell_0.gotoAndStop(field[pos_0-1]);
                break;
            }
}

Функция для перемешивания пятнашек. Для перемешивания воспользуемся перестановкой из начального положения в произволное и используем двести ходов. Она довльно проста и имитирует работу игрока, пытающегося перемешать клетки самостоятельно.

	private function shake_board():void
		{
			var rnd:Number;
			var x0,y0:Number;
			x0=3;
			y0=3;
			// небольшое приготовление
			field[x0+y0*4]=field[x0+(y0-1)*4];
			field[x0+(y0-1)*4]=16;
			y0--;
			field[x0+y0*4]=field[x0-1+y0*4];
			field[x0-1+y0*4]=16;
			x0--;
			for(var i:Number=0;i<200;i++)
			{
				rnd=Math.floor((Math.random()*11)/3); // с помощью случайной функции выберем направление перемещения на i-м шаге
				switch(rnd)
				{
					case 0:
					if(x0>0)
					{
						field[x0+y0*4]=field[x0-1+y0*4];
						field[x0-1+y0*4]=16;
						x0--;
					}
					break;
					case 1:
					if(x0<3)
					{
						field[x0+y0*4]=field[x0+1+y0*4];
						field[x0+1+y0*4]=16;
						x0++;
					}
					break;
					case 2:
					if(y0>0)
					{
						field[x0+y0*4]=field[x0+(y0-1)*4];
						field[x0+(y0-1)*4]=16;
						y0--;
					}
					break;
					case 3:
					if(y0<3)
					{
						field[x0+y0*4]=field[x0+(y0+1)*4];
						field[x0+(y0+1)*4]=16;
						y0++;
					}
					break;
				}
			}
		}

И наконец класс для описания клетки (костяшки, пятнашки):

package
{
	import flash.display.MovieClip;
	import flash.events.MouseEvent;	
 
	public class cell extends MovieClip
	{
		public function cell()
		{
			this.gotoAndStop(1);
		}
		public function eventOverHandler(event:MouseEvent):void
		{
			this.gotoAndStop(4);
		}
		public function eventOutHandler(event:MouseEvent):void
		{
			this.gotoAndStop(1);
		}
	}
}

В итоге у нас должна получиться подобная картинка:

Рис.4 Итоговая картинка для игры пятнашки

Рис.4 Итоговая картинка для игры пятнашки

Комментариев нет

Комментариев нет.

RSS-лента комментариев к этой записи.

Извините, обсуждение на данный момент закрыто.

алгоритмы, методы, программы - OrionXL