Создание игр для мобильных телефонов
Шрифт:
Если вы вспомните дизайн игры Space Out (рис. 18.1), то автомобиль игрока располагается у нижней границы экрана и может перемещаться по горизонтали влево или вправо. Код обработки нажатий клавиш устанавливает скорость автомобиля по оси X, таким образом, автомобиль перемещается в ответ на нажатие клавиши. Важно отметить, что скорость в направлении влево меньше скорости направления вправо. Эта разница объясняется тем, что автомобиль направлен вправо, следовательно, при движении влево он движется назад. В реальности автомобиль движется назад медленнее, чем вперед.
В копилку Игрока
Кроме того, что в игру Space Out добавлена доля реализма, такое различие скоростей несколько усложняет игру. Так, при движении влево сложнее скрыться от ракет.
Код обработки ввода реагирует на нажатие клавиши Огонь тоновым сигналом и вызовом
Основная работа метода update – это обновление спрайтов. Приведенный ниже код обновляет спрайты пришельцев и взрывов:
for (int i = 0; i < 3; i++) {
if (blobboSprite[i].isVisible) {
blobboSprite[i].update;
blobboSprite[i].nextFrame;
}
if (jellySprite[i].isVisible) { //Обновляются только видимые спрайты
jellySprite[i].update;
jellySprite[i].nextFrame;
}
if (timmySprite[i].isVisible) {
timmySprite[i].update;
timmySprite[i].nextFrame;
}
if (explosionSprite[i].isVisible) {
if (explosionSprite[i].getFrame < 3) //Этот код создает анимацию взрыва, после чего спрайт взрыва исчезает
explosionSprite[i].nextFrame;
else
explosionSprite[i].setVisible(false);
}
}Этот код достаточно прост, здесь обновляются и перемещаются спрайты пришельцев и взрывов. Важно понять, что обновляются только видимые спрайты. Возможно, также важным является и то, что спрайты взрыва скрываются после того, как все фреймы показаны.
Совет Разработчику
Чтобы сделать игру более эффективной и не создавать и не удалять объекты динамически, все спрайты создаются в начале игры, а затем скрываются и отображаются, чтобы создать эффект разрушения. В любой момент в игре «существуют» только видимые спрайты.
Следующий фрагмент метода update достаточно велик, поскольку в нем реализуется большая часть игровой логики.
Код, о котором я говорю, – это код обновления ракет. Он очень важен, поскольку ход игры зависит от того, с каким спрайтом столкнется ракета – со спрайтом игрока или пришельца. Ниже приведен код, работающий со спрайтами ракет:
for (int i = 0; i < 10; i++) {
if (missileSprite[i].isVisible) {
// ракета игрока?
if (missileSprite[i].getFrame == 0) { //Индекс фрейма спрайта ракеты используется для определения типа ракеты
for (int j = 0; j < 3; j++) {
// ракета попала в пришельца Блоббо?
if (blobboSprite[j].isVisible)
if (missileSprite[i].collidesWith(blobboSprite[j], false)) {
// Воспроизвести звук разрушения
try {
Manager.playTone(ToneControl.C4 – 6, 100, 100);
}
catch (Exception e) {
}
// создать взрыв
addExplosion(blobboSprite[j]);
// спрятать спрайт и увеличить счет
blobboSprite[j].setVisible(false); //При столкновении спрайта ракеты игрока со спрайтом пришельца оба спрайта исчезают
missileSprite[i].setVisible(false);
score += 10;
break;
}
// ракета попала в пришельца Джелли?
if (jellySprite[j].isVisible)
if (missileSprite[i].collidesWith(jellySprite[j], false)) {
// воспроизвести звук разрушения
try {
Manager.playTone(ToneControl.C4 – 6, 100, 100);
}
catch (Exception e) {
}
// создать взрыв
addExplosion(jellySprite[j]);
// спрятать спрайт и увеличить счет
jellySprite[j].setVisible(false);
missileSprite[i].setVisible(false);
score += 15;
break;
}
// ракета попала в спрайт пришельца Тимми?
if (timmySprite[j].isVisible)
if (missileSprite[i].collidesWith(timmySprite[j], false)) {
// воспроизвести звук разрушения
try {
Manager.playTone(ToneControl.C4 – 6, 100, 100);
}
catch (Exception e) {
// создать взрыв
addExplosion(timmySprite[j]);
// спрятать спрайт и увеличить счет
timmySprite[j].setVisible(false);
missileSprite[i].setVisible(false);
score += 20; //Поскольку пришельцы Тимми летают быстрее других, за его уничтожение дается больше очков
break;
}
}
}
// ракета пришельца?
else {
// ракета попала в спрайт автомобиля?
if (missileSprite[i].collidesWith(playerSprite, false)) {
// воспроизвести звук взрывающегося автомобиля
try {
explosionPlayer.start; //Если ракета пришельца попадает в автомобиль, воспроизводится звук взрыва
}
catch (MediaException me) {
}
// создать взрыв
addExplosion(playerSprite);
//
установить спрайт игрока в исходное положениеplayerSprite.setPosition(0,
getHeight – playerSprite.getHeight – 10); //Положение автомобиля игрока изменяется, чем создается иллюзия нового автомобиля
playerSprite.setXSpeed(4);
playerSprite.setYSpeed(0);
// спрятать спрайт ракеты
missileSprite[i].setVisible(false);
// проверить, закончена ли игра
if (carsLeft– == 0) {
// остановить музыку
try {
musicPlayer.stop;
}
catch (MediaException me) {
}
// воспроизвести звук окончания игры
try {
gameoverPlayer.start;
}
catch (MediaException me) {
}
// спрятать спрайт автомобиля
playerSprite.setVisible(false);
gameOver = true;
return;
}
}
}
missileSprite[i].update;
}
}Приведенный код проверяет столкновение спрайта ракеты с другими игровыми спрайтами. Это очень важная информация, поскольку она определяет, как взаимодействует спрайт ракеты с прочими спрайтами. Ракеты игрока могут подбить только пришельцев, а ракеты пришельцев – игрока.
Совет Разработчику
Чтобы спрайты пришельцев не уничтожили друг друга, спрайты ракет разработаны так, что они не могут уничтожить спрайты пришельцев. Поэтому код работы со спрайтами ракет сначала проверяет, кому принадлежит ракета, и уже потом проверяется столкновение спрайта ракеты с другими спрайтами. Кроме того, это позволяет минимизировать число проверок столкновений, делая код игры более эффективным.
Если вы внимательно изучите приведенный код, то увидите, что при попадании ракеты в спрайт пришельца выполняются следующие действия:
1. воспроизводится тоновый сигнал;
2. создается спрайт взрыва;
3. спрайты пришельца и ракеты скрываются;
4. счет увеличивается;
Если ракета – это ракета пришельца, то выполняются следующие действия:
1. воспроизводится звуковой файл;
2. создается спрайт взрыва;
3. спрайт автомобиля возвращается в исходное положение у левого края экрана;
4. спрайт ракеты скрывается;
5. проверяется окончание игры.
Если значение переменной carsLeft показывает, что у игрока закончились автомобили, то игра заканчивается. Музыка останавливается, воспроизводится звук конца игры, спрайт автомобиля скрывается, а значение переменной gameOver становится равным true.
Совет Разработчику
Другой способ сделать игровой код эффективнее – передать в метод collidesWith в качестве второго параметра значения false. Если вы вспомните, то этот параметр определяет, будет ли использоваться пиксельный метод детектирования столкновений. В игре Space Out такой способ детектирования изображений не нужен.
Следующий фрагмент кода в методе update добавляет спрайты в игру случайным образом. Скорость, с которой новые пришельцы появляются в игре, зависит от уровня сложности. Следовательно, вы можете плавно изменять сложность игры, увеличивая скорость появления пришельцев. Это можно сделать на основании счета игры:
if (score < 250) {
if (rand.nextInt % 40 == 0) //Это самый простой уровень игры, который заканчивается, когда игрок набирает 250 очков
addAlien;
}
else if (score < 500) {
if (rand.nextInt % 20 == 0)
addAlien;
}
else if (score < 1000) {
if (rand.nextInt % 10 == 0)
addAlien;
}
else {
if (rand.nextInt % 5 == 0) //Это самый сложный уровень игры, который начинается, когда игрок набирает 1000 очков
addAlien;
}Если счет меньше 250, то вероятность добавления нового спрайта на каждом игровом цикле равна 1/40. Это соответствует самому простому уровню игры. Сложность игры постепенно увеличивается, пока счет не станет равным 1000. В этом случае вероятность появления пришельца в игровом цикле равна 1/5. Если вы задумались о том, сколько времени требуется для выполнения одного цикла, то знайте, что пришельцы появляются достаточно быстро. Последний фрагмент кода метода update случайным образом запускает ракеты пришельцев:
if (rand.nextInt % 4 == 0) {
switch (Math.abs(rand.nextInt % 3)) {
// стреляет Блоббо
case 0:
for (int i = 0; i < 3; i++)
if (blobboSprite[i].isVisible) {
addMissile(blobboSprite[i]);
break;
}
break;
// стреляет Джелли
case 1:
for (int i = 0; i < 3; i++)
if (jellySprite[i].isVisible) {
addMissile(jellySprite[i]);
break;
}
break;
// стреляет Тимми
case 2:
for (int i = 0; i < 3; i++)
if (timmySprite[i].isVisible) {
addMissile(timmySprite[i]);
break;
}
break;
}
}