Рассмотрим подробно и пошагово механизм перемещения змейки.Именно этот механизм будет выполняться при помощи метода perem(). Для этого нам придется проделать один шаг движения змейки. Пусть змейка перемещается влево:
Шаг 1.Исходное положение змейки (см. рис. 13)
Шаг 2.В новое положение головы помещается значение минус два: -2 (см. рис. 14)
Рис. 13
Рис. 14
Шаг 3.Пробегаем весь массив и все значения,которые больше нуля увеличиваем на единицу(см. рис. 15)
Рис. 15
Шаг 4.Вместо значения минус два: -2, помещаем единицу(см. рис. 16)
Рис. 16
Шаг 5
· Если при перемещении змейка съела объект, то больше ничего не делаем. Длина змейки уже увеличилась на единицу (см. рис. 16)
· Если при перемещении объекта не было, то число в массиве, которое больше длины змейки на единицу –заменяем нулевым(см. рис. 17)
Рис. 17
Если этот алгоритм описать более кратко, то можно сказать, что голову змейки мы перемещаем по направлению движения, а хвост удаляем. В случае поедания объекта –хвост оставляем, и длина змейки увеличивается. При таком подходе змейка будет двигаться по нужному пути автоматически!
В класс gameдобавим метод, который выполняет описанный выше механизм:
// Перемещение змейки
public void perem()
{
// Перемещаем голову змейки
// и получаем результат перемещения
int flag = peremGolova();
// Если змейка врезалась в себя
// то признак окончания игры устанавливаем в истину
if (flag==3) endg=true;
// Два вложенных цикла, которые перебирают
// все элементы двухмерного массива
for (int i = 0; i < 30; i++)
{
for (int j = 0; j < 30; j++)
{
// Если значение больше нуля, то увеличиваем на 1
if (mas[i][j] > 0) mas[i][j]++;
// Если значение минус два,то меняем его на 1
else if (mas[i][j] == -2) mas[i][j]=1;
// Если не было поедания объекта
if (flag!=1)
{
// Если это хвост, то записываем в него нулевое значение
if (mas[i][j] == (dlina+1)) mas[i][j]=0;
}
}
}
// Если съеден объект
if (flag==1)
{
// Увеличиваем длину на единицу
dlina++;
// Генерируем новый объект для поедания
make_new();
// Увеличиваем количество очков на 10
kol += 10;
}
//Изменяем направление движения
povorot();
}
Теперь класс game полностью закончен!И закончена реализация третьего уровня сложности! Запустим и посмотрим игру в действии (см. рис. 18):
Рис. 18
Ниже представлен полный программный код файла game.javaдля третьего уровня сложности:
public class game
{
// Двухмерный массив для хранения игрового поля
public int[][] mas;
// Текущее направление движения
public int napr;
// Координаты головы змейки
private int gX, gY;
// Количество очков
public int kol;
// Новое направление движения
public int new_napr;
// Длина змейки
private int dlina;
// Признак окончания игры
public boolean endg;
// Изменение направления движения змейки (поворот)
private void povorot()
{
if (Math.abs((new_napr-napr))!=2)
{
napr=new_napr;
}
}
// Конструктор класса
public game()
{
//Создаем новый массив 30x30
mas = new int[30][30];
}
// Генерация нового объекта в случайном месте
private void make_new()
{
//Глухой (бесконечный цикл)
while(true)
{
// Получаем случайные значения x,y от 0 до 29
int x = (int)(Math.random()*30);
int y = (int)(Math.random()*30);
// Если в этом месте массива нулевое значение
// то помещаем туда объект для поедания змейкой
// и прерываем цикл
if (mas[y][x]==0)
{
mas[y][x] = -1;
break;
}
}
}
// Запуск игры (Старт)
public void start()
{
//Заполняем весь массив нулями
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 30; j++) {
mas[i][j] = 0;
}
}
//Начальное направление - влево
napr = 0;
//Количество очков
kol = 0;
//Создаем начальную змейку с длиной три ячейки
mas[14][14] = 1;
mas[14][15] = 2;
mas[14][16] = 3;
dlina = 3;
//Записываем в переменные координаты головы змейки
gX = gY = 14;
//Признак окончания игры
endg=false;
//Формируем первый объект для поедания змейкой
make_new();
}
// Перемещение головы змейки
public int peremGolova()
{
// Если текущее направление влево
if (napr == 0)
{
if ((gX - 1) >= 0)
gX--;
else
gX = 29;
}
// Если текущее направление вверх
else if (napr == 1)
{
if ((gY - 1) >= 0)
gY--;
else
gY = 29;
}
// Если текущее направление вправо
else if (napr == 2)
{
if ((gX + 1) <= 29)
gX++;
else
gX = 0;
}
// Если текущее направление вниз
else if (napr == 3)
{
if ((gY + 1) <= 29)
gY++;
else
gY = 0;
}
//Результат
int rez=0;
// Если съеден объект
if (mas[gY][gX]==-1) rez=1;
// Если перемещение в пустую ячейку
else if (mas[gY][gX]==0) rez=2;
// Если попадание в туловище змейки
else if (mas[gY][gX]>0) rez=3;
// В место перемещения головы
//установим значение - минус два
mas[gY][gX] = -2;
//Возвращаем результат
return rez;
}
// Перемещение змейки
public void perem()
{
// Перемещаем голову змейки
// и получаем результат перемещения
int flag = peremGolova();
// Если змейка врезалась в себя
// то признак окончания игры устанавливаем вистину
if (flag==3) endg=true;
// Два вложенных цикла, которые перебирают
// все элементы двухмерного массива
for (int i = 0; i < 30; i++)
{
for (int j = 0; j < 30; j++)
{
// Если значение больше нуля, то увеличиваем на 1
if (mas[i][j] > 0) mas[i][j]++;
// Если значение минус два,то меняем его на 1
else if (mas[i][j] == -2) mas[i][j]=1;
// Если не было поедания объекта
if (flag!=1)
{
// Если это хвост, то записываем в него нулевое значение
if (mas[i][j] == (dlina+1)) mas[i][j]=0;
}
}
}
// Если съеден объект
if (flag==1)
{
// Увеличиваем длину на единицу
dlina++;
// Генерируем новый объект для поедания
make_new();
// Увеличиваем количество очков на 10
kol += 10;
}
//Изменяем направление движения
povorot();
}
}
Окончательный вариант игры осталось преобразовать в JAR-архив.
В классе myPanel при загрузке изображений необходимо изменить путь к изображениям. После создания JAR-архива изображения будут расположены в той же папке, что иJAR-архив.Поэтому необходимо прописать путь к текущей папке. Получится следующее:
// Попытка загрузки всех изображений для игры
try
{
fon = ImageIO.read(new File("./fon.png"));
telo = ImageIO.read(new File("./telo.png"));
golova = ImageIO.read(new File("./golova.png"));
ob = ImageIO.read(new File("./ob.png"));
endg = ImageIO.read(new File("./endg.png"));
}
catch (Exception ex) {}
"./" точка и наклонная черта означают путь к текущей папке.
После этого необходимо сохранить проект и обязательно запустить игру!
В процессе запуска вы увидите, что изображения не отобразились–это нормально, ведь в текущей папке изображений нет.
Нажимаем на заголовок проекта в общем списке проектов и нажимаем правую клавишу мыши. В открывшемся окне выбираем Export(см. рис. 19)
Рис. 19
В следующем окне Java, Runnable JAR file, Next (см. рис. 20):
Рис. 20
В последнем окне в самой верхней строке необходимо выбрать:zmeika-zmeika,строкой ниже путь к JAR-архиву и имя: zmeika.jar. Переключатель устанавливаем в среднее положение и нажимаем Finish (см. рис.21).
Рис. 21
Последним шагом создаем папку с именем zmeikaи помещаем в нее все пять изображений и сам JAR-архив (см. рис.22).
Рис. 22
Папку zmeikac пятью изображениями иJAR-архивом можно считать конечным продуктом для передачи пользователю.
Внимание!!!При наличии русских букв в пути к JAR-архиву могут возникнуть проблемы при запуске JAR-архива! Самым простым выходом является перенос JAR-архива в папку, путь к которой не содержит русские буквы.