Browsing the archives for the fun category.

Actionscript 3 - PixelMorphing Class (now with source code)

BitmapData, Particles, actionscript 3, advanced image editing, algorithms, classes, fun, morphing

Ok, lot of time passed since I posted my PixelMorphing class experiment.
Seemed to me that post passed quite unobserved but then I received a lot of feedback and e-mail asking to share the source code.

Well, the first time I wanted to speed up posting and do further experimentation/optimization so I din’t prepare the source but since the main believe of this blog is that if someone ask for code I release it, here we are. Optimization still not done… I am a lazy one, so if someone want to help improve it is really welcome.

Now the steps to play with it:

  1. Download the PixelMorphing class
  2. Use it with this code:
import com.oaxoa.fx.PixelMorphing;
var pm:PixelMorphing=new PixelMorphing(pic1, pic2, 200);
addChild(pm);
 
pm.start();
//pm.reset();

or certainly you can place some buttons or some combo and wait for some event for it to start or reset. The main code of the previous post is this:

import com.oaxoa.fx.PixelMorphing;
import fl.controls.Button;
import fl.controls.ComboBox;
 
var pm:PixelMorphing=new PixelMorphing(pic1, pic2, 200);
addChild(pm);
 
var button1:Button=new Button();
button1.label="Start";
button1.y=203;
button1.x=3;
addChild(button1);
button1.addEventListener(MouseEvent.CLICK, onstart);
 
var button2:Button=new Button();
button2.label="Reset";
button2.y=203;
button2.x=3;
addChild(button2);
button2.addEventListener(MouseEvent.CLICK, onreset);
 
 
 
button1.width=button2.width=60;
button1.height=button2.height=25;
button2.visible=false;
 
function onstart(event:MouseEvent):void {
	pm.start();
	button1.visible=false;
	button2.visible=true;
}
function onreset(event:MouseEvent):void {
	pm.reset();
	button2.visible=false;
	button1.visible=true;
}
 
var ls:ComboBox=new ComboBox();
 
ls.addItem({label: "Sample 1", value: 1});
ls.addItem({label: "Sample 2", value: 2});
ls.addItem({label: "Sample 3", value: 3});
ls.addItem({label: "Sample 4", value: 4});
ls.addEventListener(Event.CHANGE, onpreset);
 
ls.x=66;
ls.y=203;
ls.height=25;
 
addChild(ls);
 
function onpreset(event:Event):void {
	button2.visible=false;
	button1.visible=true;
	pic1.gotoAndStop(ls.selectedItem.value);
	pic2.gotoAndStop(ls.selectedItem.value);
	pm.reset();
}

You can find more parameters in the constructor method of the class, but only the first two are needed.

No setters & getters for the main variables but they are public so change them then invoke reset/start method if you wanna play with their values.

Parameters names are quite self-explainatory about what they do but remember one thing:
3rd and 4th parameters are offsetX and offsetY which influence if the starting and the resulting images will bel overlapped in the same position or offsetted. However I needed jsut one bitmapData to be able to move pixels across the two images. So if you have the 2 pictures that are 200×200px (as in the linked previous post) and offset them of 200 on the x, the resulting bitmapdata for the pixelMorphing will be 400×200px. If you offset of 1000px on x axis and 1000px on y axis the resulting bitmapdata will be 1200×1200px. So pay attention with CPU load and memory consumption.

Leave some comment if something not clear or just want to say hello ;)

2 Comments

Actionscript 3 (as3) - Real-time voxel landscape

3D, BitmapData, Math, actionscript 3, fun, perlinNoise

What can be the natural evolution of an isometric engine? Of course a voxel engine…

It was really a lot of time I had this in mind and already did some experiment, but never finalized them.
What I’ll show you now is some first implementation. Source code is already optimized but I need to finish class public methods so I’ll not post source for now.

Let me say that these screenshot really suck, but you got to see them moving (they runs very fast).

This first sample is a bitmap based map. The class wants two bitmap, one for the height map and one for the color. Of course you can use the same twice (but obviously it looks good only with grayscale images). With my brand new Intel Quad core QX9550 I easilly reach the fps limitator of 51 (ok, ok… on the screenshot is written 29 but believe me! :-D ). I am new to multi core cpu and I am really surprised to see that now the browser vs IDE situation totally changed. Now I can do 51 fps in the browser (Opera 9.23) and 30 in the IDE… mmm strange behaviour, maybe I just need some sleep.

The file is very big cause of the low compressed 2000×2000 jpeg files. No preloader (don’t even try to ask for it) so be patient please (631 Kb) ;-)




Actionscript voxel landscape (Image map)

(move mouse to fly around.Map is bitmap based so has boundaries)

This second one is to make you write some comment like: “hey man how can you be so stupid… trying to code a fast voxel engine lots of optimization etc. and then you came up with a perlin noise based sample which simply drain half of the power”… Yeah! but is cool to have infinite landscape and test my new CPU :-D




Actionscript voxel landscape (perlinNoise)

Same but with two octaves… very blobby feeling.




Actionscript voxel landscape (weird 2 octaves perlinNoise)

Expect more about this and more new things. I am preparing a lot of funny stuff.

As usual if you like this let me now via comments and if you want to keep an eye on updates subscribe to my feed

12 Comments

Actionscript 3 - Fun with isometrics (part2 (with source))

BitmapData, Math, actionscript 3, classes, equalizer, fun

Hi there,

back again with some funny isoStuff.
Here’s an optimized and enhanced version of the previous post, and with source code explained.
It now has dynamic colors and you can choose colors and size (for hi and low values).


See it moving

Ok now some explanation:
The main trick behind this (for who didn’t noticed) is that the code simply redraw at every frame just the first line of blocks. Then simply draw() that first line into a BitmapData that scrolls of a block size… and the trick lives!

Ok, speaking about optimization… two main things:
1. Draw it without a line (just fills) and it goes 2x faster
2. Even that first line (60 pieces only) was not actually so fast…

About this second point the code involved with sine-wave and dynamic colors calculation contains some math equation, but nothing can really send your CPU @100%. The main CPU draining comes from the visual/rendering part.
One solution I implemented in this experiment (and it’s a trick can be used very often) is simply draw into a bitmap even that first line without adding to childList the vector part. With this little trick fps went from 15 to 31 =).

The second thing is simply that you dont really need to redraw every block @ every frame to achive a cool effect. You could just change its y without changing size for a poorer effect but surely faster. However remember that changing y can lead to higher fps but will not be enough if you still move a lot of vector shapes on screen. Draw everything to a bitmap is rule #1 for speed issues.
You could even use slice-9 grids to change the height of a block or use an animation build with 100 frames and simple gotoAndPlay(value) so you don’t have to draw everything programmatically.

Of course you can use this base for everything you need. Display height maps (maybe I’ll be posting a example of this), equalizers etc.

Now comes the code. First you will need the two classes involved.

The classes are not packaged and very simple. Simply extract them in the main dir or package them in some “common classes/com/oaxoa/blabla” folder
This was written very fast so no packaging, don’t expect setters/getters for every parameter or perfectly protected vars etc.

Ok you got the classes, now the main code. Just the first 30 lines are really needed. The rest is just to add and layout the sliders and colorpickers components.

import IsoField;
import com.oaxoa.components.FrameRater;
import fl.controls.ColorPicker;
import fl.controls.Slider;
 
var minsize:Number=10;
var maxsize:Number=10;
var spacing:Number=10;
var angle:Number=45;
var angleRadians:Number=angle/180*Math.PI;
var isofield:IsoField=new IsoField(1, 60, minsize, maxsize, spacing, angle, 0x00ffff, 0xff9900);
 
isofield.x=50;
isofield.y=50;
 
var bd:BitmapData=new BitmapData(800, 600, false, 0xffffff);
var bmp:Bitmap=new Bitmap(bd);
 
addChild(bmp);
addChild(isofield);
 
addEventListener(Event.ENTER_FRAME, onframe);
 
function onframe(event:Event):void {
	isofield.cycle();
	var matrix:Matrix=new Matrix();
	matrix.translate(50, 50);
	bd.draw(isofield, matrix);
	bd.scroll(spacing*Math.sin(angleRadians), -spacing*Math.cos(angleRadians));
}
 
// Main code end here. Stuff below is just to add sliders, labels and color pickers.
 
// add the frameRater
var fr:FrameRater=new FrameRater();
addChild(fr);
 
// add colorpickers
var cp1:ColorPicker=new ColorPicker();
cp1.x=20;
cp1.y=470;
cp1.selectedColor=0x00ffff;
addChild(cp1);
cp1.addEventListener(Event.CHANGE, oncp1);
 
var cp2:ColorPicker=new ColorPicker();
cp2.x=60;
cp2.y=470;
cp2.selectedColor=0xff9900;
addChild(cp2);
cp2.addEventListener(Event.CHANGE, oncp2);
 
function oncp1(event:Event):void {
	isofield.mincolor=cp1.selectedColor;
}
 
function oncp2(event:Event):void {
	isofield.maxcolor=cp2.selectedColor;
}
 
// add sliders
 
var slider1:Slider=new Slider();
slider1.minimum=4;
slider1.maximum=10;
slider1.value=10;
slider1.snapInterval=1;
slider1.liveDragging=true;
slider1.x=20;
slider1.y=510;
slider1.addEventListener(Event.CHANGE, onslider1);
addChild(slider1);
 
var slider2:Slider=new Slider();
slider2.minimum=4;
slider2.value=10;
slider2.maximum=10;
slider2.snapInterval=1;
slider2.liveDragging=true;
slider2.x=20;
slider2.y=540;
slider2.addEventListener(Event.CHANGE, onslider2);
addChild(slider2);
 
var slider3:Slider=new Slider();
slider3.minimum=-10;
slider3.value=6;
slider3.maximum=10;
slider3.snapInterval=1;
slider3.liveDragging=true;
slider3.x=20;
slider3.y=570;
slider3.addEventListener(Event.CHANGE, onslider3);
addChild(slider3);
 
var labelStr1:String="<b>Minimum size:</b> ";
var labelStr2:String="<b>Maximum size:</b> ";
var labelStr3:String="<b>Wave speed:</b> ";
 
function onslider1(event:Event):void {
	sliderLabel1.htmlText=labelStr1+String(slider1.value);
	isofield.minsize=slider1.value;
}
 
function onslider2(event:Event):void {
	sliderLabel2.htmlText=labelStr2+String(slider2.value);
	isofield.maxsize=slider2.value;
}
 
function onslider3(event:Event):void {
	sliderLabel3.htmlText=labelStr3+String(slider3.value);
	isofield.xfSpeed=slider3.value/1000;
}
 
var tf:TextFormat=new TextFormat();
tf.font="_sans";
 
var sliderLabel1:TextField=new TextField();
sliderLabel1.x=slider1.x+slider1.width+20;
sliderLabel1.y=slider1.y;
sliderLabel1.width=200;
sliderLabel1.selectable=false;
sliderLabel1.defaultTextFormat=tf;
sliderLabel1.htmlText=labelStr1+String(slider1.value);
addChild(sliderLabel1);
 
var sliderLabel2:TextField=new TextField();
sliderLabel2.x=slider2.x+slider2.width+20;
sliderLabel2.y=slider2.y;
sliderLabel2.width=200;
sliderLabel2.selectable=false;
sliderLabel2.defaultTextFormat=tf;
sliderLabel2.htmlText=labelStr2+String(slider2.value);
addChild(sliderLabel2);
 
var sliderLabel3:TextField=new TextField();
sliderLabel3.x=slider3.x+slider3.width+20;
sliderLabel3.y=slider3.y;
sliderLabel3.width=200;
sliderLabel3.selectable=false;
sliderLabel3.defaultTextFormat=tf;
sliderLabel3.htmlText=labelStr3+String(slider3.value);
addChild(sliderLabel3);

As usual I do like comments, so if you enjoy this (or not and want your five minutes back) -gogogo- leave one (and subscribe to my feed!) :D

4 Comments

Actionscript 3 - Fun with isometrics (part 1)

actionscript 3, fun, morphing, simulation

Hi there,

I was just wandering around on some flash blogs when I found this post on bit-101 that reminded me of an old fetish of mine: isometric representations!

So I just wrote this demo… The best result is achived when staring at it for a couple of minutes cause it changes conformation very quickly and displays a lot of different patterns.

No source code here, just a quick post after a while, but I wil be on the subject again (with source code).

View sample #1 - View sample #2

Leave a comment if you like it. Cheers

5 Comments

APE - Actionscript Physics Engine - Test 1

APE, Math, Physics, actionscript 3, fun, simulation

Hi there, I started today playing with APE - Actionscript Physics Engine (Alpha 0.45) and it’s really cool stuff.

My intention would be creating a physical based little funny game, but I need to start with some simple experiments so why not post’em here…

There are issues I still don’t understand so don’t know if are bugs or simply I should read APIs deeper. One thing I cannot realize is why if I change runtime the height or width properties of a RectangleParticle or the radius property of a CircleParticle, collisions are calculated correctly upon the new values, but cannot really manage to force a correct repaint with the new dimensions.
In the code that follows I have trhee rotating RectangleParticles with the alwaysRepaint parameter set to true and I can correctly see the rectangles rotating, but if I change size runtime nothing changes (except the collision). Neither calling the particle.paint() method at everyframe, which is an alternative to alwaysRepaint method, works.

However everything else is really supercool and moving a lot of self colliding particles @60fps!

Here we go with my first test:


ape_test11.gif
Run the test

Simply set the import folders for external classes in your Flash or Flex project pointing to the folder where you downloaded APE and copy these few lines of code to the first frame in you timeline.

import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.filters.GlowFilter;
import org.cove.ape.*;
import com.oaxoa.components.FrameRater;
 
stage.frameRate = 60;
addEventListener(Event.ENTER_FRAME, run);
 
APEngine.init(1/4);
APEngine.container = this;
 
// masslessforce aka gravity
APEngine.addMasslessForce(new Vector(0,4));
 
var defaultGroup:Group = new Group();
defaultGroup.collideInternal = true;
 
// instance the three rectangles
var rp:RectangleParticle = new RectangleParticle(150,250,250,25,0,true);
var rp2:RectangleParticle = new RectangleParticle(400,250,250,25,0,true);
var rp3:RectangleParticle = new RectangleParticle(275,450,150,20,0,true);
 
// set some graphical style
rp.setFill(0x666666);
rp2.setFill(0x666666);
rp3.setFill(0x666666);
rp.setLine(0, 0xff0000, 0);
rp2.setLine(0, 0xff0000, 0);
rp3.setLine(0, 0xff0000, 0);
 
// fixed particles are not always repainted for speed issues, but these ones will
// be rotating, so we need to force the repaint at every frame
rp.alwaysRepaint=true;
rp2.alwaysRepaint=true;
rp3.alwaysRepaint=true;
 
// add rectangles
defaultGroup.addParticle(rp);
defaultGroup.addParticle(rp2);
defaultGroup.addParticle(rp3);
 
APEngine.addGroup(defaultGroup);
 
var a:Number=0;
var r:Number=15;
function run(evt:Event):void {
	// check for removal if the particle is offscreen
	for each (var p:AbstractParticle in defaultGroup.particles) {
		if (p.py>550+r || p.px<-r || p.px>550+r) {
			defaultGroup.removeParticle(p);
		}
	}
 
	// some rotating fun
	a+=4;
	var arad:Number=a/180*Math.PI;
	rp.angle=Math.cos(arad)*45;
	rp2.angle=-Math.cos(arad)*45;
	rp3.angle=a*2;
 
	// do the simulation and the render step
	APEngine.step();
	APEngine.paint();
 
}
// timer to add particles
var timer:Timer=new Timer(50);
timer.addEventListener(TimerEvent.TIMER, ontimer);
timer.start();
function ontimer(event:TimerEvent):void {
	var cp:CircleParticle = new CircleParticle(Math.random()*350+100,-20,Math.random()*r+1);
	cp.setFill(0x444444*Math.random()+0xbbbbbb);
	cp.setLine(0, 0xff0000, 0);
	defaultGroup.addParticle(cp);
}
 
// add the frame rater to check how smooth it is running
var fr:FrameRater=new FrameRater(0xcccccc);
addChild(fr);

Byez