package GameCore { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; import flash.utils.getTimer; import Tools.Utils; /** * ... * @author Regul */ public class StarField extends Sprite { // «Холст», где мы будем рисовать точки private var bitmapData:BitmapData; // Математическая модель звезд-точек, которые мы будем рисовать private var stars:Vector.; // Количество звезд private var starsCount:uint; // Размеры «холста» private var fieldWidth:uint; private var fieldHeight:uint; // Половина холста (для получения центра) private var halfWidth:uint; private var halfHeight:uint; // Размер окантовки «холста» private const offset:uint = 10; // Размер холста в окантовной private var fieldWidthWithOffset:uint; private var fieldHeightWithOffset:uint; // Время последнего создания новой звезды (чтобы звезды не появлялись все сразу в куче) private var lastCreateTimer:int; /***/ private var sumTime:Number = 0; private var countTime:Number = 0; private var iteratorsCount:Number = 2000; public function StarField(width:int, height:int, count:uint) { fieldWidthWithOffset = fieldWidth = width; fieldHeightWithOffset = fieldHeight = height; fieldWidthWithOffset += offset; fieldHeightWithOffset += offset; halfWidth = fieldWidth / 2; halfHeight = fieldHeight / 2; starsCount = count; // Помещаем холст на экран initBody(); initStars(); // Создаем массив звезд updateStars(); // Обновляем мат. модель (положение) звезд. drawStars(); // Рисуем звезды на холсте addEventListener(Event.ENTER_FRAME, enterFrame); } /** * Обновление холста каждый кадр: * 1. Обновляем мат. модель (положение) звезд. * 2. Делаем отрисовку звезд. */ private function enterFrame(e:Event):void { updateStars(); drawStars(); } /** * Обновляем мат. модель. Если звезда выходит за область отрисовки — заново перемещаем её в центр */ private function updateStars():void { var i:uint = starsCount; var star:Point; while ( --i > -1) // Проходимся по всем звездам { star = stars[i]; // Изменяем создаем движение звезды «от центра экрана»(fieldWidth/2) star.x += (star.x - halfWidth) * 0.01; star.y += (star.y - halfHeight) * 0.01; // Если звезда вышла за границу, возвращаем её в центр (создаем новую звезду). А вообще, нужно готовиться ко встрече со звездой! :) if (star.x > fieldWidthWithOffset || star.x < -offset || star.y > fieldHeightWithOffset || star.y < - offset) { // Возвращаем звезду не чаще раза в кадр if (lastCreateTimer < 0) { // Можно сделать создание звезду каждые 2,3... кадра. У нас каждый 1 кадр lastCreateTimer = 1; // Создаем звезду в центре с некоторым отклонением в какую-нибудь сторону(в дальнейшем звезда полетит в этом направлении) star.x = halfWidth + Utils.rand(-offset, offset); star.y = halfHeight + Utils.rand( -offset, offset); } } } lastCreateTimer--; // Обновляем таймер последнего создания звезды } /** * Отрисовка звезд на холсте */ private function drawStars():void { var i:uint = starsCount; // Итератор звезд var length:Number; // Длинна от центра до звезды var star:Point; // Ссылка на мат. модель звезды var alpha:Number; // Прозрачность звезды bitmapData.lock(); // Блокируем холст ("пока не смотреть, я не закончил!") bitmapData.fillRect(bitmapData.rect, 0); // Очищаем холст while ( --i > -1) // Проходимся по всем звездам { star = stars[i]; //Расстояние звезды от центра length = Math.sqrt( (star.x - halfWidth) * (star.x - halfWidth) + (star.y - halfHeight) * (star.y - halfHeight) ); //Прозрачность звезды (чем ближе звезда к центру - тем она прозрачнее) alpha = 0xFF000000; if ( length < 300 ) alpha = ((length / 300 * 256) << 24); switch(int(Math.random()*25)) // Делаем блик для звезды с вероятностью 1:26 { case 0: // Отрисовываем звезду с "бликом" bitmapData.setPixel32( star.x, star.y, 0x00FFFFFF + alpha); bitmapData.setPixel32( star.x + 1, star.y, 0x00FFFFFF + alpha); bitmapData.setPixel32( star.x, star.y + 1, 0x00FFFFFF + alpha); bitmapData.setPixel32( star.x+1, star.y+1, 0x00FFFFFF + alpha); break; default: // Отрисовываем звезду bitmapData.setPixel32( star.x, star.y, 0x00FFFFFF + alpha); break; } } bitmapData.unlock(); // Разблокируем холст ("теперь можно смотреть, я закончил!") } /** * Создание массива звезд в мат. моделе */ private function initStars():void { //init vector stars = new Vector.(starsCount, true); var i:uint = starsCount; while ( --i > -1) { stars[i] = new Point( -offset, -offset ); } } /** * Создаем «холст», на котором будем отрисовывать звезды */ private function initBody():void { bitmapData = new BitmapData(fieldWidth, fieldHeight); var bitmap:Bitmap = new Bitmap(bitmapData); addChild(bitmap); } /** * При удалении не забываем убрать слушатель события. Если мы о нем забудем, он о нас не забудет :) */ public function destroy():void { removeEventListener(Event.ENTER_FRAME, enterFrame); } } }