Skip to content

Instantly share code, notes, and snippets.

@illuzor
Created November 10, 2012 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save illuzor/4051156 to your computer and use it in GitHub Desktop.
Save illuzor/4051156 to your computer and use it in GitHub Desktop.
package screens {
import com.adobe.nativeExtensions.Vibration;
import constants.ItemType;
import elements.Button;
import elements.Item;
import elements.Platform;
import events.GameEvent;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.events.TouchEvent;
import flash.text.TextField;
import flash.utils.Timer;
import tools.GameControl;
import tools.Tools;
/**
* Основной класс игры. Что предствляет собой игровой процесс:
* Внизу экрана находится платформа, которую можно двигать влево/вправо движением пальца по экрану в любой части экрана или наклоном устройства.
* Сверху падают так называемые айтемы, которые могут быть трёх видов:
* - ItemType.GOOD - обычный айтем. При собирании прибавляет единицу к очками, при пропускании(уход за нижнюю границу экрана)
* отнимает единицу от очков
* - ItemType.VERY_GOOD - "усиленный" айтем. При собирании прибавляет 5 к очками. При пропускании ничего не происходит.
* - ItemType.EVIL - "злой" айтем. При собирании отнимает единицу от очков. При пропускании ничего не происходит.
*
* При значении очков меньше пяти засчитывается проигрыш, а результатом игры считается максимальное набранное количество очков.
* С каждым новым уровнем айтемы движутся быстрей, чем в предыдущем.
*
* Сверху слева находится индикатор набранных очков, справа сверху кнопка выхода в главное меню.
* Снизу в центре под платформой находится индикатор текущего уровня.
*
*
* @author illuzor
*/
[Event(name = "gameOver", type = "events.GameEvent")]
[Event(name = "exitGame", type = "events.GameEvent")]
public class GameScreen extends Sprite {
/** @private контейнер для платформы и айтемов */
private var gameContainer:Sprite;
/** @private кнопка для выхода в главное меню */
private var menuButton:Button;
/** @private плтаформа */
private var platform:Platform;
/** @private игровой таймер. нужен для добавления нового айтема */
private var gameTimer:Timer;
/** @private номер текущего уровня */
private var currentLevel:uint;
/** @private текущее количество очков */
private var currentScore:int;
/** @private текстовое поле для отображения уровня */
private var levelText:TextField;
/** @private текстовое поле для отображения количества очков */
private var scoreText:TextField;
/** @private переменная вибрации */
private var vibration:Vibration = new Vibration();
/** @private менеджер управления */
private var control:GameControl;
/** максимальное количество очков */
public var maxScore:uint;
/**
* В конструкторе слушаем добавление на сцену.
*/
public function GameScreen() {
addEventListener(Event.ADDED_TO_STAGE, addedtToStage);
}
/**
* @private создаём элементы экрана
*
* @param e событие добавления на сцену
*/
private function addedtToStage(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, addedtToStage);
gameContainer = new Sprite(); // контейнер
addChild(gameContainer);
platform = new Platform(); // создаём платформу, подгоняем её размер и положение и добавляем на сцену
platform.width = stage.stageWidth * .18;
platform.scaleY = platform.scaleX;
platform.x = (stage.stageWidth - platform.width) / 2;
platform.y = stage.stageHeight * .88;
addChild(platform);
scoreText = Tools.generateTextField(30, "SCORE: 0"); // текстовое поле очков
scoreText.width = stage.stageWidth / 2;
scoreText.x = scoreText.y = 10;
addChild(scoreText);
levelText = Tools.generateTextField(30, "LEVEL: 1"); // текстовое поле уровня
levelText.width = levelText.textWidth + 4;
levelText.x = (stage.stageWidth - levelText.width) / 2;
levelText.y = stage.stageHeight - levelText.height - 20;
addChild(levelText);
menuButton = new Button("MENU");// кнопка для выхода в главное меню.
addChild(menuButton);
menuButton.width = stage.stageWidth / 3.2;
menuButton.scaleY = menuButton.scaleX;
menuButton.x = stage.stageWidth - menuButton.width - 10;
menuButton.y = 10;
// создаём менеджер управления и отдаём ему ссылки на платформу и сцену
control = new GameControl(platform, stage);
startNewLevel(); // запускаем новый уровень
menuButton.addEventListener(TouchEvent.TOUCH_TAP, exitGame); // событие нажатия на кнопку выхода в меню
addEventListener(Event.ENTER_FRAME, updateGame); // обновление состояния игры
addEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
}
/**
* @private запуск нового уровня. каждый уровень состоит из 20 айтемов
*/
private function startNewLevel():void {
var interval:uint = 2300; // интервал вызова таймера
if (2300 - currentLevel * 350 < 250) { // чем выше уровень, тем меньше интервал
interval = 350;
} else {
interval = 2300 - currentLevel * 350;
}
gameTimer = new Timer(interval, 20); // создаём и запускаем таймер.
gameTimer.start();
gameTimer.addEventListener(TimerEvent.TIMER, addItem);
gameTimer.addEventListener(TimerEvent.TIMER_COMPLETE, cicleEnd);
}
/**
* @private Создаём новый айтем по таймеру
*
* @param e событие тика таймера
*/
private function addItem(e:TimerEvent):void {
var randomRange:Number = Math.random(); // случайное значене
var itemType:String = ItemType.GOOD; // тип нового айтема. по умолчнанию все айтемы обычные
if (randomRange > 0.65 && randomRange < .95) { // если случайное значение в заданном диапазоне (30%)...
itemType = ItemType.EVIL; // ... айтем злой
} else if (randomRange >= .95 ){ // 5% айтемов пусть будут "усиленными"
itemType = ItemType.VERY_GOOD;
}
var item:Item = new Item(itemType); // создаём новый айтем со сгенерированным типом
item.x = stage.stageWidth * Math.random(); // помещаем на случайны .x
item.y = -item.height; // а по .y убираем за пределы сцены
item.speed = currentLevel + 1; // скорость айтема
gameContainer.addChild(item); // и добавлеем его на сцену
}
/**
* @private когда таймер закончил работу, очищаем, что не нужно и запускаем новый уровень
*
* @param e событие окончания работы таймера
*/
private function cicleEnd(e:TimerEvent):void {
gameTimer.removeEventListener(TimerEvent.TIMER, addItem);
gameTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, cicleEnd);
gameTimer = null; // удаляем слушатели с таймера и ссылку на таймер
currentLevel++; // увеличиваем уровень на единицу
levelText.text = "LEVEL: " + String(currentLevel + 1); // обновляем текст уровня
levelText.width = levelText.textWidth +4;
startNewLevel();// запускаем новый уровень
}
/**
* @private Игровой цикл
* Обновляем положение айтемов. если они ушли за пределы сцены, удаляем.
* Обратываем их столкновения с платформой
*
* @param e enterFrame событие
*/
private function updateGame(e:Event):void {
// в цикле проходимся по всему содержимому игрового контейнера, кроме платформы (i = 1)
for (var i:int = 1; i < gameContainer.numChildren; i++) {
var tempItem:Item = gameContainer.getChildAt(i) as Item; // берём айтем
tempItem.y += (tempItem.speed * 3) * .8; // увеличиваем его .y координату в зависимости от его скорости.
if (tempItem.y > stage.stageHeight) { // если он ушёл вниз за сцену ...
gameContainer.removeChild(tempItem); //... удаляем его ...
if (tempItem.type == ItemType.GOOD) currentScore--; // .. а если его тип при этом оказался обычным, отнимаем единицу от очков.
}
if (tempItem.hitTestObject(platform)) { // если айтем пойман платформой
// в зависимости от его типа, производим действие.
// думаю, тут ничего не надо объяснять
switch (tempItem.type) {
case ItemType.GOOD:
currentScore++;
break;
case ItemType.VERY_GOOD:
currentScore +=5;
break;
case ItemType.EVIL:
currentScore--;
// вибрируем 150 миллисекунд, если вибрация вообще поддерживается
if (Vibration.isSupported) vibration.vibrate(150);
break;
}
// также при попадании на платформу айтем больше не нужен, удаляем его со сцены
gameContainer.removeChild(tempItem);
}
}
scoreText.text = "SCORE: " + currentScore; // обновляем текстовое поле с очками
if (maxScore < currentScore) maxScore = currentScore; // записываем максимальное количество очков
if (currentScore < -5) { // если количество очков меньше, чем -5..
dispatchEvent(new GameEvent(GameEvent.GAME_OVER)); //... генерируем событие проигрыша
}
}
/**
* @private генерируем событие выхода из игры
*
* @param e событие прикосновения к кнопке выхода в меню
*/
private function exitGame(e:TouchEvent):void {
dispatchEvent(new GameEvent(GameEvent.EXIT_GAME));
}
/**
* @private удаляем все ненужные больше слушатели
*
* @param e событие удаления со сцены
*/
private function removedFromStage(e:Event):void {
removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
removeEventListener(Event.ENTER_FRAME, updateGame);
menuButton.removeEventListener(TouchEvent.TOUCH_TAP, exitGame);
gameTimer.stop();
gameTimer.removeEventListener(TimerEvent.TIMER, addItem);
gameTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, cicleEnd);
gameTimer = null;
control.clear(); // очишаем менеджер управления
control = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment