Tic Tac Toe

by royi
It's like Tic Tac Toe, but with pixels.
♥0 | Line 231 | Modified 2014-08-26 23:23:03 | MIT License
play

ActionScript3 source code

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

package {
    import flash.ui.Mouse;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;
    import flash.events.Event;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    
    import com.bit101.components.*;
    
    [SWF(width=465, height=465, frameRate=60, backgroundColor=0x000000)]
    public class Main extends Sprite {
        private static const CANVAS_SCALE:int = 8;
        private static const GRID_SIZE:int = 16;
        private static const PLAYER:String = "player";
        private static const CPU:String = "cpu";
        
        private var sw:int, sh:int, cw:int, ch:int;
        private var bgColor:uint = 0xff7777, fgColor:uint = 0xffffff;
        private var canvas:BitmapData;
        private var draw:Function;
        private var gameOver:Boolean = false;
        private var board:Array = [[],[],[]];
        private var gameObjects:Array = [];
        private var moves:int = 0;
        
        private var arrow:GameObject;
        private var grid:GameObject;
        
        // GFX
        private var gridGfx:Gfx;
        private var skullGfx:Gfx;
        private var heartGfx:Gfx;
        private var arrowGfx:Gfx;
        
        private var debug:Label;
        private var counter:int = 0;
        
        public function Main() {
            sw = stage.stageWidth, sh = stage.stageHeight;
            cw = sw / CANVAS_SCALE, ch = sh / CANVAS_SCALE;
            canvas = new BitmapData(cw, ch, false, 0xff7777);
            var bmp:Bitmap = new Bitmap(canvas);
            bmp.scaleX = bmp.scaleY = CANVAS_SCALE;
            addChild(bmp);
            
            readyGfx();
            
            arrow = new GameObject(arrowGfx.pixels);
            grid = new GameObject(gridGfx.pixels);
            grid.scatterPixels(cw, ch);
            gameObjects.push(grid);
            
            draw = GAME;
            
            addEventListener(Event.ENTER_FRAME, loop);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            
            Mouse.hide();
            
            debug = new Label(this);
        }
        
        private function cpuMove():void {
            var possibleMoves:Array = [];
            
            var x:int = randomMinMax(0, 3);
            var y:int = randomMinMax(0, 3);
            
            while (isTaken(x, y)) {
                x = randomMinMax(0, 3);
                y = randomMinMax(0, 3);
            }
            
            board[x][y] = CPU;
            
            var gameObject:GameObject = new GameObject(skullGfx.pixels, CPU, (x * GRID_SIZE) + 5, (y * GRID_SIZE) + 5);
            gameObject.scatterPixels(cw, ch);
            gameObjects.push(gameObject);
            
            if (hasWon(CPU)) {
                gameOver = true;
                for (var i:int = gameObjects.length-1; i >= 0; i--) {
                    if (gameObjects[i].id == PLAYER) gameObjects[i].explodePixels(cw, ch);
                }
            }
            
            /*
            for (var i:int = 0; i < 3; i++) {
                for (var j:int = 0; j < 3; j++) {
                    
                }
            }
            */
            
        }
        
        private function isTaken(x:int, y:int):Boolean {
            if (board[x][y])
                return true;
            
            return false;
        }
        
        private function hasWon(side:String):Boolean {
            if (board[0][0] == side && board[0][1] == side && board[0][2] == side) return true;
            if (board[1][0] == side && board[1][1] == side && board[1][2] == side) return true;
            if (board[2][0] == side && board[2][1] == side && board[2][2] == side) return true;
            if (board[0][0] == side && board[1][0] == side && board[2][0] == side) return true;
            if (board[0][1] == side && board[1][1] == side && board[2][1] == side) return true;
            if (board[0][2] == side && board[1][2] == side && board[2][2] == side) return true;
            if (board[0][0] == side && board[1][1] == side && board[2][2] == side) return true;
            if (board[2][0] == side && board[1][1] == side && board[0][2] == side) return true;
            return false;
        }
        
        private function onMouseMove(e:MouseEvent):void {
            arrow.x = mouseX / CANVAS_SCALE;
            arrow.y = mouseY / CANVAS_SCALE;
        }
        
        private function onMouseDown(e:MouseEvent):void {
            if (gameOver) return;
            
            var mx:int = mouseX / CANVAS_SCALE;
            var my:int = mouseY / CANVAS_SCALE;
            mx = (mx - 5) / GRID_SIZE;
            my = (my - 5) / GRID_SIZE;
            if (mx > 2) mx = 2;
            if (my > 2) my = 2;
            
            if (!board[mx][my]) {
                board[mx][my] = PLAYER;
                
                var gameObject:GameObject = new GameObject(heartGfx.pixels, PLAYER, (mx * GRID_SIZE) + 5, (my * GRID_SIZE) + 5);
                gameObject.scatterPixels(cw, ch);
                gameObjects.push(gameObject);
                
                moves++;
                
                if (hasWon(PLAYER)) {
                    gameOver = true;
                    for (var i:int = gameObjects.length-1; i >= 0; i--) {
                        if (gameObjects[i].id == CPU) gameObjects[i].explodePixels(cw, ch);
                    }
                    return;
                }
                
                if (moves < 5)
                    cpuMove();
            }
        }
        
        private function readyGfx():void {
            gridGfx = new Gfx();
            pixelRect(gridGfx, 21, 5, 1, 48);
            pixelRect(gridGfx, 37, 5, 1, 48);
            pixelRect(gridGfx, 5, 21, 48, 1);
            pixelRect(gridGfx, 5, 37, 48, 1);
            
            skullGfx = new Gfx();
            pixelRect(skullGfx, 6, 3, 5, 1);
            pixelRect(skullGfx, 4, 4, 9, 1);
            pixelRect(skullGfx, 3, 5, 11, 1);
            pixelRect(skullGfx, 3, 6, 3, 2);
            pixelRect(skullGfx, 7, 6, 4, 2);
            pixelRect(skullGfx, 12, 6, 2, 2);
            pixelRect(skullGfx, 4, 8, 4, 1);
            pixelRect(skullGfx, 10, 8, 3, 1);
            pixelRect(skullGfx, 6, 9, 5, 1);
            pixelRect(skullGfx, 7, 10, 1, 1);
            pixelRect(skullGfx, 9, 10, 1, 1);
            pixelRect(skullGfx, 6, 11, 1, 1);
            pixelRect(skullGfx, 8, 11, 1, 1);
            pixelRect(skullGfx, 10, 11, 1, 1);
            pixelRect(skullGfx, 7, 12, 3, 1);
            
            heartGfx = new Gfx();
            pixelRect(heartGfx, 4, 4, 3, 1);
            pixelRect(heartGfx, 10, 4, 3, 1);
            pixelRect(heartGfx, 3, 5, 2, 1);
            pixelRect(heartGfx, 6, 5, 2, 1);
            pixelRect(heartGfx, 9, 5, 5, 1);
            pixelRect(heartGfx, 3, 6, 1, 1);
            pixelRect(heartGfx, 5, 6, 9, 1);
            pixelRect(heartGfx, 3, 7, 11, 1);
            pixelRect(heartGfx, 4, 8, 9, 1);
            pixelRect(heartGfx, 5, 9, 7, 1);
            pixelRect(heartGfx, 6, 10, 5, 1);
            pixelRect(heartGfx, 7, 11, 3, 1);
            pixelRect(heartGfx, 8, 12, 1, 1);
            
            arrowGfx = new Gfx();
            pixelRect(arrowGfx, 0, 0, 2, 2);
            arrowGfx.pixels.push(0, 2);
            arrowGfx.pixels.push(2, 0);
            arrowGfx.pixels.push(2, 2);
            arrowGfx.pixels.push(3, 3);
        }
        
        private function loop(e:Event):void {
            canvas.lock();
            draw();
            canvas.unlock();
        }
        
        private function INTRO():void {
            
            //canvas.fillRect(canvas.rect, bgColor);
            
            canvas.setPixel(randomMinMax(0, cw), randomMinMax(0, ch), fgColor);
        }
        
        private function GAME():void {
            canvas.fillRect(canvas.rect, bgColor);
            /*
            for (var i:int = gridGfx.pixels.length-1; i > 0; i-=2) {
                canvas.setPixel(gridGfx.pixels[i-1], gridGfx.pixels[i], fgColor);
            }
            */
            var i:int;
            for (i = arrow.pixels.length-1; i > 0; i-=2) {
                canvas.setPixel(arrow.pixels[i-1] + arrow.x, arrow.pixels[i] + arrow.y, fgColor);
            }
            
            for (i = gameObjects.length-1; i >= 0; i--) {
                gameObjects[i].update();
                for (var j:int = gameObjects[i].pixels.length-1; j > 0; j-=2) {
                    if (!gameObjects[i].visible) continue;
                    canvas.setPixel(gameObjects[i].pixels[j-1] + gameObjects[i].x, gameObjects[i].pixels[j] + gameObjects[i].y, fgColor);
                }
            }
        }
        
        private function pixelRect(gfx:Gfx, x:int, y:int, width:int, height:int):void {
            for (var ix:int = 0; ix < width; ix++) {
                for (var iy:int = 0; iy < height; iy++) {
                    gfx.pixels.push(x + ix);
                    gfx.pixels.push(y + iy);
                }
            }
        }
        
        private function randomMinMax(min:Number, max:Number):Number {
            return min + (max - min) * Math.random();
        }
    }
}

class Gfx extends Object {
    public var pixels:Array = [];
}

class GameObject extends Object {
    public var pixels:Array;
    public var pixelsEnd:Array;
    public var id:String;
    public var x:Number, y:Number;
    public var visible:Boolean;
    
    public function GameObject(pixels:Array, id:String = "", x:Number = 0, y:Number = 0, visible:Boolean = true) {
        this.pixelsEnd = pixels, this.id = id; this.x = x, this.y = y, this.visible = visible;
        
        this.pixels = pixelsEnd.slice();
    }
    
    public function scatterPixels(canvasWidth:int, canvasHeight:int):void {
        for (var i:int = pixelsEnd.length-1; i > 0; i-=2) {
            pixels[i-1] = randomMinMax(0-x, canvasWidth-x);
            pixels[i] = randomMinMax(0-y, canvasHeight-y);
        }
    }
    
    public function explodePixels(canvasWidth:int, canvasHeight:int):void {
        for (var i:int = pixelsEnd.length-1; i > 0; i-=2) {
            pixelsEnd[i-1] = randomMinMax(0-x, canvasWidth-x);
            pixelsEnd[i] = randomMinMax(0-y, canvasHeight-y);
        }
    }
    
    public function update():void {
        for (var i:int = pixels.length-1; i > 0; i-=2) {
            pixels[i-1] += (pixelsEnd[i-1] - pixels[i-1]) * .1;
            pixels[i] += (pixelsEnd[i] - pixels[i]) * .1;
            
            if (Math.ceil(pixels[i-1]) == pixelsEnd[i-1])
                pixels[i-1] = pixelsEnd[i-1];
                
            if (Math.ceil(pixels[i]) == pixelsEnd[i])
                pixels[i] = pixelsEnd[i];
        }
    }
    
    private function randomMinMax(min:Number, max:Number):Number {
        return min + (max - min) * Math.random();
    }
}