Actionscript:
-
[SWF(width=500, height=500)]
-
var canvasSize:int=stage.stageWidth;
-
var canvas:BitmapData=new BitmapData(canvasSize,canvasSize,false,0x000001);
-
addChild(new Bitmap(canvas, "auto", true));
-
var size:int=canvas.width*canvas.height - canvasSize;
-
var pixels:Vector.<uint>=canvas.getVector(canvas.rect);
-
for (var i:int = 0; i<canvasSize; i++) {
-
var xp:int=int(Math.random()*canvasSize);
-
var yp:int=int(Math.random()*canvasSize);
-
pixels[xp+yp*canvasSize]=0xFF000000;
-
}
-
var targetCol:uint=0xFF000000;
-
var buffer:Vector.<uint>=pixels.concat();
-
var fade:uint=1;
-
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
var curr:uint=targetCol;
-
var r:int = (curr>> 16) & 0xFF;
-
var g:int = (curr>> 8) & 0xFF;
-
var b:int=curr&0xFF;
-
r+=fade;
-
g+=fade;
-
b+=fade;
-
if (r>255) r=255;
-
if (g>255) g=255;
-
if (b>255) b=255;
-
var darker:uint=0xFF000000|r<<16|g<<8|b;
-
if (darker==0xFFFFFFFF) {
-
removeEventListener(Event.ENTER_FRAME, onLoop);
-
}
-
for (var i:int = canvasSize; i<size; i++) {
-
curr=pixels[i];
-
if (curr==targetCol) {
-
var index:int=i-canvasSize+int(Math.random()*3) - 1;
-
if (index>0) buffer[index]=darker;
-
if (int(Math.random()*50)==1) {
-
index=i-canvasSize+int(Math.random()*3)-1;
-
if (index>0) buffer[index]=darker;
-
}
-
}
-
}
-
targetCol=darker;
-
canvas.lock();
-
canvas.setVector(canvas.rect, buffer);
-
pixels=buffer.concat();
-
canvas.unlock();
-
}
This snippet uses setVector() to draw something that looks like this:
This is a cellular automaton. It has kind of a strange rule set - but you could easily use this snippet to do more traditional cellular automata.
Actionscript:
-
var canvasSize:int = 400;
-
var canvas:BitmapData = new BitmapData(canvasSize, canvasSize, false, 0xFFFFFF);
-
addChild(new Bitmap(canvas));
-
var size:int = canvas.width * canvas.height;
-
var pixels:Vector.<uint> = canvas.getVector(canvas.rect);
-
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
for (var i:int = 0; i<500; i++){
-
fillCircle(int(Math.random() * canvasSize),
-
int(Math.random() * canvasSize),
-
int(Math.random() * 5 + 3),
-
uint(Math.random() * 0xFFFF));
-
}
-
canvas.lock();
-
canvas.setVector(canvas.rect, pixels);
-
canvas.unlock();
-
}
-
-
function fillCircle(xp:int,yp:int, radius:int, col:uint = 0x000000):void {
-
var xoff:int =0;
-
var yoff:int = radius;
-
var balance:int = -radius;
-
while (xoff <= yoff) {
-
var p0:int = xp - xoff;
-
var p1:int = xp - yoff;
-
var w0:int = xoff + xoff;
-
var w1:int = yoff + yoff;
-
hLine(p0, yp + yoff, w0, col);
-
hLine(p0, yp - yoff, w0, col);
-
hLine(p1, yp + xoff, w1, col);
-
hLine(p1, yp - xoff, w1, col);
-
if ((balance += xoff++ + xoff)>= 0) {
-
balance-=--yoff+yoff;
-
}
-
}
-
}
-
function hLine(xp:int, yp:int, w:int, col:uint):void {
-
var index:int = xp + yp * canvasSize;
-
for (var i:int = 0; i <w; i++){
-
index++;
-
if (index> -1 && index <size){
-
pixels[index] = col;
-
}
-
}
-
}
In the past I've posted examples of Bresenham's Circle (here and here). Both of those examples make use of setPixel(). Today's snippet demos a version of Bresenham's Circle that works with setVector().
Actionscript:
-
[SWF(width=401,height=401,background=0xEFEFEF)]
-
-
var w:Number = stage.stageWidth-1;
-
var h:Number = stage.stageHeight-1;
-
var tileSize:Number = 20;
-
var halfTileSize:Number = 20;
-
var hTiles:Number = w / tileSize;
-
var vTiles:Number = h / tileSize;
-
var world:Shape = Shape(addChild(new Shape()));
-
var map:Array=[];
-
populateMap();
-
var gridColor:uint = 0xCCCCCC;
-
grid(tileSize, gridColor);
-
-
vTiles -= 1;
-
var movers:Array = [];
-
for (var i:int = 0; i<100; i++){
-
movers.push(makeMover(i % hTiles, int( i / hTiles),0x000000))
-
movers.push(makeMover(i % hTiles, vTiles - int( i / hTiles),0xFF0000))
-
}
-
var moverNum:int = movers.length;
-
hTiles -= 1;
-
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
world.graphics.clear();
-
for (var i:int = 0; i<moverNum; i++){
-
movers[i]();
-
}
-
}
-
function populateMap():void{
-
for (var i:int = 0; i<vTiles; i++){
-
map[i] = [];
-
for (var j:int = 0; j<hTiles; j++){
-
map[i][j] = 0;
-
}
-
}
-
}
-
function grid(size:Number=30, lineColor:uint=0xFFFF00, lineAlpha:Number=1):void {
-
with(graphics){
-
lineStyle(0, lineColor, lineAlpha);
-
drawRect(0,0,w,h);
-
for (var i:Number = size; i<w; i+=size) {
-
moveTo(i, 0);
-
lineTo(i, w);
-
}
-
for (i = size; i<h; i+=size) {
-
moveTo(0, i);
-
lineTo(h, i);
-
}
-
}
-
}
-
function makeMover(x:Number, y:Number, col:uint):Function{
-
var xp:Number = x;
-
var yp:Number = y;
-
var prevX:Number = x;
-
var prevY:Number = y;
-
map[yp][xp] = 1;
-
var dx:Number = xp;
-
var dy:Number = yp;
-
var counter:int = 0;
-
return function():void{
-
if (counter> 20){
-
if (int(Math.random()*30) == 1){
-
xp += int(Math.random()*2) - 1 | 1;
-
xp = xp <0 ? 0 : xp;
-
xp = xp> hTiles ? hTiles : xp;
-
if (map[yp][xp] == 1){
-
xp = prevX;
-
}else{
-
map[prevY][prevX] = 0;
-
map[yp][xp] = 1;
-
counter = 0;
-
}
-
prevX = xp;
-
}else
-
if (int(Math.random()*30) == 1){
-
yp += int(Math.random()*2) - 1 | 1;
-
yp = yp <0 ? 0 : yp;
-
yp = yp> vTiles ? vTiles : yp;
-
if (map[yp][xp] == 1){
-
yp = prevY;
-
}else{
-
map[prevY][prevX] = 0;
-
map[yp][xp] = 1;
-
counter = 0;
-
}
-
prevY = yp;
-
}
-
}
-
counter++;
-
dx += (xp - dx) * 0.5;
-
dy += (yp - dy) * 0.5;
-
with(world.graphics){
-
lineStyle(0, gridColor,1, true)
-
beginFill(col);
-
drawRect(dx * tileSize, dy * tileSize, tileSize, tileSize);
-
}
-
}
-
}
This (somewhat long) snippet moves boxes around on a grid - the boxes avoid one another by reading values in a 2D array. This technique can also be used for collision detection in tile-based games.
Have a look at the swf here...
Actionscript:
-
[SWF(width=800, height=600)]
-
var xn1:Number;
-
var xn:Number = Math.random() * Math.random() * .2;
-
var inc:int = 0;
-
var xp:Number = 10;
-
var yp:Number = 10;
-
var count:int = 1;
-
scaleX = scaleY = 2;
-
graphics.lineStyle(0,0x00000);
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
-
xn1 = 2 * xn % 1;
-
xn = xn1;
-
if (inc == 0){
-
graphics.moveTo(xp + inc, yp + 30 - xn1 * 30);
-
}else{
-
graphics.lineTo(xp + inc, yp + 30 - xn1 * 30);
-
}
-
inc++
-
if (inc == 50){
-
inc = 0;
-
xp = 10 + count % 6 * 60;
-
yp = 10 + int(count / 6) * 60;
-
xn = Math.random() * Math.random() * .2;
-
trace(xn);
-
count++;
-
}
-
}
This snippet plots 2x mod 1 maps with random starting values for xn. More info over at wikipedia and mathworld.
Posted in Math, misc, motion | Also tagged actionscript, flash |