Game Life Gex

by Cheshir
♥0 | Line 202 | Modified 2016-12-03 07:11:28 | MIT License
play

ActionScript3 source code

/**
 * Copyright Cheshir ( http://wonderfl.net/user/Cheshir )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/yRXi
 */

package {
    import flash.events.Event;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextField;
    import flash.events.MouseEvent;
    import flash.display.Sprite;
    public class FlashTest extends Sprite {
        public var front:Sprite;
        public var logit:TextField;
        public var play:Sprite;
        
        public var field:Array=[];
        public var fieldCheck:Array=[];
        
        public function FlashTest() {
            // write as3 code here..
            front = new Sprite();
            play = new Sprite();
            logit = new TextField();
            logit.autoSize = TextFieldAutoSize.LEFT;
            initField();
            
            drawField();
            addChild(front);
            addChild(logit);
            addChild(play);
            play.x = 160; play.y = 10;
            drawPlayButton();
            stage.addEventListener(MouseEvent.MOUSE_MOVE, cellMove);
            stage.addEventListener(MouseEvent.CLICK, cellSet);
            play.addEventListener(MouseEvent.CLICK, playHolder);
            /* Так, теперь у нас есть 
            1. Вселенная
            2. Проверка соседей
            3. Живые и мертвые клетки
            4. Изменение клеток
                Нужно добавить...
            5. Пуск/Пауза
            6. Проверка, отметить, что должно изменится
            7. Обновление поля
            
            */
            stage.addEventListener(Event.ENTER_FRAME, loopGame);
            stage.frameRate = 8;
        }
        // Цикл игры
        private var checkFrame:Boolean = true;
        private var inGame:Boolean = false;
        public function loopGame(e:Event):void{
            if(!inGame){ return; } // Вообще пауза, забей на все
            
            var tx:int = 0;
            var ty:int = 0;
            if(checkFrame){ // Проверочный этап
                // необходимо пройти по массиву игры field и записать 
                // в массив fieldCheck - как должно быть на следующей итерации
                //log("check step");
                while(tx<18){
                    ty = 0;
                    while(ty<18){
                        fieldCheck[tx][ty] = cell_automat_2(tx,ty);
                        ty+=1;
                    }
                    tx+=1;
                }
            } else { // Этап обновления
                // Здесь необходимо переписать все из массива fieldCheck в field  
                log("uppdate step");
                while(tx<18){ // самый быстрый цикл на диком as3
                    ty = 0;
                    while(ty<18){
                        field[tx][ty] = fieldCheck[tx][ty];
                        ty+=1;
                    }
                    tx+=1;
                }
                drawField();    // Чуть не забыл ;)
            }
            checkFrame = !checkFrame;
        }
        
        // Ну блин... тут плохо все...
        // Изменим правила 2,3,4 - клетка выживает, 3 или 4 клетка зарождается
        public function cell_automat_2(tx:int, ty:int):int{
            var cl:int = fieldGet(tx,ty);
            var ar:int = aroundCount(tx,ty);
            if(ar<2 || ar>3){ // Вымирание
                return 0;
            }
            if(cl==0 && ar==3){ // Зарождение
                return 1;
            }
            if(cl==1 && (ar==2 || ar==3)){ // Жизнь
                return 1;
            }
            return 0;
        }
        
        // Классические правила 2,3 - клетка выживает, ровно 3 клетка зарождается
        public function cell_automat_1(tx:int, ty:int):int{
            // Определим жива ли клетка
            var cl:int = fieldGet(tx,ty);
            var ar:int = aroundCount(tx,ty); 
         //   log("cell is "+cl+" around "+ar);
            if(ar<2 || ar>3){ // Одиночество и перенаселение = вымирание
                return 0;
            }
            if(cl==0 && ar==3){ // Зарождение
                return 1;
            }
            if(cl==1 && (ar==2 || ar==3)){ // Поддержание жизни
                return 1;
            }
            return 0;
        }
        
        // Запуск и остановка игры.
        public function playHolder(e:MouseEvent):void{
            inGame = !inGame;
            if(inGame){
                drawPauseButton();
            } else {
                // Когда игра ставится на паузу недостаточно просто остановить отрисовку
                drawPlayButton(); // Необходимо вернуть игру в состояние проверочного этапа
                checkFrame = true;
            }
        }
        // Игра на паузе рисуем стрелку
        public function drawPlayButton():void{
            play.graphics.clear();
            play.graphics.beginFill(0xffffff);
            play.graphics.drawRect(0,0,30,30);
            play.graphics.beginFill(0x00cc00);
            play.graphics.lineTo(30,15);
            play.graphics.lineTo(0,30);
            play.graphics.endFill();
        }
        public function drawPauseButton():void{
            play.graphics.clear();
            play.graphics.beginFill(0xffffff);
            play.graphics.drawRect(0,0,30,30);
            play.graphics.beginFill(0xcc0000);
            play.graphics.drawRect(0,0,10,30);
            play.graphics.drawRect(20,0,10,30);
            play.graphics.endFill();
        }
        
        // Создание пуcтого поля
        public function initField():void{
            // Как хранить данные о гексагональных клетках? 
            // Так же как и обычные, просто каждая четная колонка смещена.
            for(var tx:int=0; tx<18; tx++){
                field[tx] = [];
                fieldCheck[tx] = [];
                for(var ty:int=0; ty<18; ty++){
                    field[tx][ty] = Math.round(Math.random()); // Все клетки 1 || 0
                    fieldCheck[tx][ty] = 0;
                }
            }
        }
        
        // Рассчет соседей в gex-окресностях
        public function aroundCount(x:uint, y:uint):int{
            // Игра "Жизнь" использует окресность Мура, но у меня только 6 клеток
            // так, тут где то запара
            var ar:int = 0;
            if(x%2==0){ // Четные
                ar += fieldGet(x, y-1);
                ar += fieldGet(x+1, y-1);
                ar += fieldGet(x+1, y);
                ar += fieldGet(x, y+1);
                ar += fieldGet(x-1, y);
                ar += fieldGet(x-1, y-1);
            } else { // Нечетные
                ar += fieldGet(x, y-1);
                ar += fieldGet(x+1, y);
                ar += fieldGet(x+1, y+1);
                ar += fieldGet(x, y+1);
                ar += fieldGet(x-1, y+1);
                ar += fieldGet(x-1, y);
            }
        //    log("and ar?"+ar);
            return ar;
        //    log(x+" "+y+" around "+ar);
        }
        
        // Чтобы не ломалось out of range и "закольцевать" массив
        public function fieldGet(x:int, y:int):int{ 
            var lx:int = field.length-1;
            var ly:int = field[0].length-1;
          //  log("leng "+lx+" x "+x);
            if(x>lx) { x-=lx; } else if (x<0){ x+=lx; }
            if(y>ly){  y-=ly; } else if (y<0){ y+=lx; }
            return field[x][y];
        }

        // Корректирование игрового поля кликом 
        public function cellSet(e:MouseEvent):void{
            var xj:int = Math.floor((e.localX+7) / 14)-4;
            var yj:int = Math.floor((e.localY) / 16)-4;
            if(xj>17 || yj>17 || xj<0 || yj<0){
                log("за пределами")
                return;
            }
            
            var cell:int = fieldGet(xj,yj);
            if(cell==1){
               field[xj][yj]=0; 
            } else if(cell==0){
               field[xj][yj] = 1;
            }
            drawField();
//            log(xj+" "+yj+" now:"+field[xj][yj]+" ar:"+aroundCount(xj,yj));
            aroundCount(xj,yj); // Ошибочка'C
        }
        
        // Перемещение указателя мышки
        public function cellMove(e:MouseEvent):void {
            var xj:int = Math.floor((e.localX+7) / 14)*14;
            var yj:int = Math.floor((e.localY) / 16)*16;
            if(xj/14%2==1){ // Все еще проблема с позиционированием позиции мышки
                yj+=8; // Но по крайней мере почти.
            }
            front.graphics.clear();
            front.graphics.beginFill(0xff0000, 0.6);
            front.graphics.drawCircle(xj,yj, 7);
        //    log(xj+" "+yj);
        }

        // Дебаг, потому как trace нету
        public function log(s:*):void{
            logit.text = s.toString();
        }
        
        // Отрисовка Поля клеток
        public function drawField():void{
            this.graphics.clear();
            for(var i:int=0; i<18; i++){
                drawLine(i);
            }
        }
        
        // Отрисовка Столбца клеток
        public function drawLine(x:int):void{
            var yJoo:int = 16;
            if(x%2==0){
                yJoo = 8;
            }
            for(var y:int=0; y<18; y++){
                if(field[x][y]==1){
                    this.graphics.beginFill(0);//99aa99);
                } else {
                    this.graphics.beginFill(0xcccccc);
                }
                this.graphics.drawCircle(56 + x*14, 56 + yJoo + y*16, 7);
            }
            log("draw "+x);
        }
        

    }
}

Forked