- •Занятие 1. "Постановка задания для разработки игры Змейка. Работа с двумерным массивом"
- •Правила самостоятельной разработки игр данного курса
- •Работа с двумерным массивом в Java
- •Применение двумерного массива при создании игр
- •Постановка задания по созданию игры Змейка
- •Разделение задания для трех уровней сложности
- •План разработки проекта
- •Алгоритм для реализации игры Змейка
- •Перемещать голову змейки в нужном направлении.
- •Удалять хвост змейки. Удаление хвоста равносильно записи нулевого значения в элемент массива, где находилось число, отвечающее за хвост змейки.
- •Итог занятия
- •Занятие 2. "Постановка задания для разработки игры Морской бой"
- •Постановка задания по созданию игры Морской бой
- •Разделение задания для трех уровней сложности
- •Рекомендации для реализации игровых полей игры Морской бой
- •Алгоритм для реализации игры "Морской бой"
- •Генерация кораблей на игровом поле
- •Итог занятия
- •Занятие 3. "Постановка задания для разработки игры Пасьянс-Косынка"
- •Правила игры Пасьянс-Косынка
- •Упаковка файлов изображений внутрьJar-архива
- •Работа со списком в Java
- •Import java.Util.ArrayList;
- •Постановка задания по созданию игры Пасьянс-Косынка
- •Разделение задания для трех уровней сложности
- •Алгоритм перемешивания карт в колоде
- •Создание массива списков значений
- •Итог занятия
- •Заключение
- •Занятие 1. "Разработка игры Змейка. Первый и второй уровень сложности"
- •Рекомендации для изучения программного кода игр
- •Изучаемый программный код необходимо самостоятельно вводить с клавиатуры в среде разработки, глядя на образец в печатном издании.
- •Каждую строчку, каждый фрагмент программного кода стараться максимально разобрать и понять смысл. Не следует бездумно переписывать программный код и запускать!
- •Моменты, которые вызывают особые сложности в понимании, стараться нарисовать на бумаге или пройти пошагово.Например, цикл, который использует формулу с изменяющимися переменными в цикле.
- •Старайтесь больше экспериментировать с записанным программным кодом. Изменяйте значение кого-нибудь параметра и запускайте программу. Смотрите на изменения.
- •После разбора фрагмента программного кода –закрывайте книгу и начинайте пытаться записать свой программный код,который выполняет тоже самое, при этом, не заглядывая в книгу - с чистого листа.
- •Реализация первого уровня сложности игры Змейка Подготовка изображений для игры Змейка
- •Создание проекта и файлов классов игры Змейка
- •Реализация второго уровня сложности игры Змейка(начало)
- •Итог занятия
- •Занятие 2. "Разработка игры Змейка. Второй и третий уровень сложности"
- •Реализация второго уровня сложности игры Змейка(завершение)
- •Реализация третьего уровня сложности игры Змейка
- •Механизм перемещения змейки
- •Итог занятия
- •Занятие 3. "Разработка игры Морской бой. Первый уровень сложности"
- •Создание проекта и файлов классов игры Морской бой
- •Итог занятия
- •Занятие 4. "Разработка игры Морской бой. Второй уровень сложности"
- •Реализация второго уровня сложности игры Морской бой
- •Обозначения состояния ячейки игрового поля
- •Отрисовка игрового поля на основании двумерного массива
- •Ситуация выхода за пределы массива
- •Генерация однопалубных кораблей
- •Генерация четырехпалубного корабля
- •Итог занятия
- •Занятие 5. "Разработка игры Морской бой. Третий уровень сложности"
- •Реализация третьего уровня сложности игры Морской бой
- •Выполнение ходов игроком и компьютером
- •Стратегия ходов компьютера
- •Итог занятия
- •Занятие 6. "Разработка игры Пасьянс-Косынка. Начало первого уровня сложности"
- •Подготовка изображений для игры
- •Создание проекта и файлов классов игры Пасьянса-Косынка
- •Реализация класса kosinka
- •Реализация класса okno
- •Import javax.Swing.*;
- •Import java.Awt.*;
- •Реализация класса pole
- •Реализация класса karta
- •Import javax.Imageio.*;
- •Import java.Awt.*;
- •Import java.Io.*;
- •Итог занятия
- •Занятие 7. "Разработка игры Пасьянс-Косынка. Завершение первого уровня сложности"
- •Реализация класса stopka
- •Import java.Util.ArrayList;
- •Начало реализации класса game
- •Реализация класса pole
- •Завершение реализации класса game для первого уровня сложности
- •Vidacha();
- •Итог занятия
- •Занятие 8. "Разработка игры Пасьянс-Косынка. Второй уровень сложности"
- •Перерисовка всех стопок карт
- •Stopki[I].Get(stopki[I].Size()-2).Draw(gr);
- •Раздача карт в нижние семь стопок
- •Начало реализации третьего уровня сложности
- •Итог занятия
- •Занятие 9. "Разработка игры Пасьянс-Косынка. Третий уровень сложности"
- •// Получаем номер верхней карты
- •Тестирование переноса
- •Vidacha();
- •Заключение
- •Итог занятия
Завершение реализации класса game для первого уровня сложности
Пять классов нашего проекта уже полностью закончены. Все остальные доработки, для всех трех уровней сложности, затронут только класс game. Перейдем в файлgame.java.
В классе gameу нас добавлено несколько методов, которые пока ничего не выполняют. Начнем с конструктора класса:
//Конструктор класса
public game()
{
//Загрузка изображения рубашки карты
try
{
rubashka = ImageIO.read(new File("c:\\karta\\k0.png"));
}
catch (Exception ex) {}
//Создание массива из 13 элементов,
//каждый элемент массива - это список значений (стопка карт)
stopki = new stopka[13];
// Для каждого элемента массива в цикле
//создаем новый объект
for (int i=0;i<13;i++)
{
// Создание нового объекта (нового списка значений)
stopki[i] = new stopka();
}
//Запуск игры - старт игры
start();
}
Конструктор загружает изображение рубашки карты. Далее создается массив из тринадцати элементов. Каждый элемент массива –это объект класса stopka. Другими словами,это список значений с картами –стопка карт. После создания массива в цикле создается объект для каждого элемента массива. И в конце происходит запуск игры –старт новой игры.
Далее займемся методом для загрузки колоды карт:
// Загрузка изображений колоды
private void load()
{
//Цикл делает 52 шага
for (int i=1;i<=52;i++)
{
// В верхнюю левую стопку загружаем карты
stopki[0].add(new karta("c:\\karta\\k"+(i)+".png", rubashka, i));
}
}
Массив stopkiбудет содержать все тринадцать стопок карт. Нумерация в массиве начинается с нуля. Соответственно каждая стопка на игровом поле будет иметь свой номер. Решим, что нумерация стопок будет идти слева направо и сверху вниз(см. рис. 11). Так как читается текст в книге.
Рис. 11
Мы будем обращаться к стопкам карт так, как показано на рисунке(см. рис. 11).Соответственно верхняя левая стопка будет иметь номер: 0.Именно в эту стопку мы будем загружать все карты при старте игры. Загрузка будет производиться в цикле. Для добавления в список используется метод add():
stopki[0].add(new karta("c:\\karta\\k"+(i)+".png", rubashka, i));
При добавлении создается объект на основании классаkarta и конструктору класса kartaпередаются три параметра: путь к файлу карты, изображение рубашки карты и номер карты.
Далее займемся методом для запуска игры:
// Старт игры - Новая игра
public void start()
{
//Очищаем все тринадцать списков
for (int i=0;i<13;i++)
{
// Удаление всех элементов списка
stopki[i].clear();
}
//Производим загрузку
load();
//Признак конца игры - false
endGame = false;
//Признак первой выдачи - true
pervVidacha = true;
}
Метод start()будет вызываться каждый раз при нажатии на кнопку Новая игра. В начале этот метод очищает все тринадцать списков,удаляя из них элементы. Далее производится загрузка колоды карт в верхнюю левую стопку. Признак окончания игры устанавливается –ложь.Признак первой выдачи из верхней левой колоды устанавливается –истина, потому что после старта игры произойдет самая первая выдача карт.
Для первого уровня сложности необходимо загрузить все карты в верхнюю левую стопку с номером 0 и затем производить выдачу карт, перемещая их во вторую слева верхнюю стопку с номером 1. Пока достаточно выполнять отрисовку только этих стопок карт. Так как все карты колоды будут пока находиться в этих двух стопках. Добавим код в метод drawKoloda():
// Метод отрисовки всех стопок карт
public void drawKoloda(Graphics gr)
{
//ВЕРХНЯЯ ЛЕВАЯ СТОПКА
// Если в стопке есть карты
if (stopki[0].size()>0)
{
// Получаем и рисуем самую верхнюю карту
stopki[0].get(stopki[0].size()-1).draw(gr);
}
//ВТОРАЯ СЛЕВА ВЕРХНЯЯ СТОПКА
// Если в стопке более одной карты
if (stopki[1].size()>1)
{
// Получаем и рисуем вторую сверху карту
stopki[1].get(stopki[1].size()-2).draw(gr);
// Получаем и рисуем самую верхнюю карту
stopki[1].get(stopki[1].size()-1).draw(gr);
}
else if (stopki[1].size()==1) // если в стопке одна карта
{
// Получаем и рисуем самую верхнюю карту
stopki[1].get(stopki[1].size()-1).draw(gr);
}
}
Метод drawKoloda() будет вызываться в методе paintComponent()класса poleпосле рисования фона и тринадцати белых прямоугольных рамок.
Сначала рисуем верхнюю левую стопку с номером 0:
// ВЕРХНЯЯ ЛЕВАЯ СТОПКА
// Если в стопке есть карты
if (stopki[0].size()>0)
{
// Получаем и рисуем самую верхнюю карту
stopki[0].get(stopki[0].size()-1).draw(gr);
}
Проверяем, есть ли в ней карты. Если есть, то рисуем самую верхнюю карту.
Самая верхняя карта имеет номер: size()-1, потому что нумерация элементов списка идет с нуля. Метод get()получает карту по номеру.Метод draw() находится в классе karta.
Далее рисуем вторую слева верхнюю стопку с номером 1:
// ВТОРАЯ СЛЕВА ВЕРХНЯЯ СТОПКА
// Если в стопке более одной карты
if (stopki[1].size()>1)
{
// Получаем и рисуем вторую сверху карту
stopki[1].get(stopki[1].size()-2).draw(gr);
// Получаем и рисуем самую верхнюю карту
stopki[1].get(stopki[1].size()-1).draw(gr);
}
else if (stopki[1].size()==1) // если в стопке одна карта
{
// Получаем и рисуем самую верхнюю карту
stopki[1].get(stopki[1].size()-1).draw(gr);
}
Со второй стопкой ситуация несколько отличается. Если в стопке всего одна карта, то рисуем самую верхнюю. Если более одной карты, то рисуем сначала вторую сверху, а потом самую верхнюю. Самая верхняя карта будет всегда рисоваться поверх второй сверху, потому сначала выводится вторая карта сверху. Две карты стопки с номером 1пользователь будет видеть,когда мышью захватит самую верхнюю карту и переместит ее в сторону.
Следующий метод,который заслуживает внимание –метод getNomKolodaPress(). Метод будет определять по координатам курсора мыши стопку, над которой находится курсор. Метод должен возвращать номер стопки или значение минус единица, если курсор не находится над стопкой карт:
// Определение стопки на которую нажали мышью
private int getNomKolodaPress(int mX, int mY)
{
// Если стопка не выбрана
int nom=-1;
// Если курсор находится в зоне верхних стопок
if ((mY>=15)&& (mY<=(15+97)))
{
if ((mX>=30) && (mX<=(30+72))) nom = 0;
if ((mX>=140) && (mX<=(140+72))) nom = 1;
if ((mX>=360) && (mX<=(360+72))) nom = 2;
if ((mX>=470) && (mX<=(470+72))) nom = 3;
if ((mX>=580) && (mX<=(580+72))) nom = 4;
if ((mX>=690) && (mX<=(690+72))) nom = 5;
}
// Если курсор находится в зоне нижних стопок
else if ((mY>=130) && (mY<=(700)))
{
if ((mX>=30) && (mX<=110*7))
{
if (((mX-30)%110)<=72)
{
nom = (mX-30)/110;
nom += 6;
}
}
}
// Возврат результата
return nom;
}
При определении номера стопки, над которой расположен курсор необходимо анализировать координаты курсора мыши. Ширина каждой карты –72пикселя, высота каждой карты–97 пикселей. Верхний ряд стопок находится с отступом по Y –15 пикселей.Нижний ряд стопок находится с отступом поY –130 пикселей. Отступ между стопками карт,расположенных рядом в одном ряду –110пикселей. Самая левая стопка находится с отступом по X- 30пикселей. Для верхнего ряда необходимо точное вычисление по размерам карты. Для нижнего ряда нужно учитывать,что карты раскладываются сверху вниз–одна ниже другой. Поэтому нижнюю границу стопки нижнего ряда необходимо брать –700пикселей(до нижней части окна).
Выдачу карты мы будем производить при отпускании левой клавиши мыши, если в этот момент курсор мыши находится над верхней левой стопкой карт с номером 0:
// При отпускании левой кнопки мыши
public void mouseReleased(int mX, int mY)
{
//Определяем номер стопки
int nom = getNomKolodaPress(mX, mY);
// Если верхняя левая стопка
if (nom==0)
{
// Делаем выдачу карты
