Java/Игра змейка
Внешний вид
< Java
Книга Java
- Начало
- Hello World!
- Комментарии
- Переменные
- Стандартные структуры
- Операторы условий
- Полезные сокращения
- Операторы цикла
- Классы
- Исключения
- Коллекции
- Listeners
- GUI
- Паттерны
- Программы
- Компилирование
Если не терпится написать что-нибудь интересное, например игру - вы находитесь на правильной странице! Данная игра не является законченным продуктом, в ней почти нет коментариев, зато она работает и в ней есть несколько ключевых элементов с помощью которых можно написать свою собственную игру. В общем, берем исходники и доделываем/переделываем игру сами!
Дизайн программы
[править]На графическом поле со стенами ползает змейка, которой игрок управляет стрелками, собирая апельсины.
Функциональность
[править]//**//Для начала в объекта actions установим голову змейки в центр поля. Потом создаем 2 массива в которых будут храниться координаты //**//сегментов змейки.
//**// Действия которые выполняются при загрузке объекта
onClipEvent (load) {
//**//Переменная в которой хранится количество сегментов тела змейки
body_count = 0;
//**//Переменная необходимая для паузы в движении змейки
move_timer=getTimer();
//**//Переменная необходимая для паузы при создании бонусов
bonus_timer=getTimer();
//**//Переменная которая указывает создан ли бонус или нет.
bonus_exist = 0;
//**//Устанавливаем голову змейки в центр игрового поля
_root.snake_head._x = 290;
_root.snake_head._y = 250;
//**//Создаем массивы в которых будем хранить координаты тела змейки
var cell_x:Array = new Array();
var cell_y:Array = new Array();
//**// Затем методом дубликации создадим начальный хвост для змейки, и вписываем координаты каждого сегмента в массивы.
//**//Создание хвоста змейки циклом от 1 до 7
for (i=1; i<7; i++) {
duplicateMovieClip(_root.snake_body, 'snake_body'+i, i);
//**//Расстановка сегментов хвоста на поле, снизу головы змейки
_root['snake_body'+i]._x = _root.snake_head._x;
_root['snake_body'+i]._y = _root.snake_head._y+(i*20);
//**//Вписываем в массив новые переменные
cell_x[i+1] = _root['snake_body'+i]._x;
cell_y[i+1] = _root['snake_body'+i]._y;
//**//Записываем в переменной количество сегментов тела
body_count++;
}}
//**//Затем добавим код, который будет управлять движением змейки, он очень прост, при нажатии на кнопку управления - голова змейки //**//меняет свое направление.
//**//Блок управления движением змейки при нажатии кнопки - змейка меняет направление
on (keyPress "<Left>") {
_root.snake_head._rotation = -90;
}
on (keyPress "<Right>") {
_root.snake_head._rotation = 90;
}
on (keyPress "<Up>") {
_root.snake_head._rotation = 0;
}
on (keyPress "<Down>") {
_root.snake_head._rotation = 180;
}
//**//Для движения змейки, появления бонусов, проверки столкновений, испольуем событие которое будет проверяться каждый кадр //**//мувика(onClipEvent (enterFrame)). Напишем код который будет дублировать мувик бонуса и размещать его в случайном месте на сцене, //**//перед дубликацией мувика проверяется тайме и переменная которая указывает создан бонус или нет, это нужно для того чтобы на //**//сцене размещался только 1 бонус.
onClipEvent (enterFrame) {
//**//Создание бонусов.
//**//Проверяем, если таймер меньше и переменная указывает что бонуса не создано - создаем бонус.
if (getTimer()-bonus_timer>500 && !bonus_exist) {
//**//Дублируем клип, присваиваем ему имя
duplicateMovieClip(_root.bonus, 'bonus_real', 1000);
//**//Устанавливаем случайные координаты для дублированного бонуса
_root.bonus_real._x = random(30)*20+10;
_root.bonus_real._y = random(25)*20+10;
//**//Ставим в переменной что бонус создан.
bonus_exist = 1;
}
//**//Движение тела змейки по клеткам с проверкой таймера, для создания задержки и вписывание новых данных в массивы
//**//Движение змейки
//**//Проверяем таймер, для движения с задержкой.
if (getTimer()-move_timer>170) {
//**//Обновление таймера движения.
move_timer = getTimer();
//**//вписываем в массив координаты головы змейки
cell_x[1] = _root.snake_head._x;
cell_y[1] = _root.snake_head._y;
//**//Движение головы змейки в клетку по направлению(_rotation)
_root.snake_head._x += 20*Math.sin(_root.snake_head._rotation*(Math.PI/180));
_root.snake_head._y -= 20*Math.cos(_root.snake_head._rotation*(Math.PI/180));
//**//Запись циклом сегментов тела змейки в массивы
for (i=1; i<body_count+1; i++) {
_root['snake_body'+i]._x = cell_x[i];
_root['snake_body'+i]._y = cell_y[i];
}
//**//Передвижение циклом всех сегментов тела змейки в вышестоящую ячейку массива.
for (i=1; i<body_count+1; i++) {
cell_x[i+1] = _root['snake_body'+i]._x;
cell_y[i+1] = _root['snake_body'+i]._y;
}
//**//Проверку столкновения головы змейки с бонусом, осуществляется встроенной функцией Flash - hitTest(), если столкновение произошло //**//- дублируем для тела змейки новые сегменты и устанавливаем им позицию в хвосте змейки на место последнего сегмента, при //**//последующем движении змейки - они будут следовать за ней, и вписывать свои координаты в массивы.
//**//Проверка столкновения головы змейки с бонусом методом HitTest`а и добавление новых сегментов к телу змейки
if (_root.snake_head.hitTest(_root.bonus_real._x, _root.bonus_real._y)) {
trace('Bonus eat, you grow!');
removeMovieClip(_root.bonus_real);
//**//Устанавливаем переменную, что бонус съеден и обновляем таймер для создания нового бонуса
bonus_exist = 0;
bonus_timer = getTimer();
//**//Добавляем циклом новые сегменты тела к змейке на последний сегмент тела и увеличиваем переменную отвечающую за длину тела.
for (i=0; i<4; i++) {
duplicateMovieClip(_root.snake_body, 'snake_body'+body_count, body_count);
body_count++;
_root['snake_body'+body_count]._x = _root['snake_body'+(body_count-1)]._x;
_root['snake_body'+body_count]._y = _root['snake_body'+(body_count-1)]._y;
cell_x[body_count] = _root['snake_body'+body_count]._x;
cell_y[body_count] = _root['snake_body'+body_count]._y;
}
}
//**//Проверка столкновения головы змейки с телом осуществляется циклом с функцией hitTest(), циклом проверяются все сегменты змейки //**//на столкновение с головой. Если столкновение произошло - функцией fscommand осуществляется закрытие мувика.
//Проверка столкновения головы с сегментами тела HitTest`ом
for (i=0; i<body_count+1; i++) {
//**//Если столкновение произошло - выводим сообщение и закрываем мувик.
if (_root.snake_head.hitTest(_root['snake_body'+i]._x, _root['snake_body'+i]._y, 0)) {
trace('You eat your body. Cannibal !');
fscommand('quit', true);
}
}
}
}
Классы
[править]- SnakeApp - Окно игры. Окно игры содержит игру, слушает клавиатуру и пересылает команды
- SnakeGame - Главный класс игры. В сущности вся игра тут
- Snake - класс змейки. Змейка вынесена в отдельный класс, чтобы в будущем была возможность создания нескольких экземпляров одновременно
Отладка
[править]Так как программа сырая, вам предлагается ее улучшить и доделать. Вот неполный список вещей, которые нужно исправить:
- Нет проверок на самосъедание
- После аварии змейка может продолжить движение (уйти в бесконечность)
- Нет возможности перезапустить игру не закрывая окна
Исходники
[править]- SnakeApp.java - Окно игры
- SnakeGame.java - Главный класс игры
- Snake.java - класс змейки
- sn1.dat - текстовый файл с данными о стенках (поместите его в C:\ или измените путь в классе SnakeGame или в папке NetBeans scr....)