Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Java Модуль 4.docx
Скачиваний:
14
Добавлен:
01.07.2025
Размер:
20.72 Mб
Скачать

Начало реализации третьего уровня сложности

Продолжим создание нашей игры. Еще предстоит многое сделать.

Нам осталось запрограммировать перенос карт или группы карт мышью.

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

//Изображение рубашки карты

public Image rubashka;

// Массив стопок карт

private stopka[] stopki;

// Признак первой выдачи карт из верхней

// левой стопки

private boolean pervVidacha;

// Признак окончания игры

public boolean endGame;

// Номер стопки захваченной пользователем

private int nomStopki;

// Номер карты в стопке захваченной пользователем

private int nomKarti;

// Смещения координат курсора мыши

//относительно координат карты

private int dx ,dy;

// Координаты карты до начала переноса мышью

private int oldX ,oldY;

// Таймер для эффекта окончания игры

private Timer tmEndGame;

Переменная nomStopki –это номер стопки, захваченной мышью. Это стопка, карту или группу карт которой,пользователь захватил мышью и начинает перемещать по игровому полю. ПеременнаяnomKarti–это номер карты в захваченной стопке. Карта, на которую пользователь навел курсор мыши и нажал левую клавишу для захвата. Переменныеdx, dy –это смещения в пикселях от верхнего левого угла карты до курсора мыши. Эти смещения необходимы при переносе захваченных карт. Переменные oldX, oldY –это координаты карты до начала переноса.Эти координаты мы будем запоминать в отдельных переменных. Если перенос будет неверным, то будем возвращать карты назад.Переменная tmEndGame –это таймер, который будет выполнять эффект при окончании игры.Когда игра закончится, переменная endGame будет иметь значение true. В этот момент таймер будет запускаться.Найдем конструктор класса game. Перед вызовом метода start() (см. рис. 5),

Рис. 5

добавим программный код для таймера:

// Таймер для эффекта при окончании игры

//будет запускаться при успешном завершении игры

//скорость работы - 10 раз в секунду.

tmEndGame = new Timer(100,new ActionListener() {

@Override

public void actionPerformed(ActionEvent arg0) {

// Перебираем четыре домашние стопки

for (int i=2;i<=5;i++)

{

// Получаем самую нижнюю карту

karta getKarta = stopki[i].get(0);

// Нижнюю карту добавляем наверх

stopki[i].add(getKarta);

// Удаляем нижнюю карту

stopki[i].remove(0);

}

}

});

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

Далее добавим метод для проверки факта окончания игры:

// Проверка окончания игры

private void testEndGame()

{

//Проверяем, что во всех четырех

//домашних стопках по 13 карт

if ((stopki[2].size()==13) &&

(stopki[3].size()==13) &&

(stopki[4].size()==13) &&

(stopki[5].size()==13))

{

// Признак окончания игры

endGame = true;

// Запускаем таймер

tmEndGame.start();

}

}

Метод testEndGame()будет вызываться после каждого добавления карты в домашнюю стопку. Как только во всех четырех домашних стопках будет по 13карт это значит, пасьянс разложен. Именно в этот момент будет запускаться таймер для эффекта окончания игры. И признак конца игры будет изменяться на true.

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

// Автоматическое открытие верхней карт

// в нижних стопках

private void openKarta()

{

//Перебираем все нижние стопки карт

for (int i=6;i<=12;i++)

{

// Если в стопке есть карты

if (stopki[i].size()>0)

{

// Номер последней карты в стопке

int nomPoseld = stopki[i].size()-1;

// Получаем последнюю карту

karta getKarta = stopki[i].get(nomPoseld);

// Если карты отображается рубашкой,

// то открываем ее

if (getKarta.tipRubashka==true) getKarta.tipRubashka = false;

}

}

}

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

Теперь перейдем в методstart() и в самом конце метода добавим:

//Номер выбранной карты

nomKarti =-1;

//Номер выбранной стопки

nomStopki =-1;

При старте игры на игровом поле не будет выбранной стопки и карты. Если стопка и карта не выбраны, то будем записывать в эти переменные значениеминус единица.Это будет означать, что на игровом поле нет переносимых мышью карт.

На третьем уровне сложности необходимо реализовать перерисовку карт в режиме переноса карт.Поэтому выполним доработку метода drawKoloda().

У каждой карты имеется свойство vibrana–это признак захваченной мышью карты. Если значение этого свойства true–это значит, что пользователь подвел курсор к карте, нажал левую клавишу мыши и удерживает левую клавишу, чтобы выполнить перенос. В этот момент в переменной nomStopki

будет находиться номер выбранной стопки. Перейдем в самый конец метода drawKoloda() и найдем циклы, которые перерисовывают нижние семь стопок (см. рис.6).

Рис. 6

Модернизируем эти циклы так:

//НИЖНИЕ СЕМЬ СТОПОК

for (int i=6;i<13;i++)

{

//Если в стопке есть карты

if (stopki[i].size()>0)

{

// Перебираем все карты из стопки

for (int j=0;j<stopki[i].size();j++)

{

// Если находим выбранную карту,

// то прерываем цикл

if (stopki[i].get(j).vibrana==true) break;

// Рисуем карты

stopki[i].get(j).draw(gr);

}

}

}

Внутри циклов добавилась новая строка:

// Если находим выбранную карту,

// то прерываем цикл

if (stopki[i].get(j).vibrana==true) break;

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

В самом низу методаdrawKoloda() добавим последний фрагмент кода, который перерисовывает захваченные мышью карты:

// ПЕРЕНОСИМЫЕ МЫШЬЮ КАРТЫ

// Если имеется выбранная стопка

if (nomStopki!=-1)

{

// Перебираем карты от выбранной и до конца стопки

for (int i=nomKarti;i<stopki[nomStopki].size();i++)

{

// Рисуем карты

stopki[nomStopki].get(i).draw(gr);

}

}

nomKarti –это номер карты в выбранной стопке, nomStopki–это номер выбранной стопки. Если на текущий момент пользователь ничего не переносит в режиме захвата мышью, то значения этих переменных раны минус единице. Теперь метод 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);

}

//ЧЕТЫРЕ ДОМАШНИЕ СТОПКИ

for (int i=2;i<=5;i++)

{

//Если в стопке более одной карты

if (stopki[i].size()>1)

{

// Получаем и рисуем вторую сверху карту

stopki[i].get(stopki[i].size()-2).draw(gr);

// Получаем и рисуем самую верхнюю карту

stopki[i].get(stopki[i].size()-1).draw(gr);

}

else if (stopki[i].size()==1) // если в стопке одна карта

{

// Получаем и рисуем самую верхнюю карту

stopki[i].get(stopki[i].size()-1).draw(gr);

}

}

//НИЖНИЕ СЕМЬ СТОПОК

for (int i=6;i<13;i++)

{

//Если в стопке есть карты

if (stopki[i].size()>0)

{

// Перебираем все карты из стопки

for (int j=0;j<stopki[i].size();j++)

{

// Если находим выбранную карту,

// то прерываем цикл

if (stopki[i].get(j).vibrana==true) break;

// Рисуем карты

stopki[i].get(j).draw(gr);

}

}

}

// ПЕРЕНОСИМЫЕ МЫШЬЮ КАРТЫ

// Если имеется выбранная стопка

if (nomStopki!=-1)

{

// Перебираем карты от выбранной и до конца стопки

for (int i=nomKarti;i<stopki[nomStopki].size();i++)

{

// Рисуем карты

stopki[nomStopki].get(i).draw(gr);

}

}

}

Найдем метод mouseDragged()–это метод, который вызывается при захвате мышью. Курсор мыши перемещается с зажатой левой клавишей мыши. В этом методе нам необходимо изменять координаты выбранной карты в соответствии с курсором мыши. Если переносится сразу группа карт, то все карты, которые ниже выбранной карты должны иметь смещения вниз(координату по Y)по 20 пикселей, а координата по Xдля всех карт будет одинаковой. Запишем код в метод mouseDragged():

// При захвате карты мышью

public void mouseDragged(int mX, int mY)

{

// Если стопка выбрана

if (nomStopki>=0)

{

// Получаем выбранную карту

karta getKarta = stopki[nomStopki].get(nomKarti);

// Изменяем координаты карты по курсору мыши

getKarta.x = mX-dx;

getKarta.y = mY-dy;

// Ограничение области переноса карт

if (getKarta.x<0) getKarta.x = 0;

if (getKarta.x>720) getKarta.x = 720;

if (getKarta.y<0) getKarta.y = 0;

if (getKarta.y>650) getKarta.y = 650;

// Все остальные карты в переносимой группе карт

// размещаем со сдвигом вниз на 20пикселей

int y=20;

for (int i=nomKarti+1;i<stopki[nomStopki].size();i++)

{

stopki[nomStopki].get(i).x = getKarta.x;

stopki[nomStopki].get(i).y = getKarta.y + y;

y += 20;

}

}

}

В методе mouseDragged() имеются ограничения в области перемещения карт. ПоXот 0до 720, по Yот 0до 650.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]