Today’s quiz is not multiple choice. Instead, your task is to write a function that draws stairs that look like this:
Your function should have the following arguments:
drawStairs(graphics, stairNum); // you may include additional arguments for size, depth etc..
Feel free to post your solution in the comments.
I’ll post my solution for this in the comments tomorrow. There is also another multiple choice quiz in the pipeline for tomorrow…
BONUS: Try to use as few Graphics class method calls as possible.
You can see my solutions here.
19 Comments
function drawStairs( g:Graphics, stairNum:uint = 10 ):void
{
//builds the stairs rectangle
var w:uint = 25;
var h:uint = 50;
var offset:uint = 0;
//origins
var c0:Point = new Point( 0, 0 );
var c1:Point = new Point( 0, -h );
var c2:Point = new Point( w, -h);
var c3:Point = new Point( w, 0);
//deformation matrices
var m0:Matrix = new Matrix( 1, 0, -.666666, 1, offset, offset );
var m1:Matrix = new Matrix( 0, 1, -.666666, 1, offset + w, offset );
//dest points
var p0:Point, p1:Point, p2:Point, p3:Point, p4:Point, p5:Point;
p0 = m0.deltaTransformPoint( c0 );
p1 = m0.deltaTransformPoint( c1 );
p2 = m0.deltaTransformPoint( c2 );
p3 = m0.deltaTransformPoint( c3 );
p4 = m1.deltaTransformPoint( c2 ).add( new Point( w, 0 ) );
p5 = m1.deltaTransformPoint( c3 ).add( new Point( w, 0 ) );
//starts drawing
g.lineStyle( 3 );
g.moveTo( offset + ( stairNum * w ), offset + ( stairNum * w ));
g.lineTo( offset, offset + ( stairNum * w ) );
g.lineTo( offset, offset );
while( stairNum– )
{
g.moveTo( offset + p2.x, offset + p2.y );
g.lineTo( offset + p3.x, offset + p3.y );
g.lineTo( offset + p0.x, offset + p0.y );
g.lineTo( offset + p1.x, offset + p1.y );
g.lineTo( offset + p2.x, offset + p2.y );
g.lineTo( offset + p4.x, offset + p4.y );
g.lineTo( offset + p5.x, offset + p5.y );
g.lineTo( offset + p3.x, offset + p3.y );
offset += w;
}
}
this does the thing but it is pretty verbose and rather slow…
I’m eagerly waiting for your solution
nice work… thanks for posting
Here’s my solution. Don’t think it’s the best, but it works.
//Adds a sprite, draws stairs, and centers the sprite
var sprite:Sprite = new Sprite();
addChild(sprite);
drawStairs(sprite.graphics, 10, 30, 30, 25, 3);
sprite.x = stage.stageWidth/2 - sprite.width/2;
sprite.y = stage.stageHeight/2 - sprite.height/2;
function drawStairs(graphics, stairNum, width=25, height=25, depth=25, thickness=1){
graphics.lineStyle(thickness);
drawBase(graphics, width*stairNum, height*stairNum);
for (var i:int = 0; i < stairNum; i++){
drawStair(graphics, i, width, height, depth);
}
}
function drawBase(graphics, totalWidth, totalHeight){
graphics.lineTo(0, totalHeight);
graphics.lineTo(totalWidth, totalHeight);
}
function drawStair(graphics, currentStair, width, height, depth){
var x = currentStair * width;
var y = currentStair * height;
var endx = x + width;
var endy = y-Math.sqrt(Math.abs((depth * depth)-(width * width)));
graphics.moveTo(endx, y);
graphics.lineTo(x, y);
graphics.lineTo(endx, endy);
graphics.lineTo(endx + width, endy);
graphics.lineTo(endx, y);
graphics.lineTo(endx, y + height);
graphics.lineTo(endx + width, endy + height);
graphics.lineTo(endx + width, endy);
}
nicely done Jamin
wow 4 comments… I’m slow
package {
import flash.display.Graphics;
import flash.display.Sprite;
public class Foo extends Sprite{
public function Foo() {
var s:Sprite = new Sprite; s.x = s.y = 50;
addChild (s); drawStairs (s. graphics, 9);
}
public function drawStairs(g:Graphics, n:int):void {
g.lineStyle (2);
var i:int, s:Number = 10;
// going down stairs
for (i = 0; i -1; i–) {
g.moveTo (s * (1 + i), s * i);
g.lineTo (s * i, s * i);
}
// jump down
g.lineTo (0, s * n);
g.lineTo (s * n, s * n);
g.lineTo (s * (n + 1), s * (n - 1));
// going up stairs again
for (i = n - 1; i > -1; i–) {
g.lineTo (s * (2 + i), s * (i - 1));
g.moveTo (s * (1 + i), s * (i - 1));
}
}
}
}
aww my code got screwed up, or at least it looks so in “awaiting moderation” preview. re-posted to http://wonderfl.net/code/5236b8b5f1fff575f657bfd0832be95914111fb5
sorry about the messed up code… I really should fix that in wordpress… thanks for posting it on wondeful
following the rules literally and being very cheeky…
function drawStairs( graphics, stairNum ) {
var imageLoader:Loader = new Loader();
imageLoader.contentLoaderInfo.addEventListener( Event.COMPLETE, function(e:Event) { addChild( e.target.loader.content ) } );
imageLoader.load( new URLRequest( ‘http://actionsnippet.com/wp-content/stairs.gif’ ) );
}
that’s hilarious
I cheated:
function drawStairs(g:Graphics=null, num:int=0):void {
var stairSize:uint = 22;
var len:int = num*2;
var off:int = stairSize/2;
var skew:Number = Math.tan((-45/180)*Math.PI);
var bmpd:BitmapData = new BitmapData(stairSize*(num+1)+1,stairSize*(num+1)+1,true,0×00000000);
var bmp:Bitmap = new Bitmap(bmpd);
var box:Shape = new Shape();
with(box.graphics) {
lineStyle(2,0×000000,1,true,LineScaleMode.NONE);
drawRect(0,0,stairSize,stairSize);
endFill();
}
for(var i:int=0; i<len; i++) {
var m:Matrix;
if(i%2==0) {
m = new Matrix(1,0,skew,1,(off*i)+stairSize,(off*i)+1);
} else {
m = new Matrix(1,skew,0,1,(off*i)+off,((off*i)+off)+1);
}
bmpd.draw(box,m);
}
bmpd.fillRect(new Rectangle(0,stairSize,2,bmpd.height),0xFF000000);
bmpd.fillRect(new Rectangle(0,bmpd.height-2,bmpd.width-stairSize,2),0xFF000000);
addChild(bmp);
}
drawStairs(null,10);
ha… that’s awesome
This question was fun, I love your quiz series.
…and errr, I didn’t use the graphics parameter
private function drawStairs(numSteps:int,stepWidth:int,stepDepth:int):Sprite
{
var stairs:Sprite = new Sprite();
var stepsTop:Shape = new Shape();
stepsTop.graphics.lineStyle(4, 0×000000);
stepsTop.transform.matrix = new Matrix(1, 0, -1, 1, 0, 0);
stairs.addChild(stepsTop);
var stepsSide:Shape = new Shape();
stepsSide.graphics.lineStyle(4, 0×000000);
stepsSide.transform.matrix = new Matrix(1, -1, 0, 1, 0, 0);
stairs.addChild(stepsSide);
for (var i:int = 0; i < numSteps; i++)
{
stepsTop.graphics.drawRect(stepWidth * 2 * i, -stepDepth + stepWidth * i, stepWidth, stepDepth);
stepsSide.graphics.drawRect(stepWidth + stepWidth * i, stepWidth + stepWidth * 2 * i, stepDepth, stepWidth);
}
stairs.graphics.lineStyle(3,0×000000);
stairs.graphics.lineTo(0, stepWidth * numSteps);
stairs.graphics.lineTo(stepWidth*numSteps, stepWidth*numSteps);
return stairs;
}
var stairs:Sprite=new Sprite();
stairs.x=100;
stairs.y=100
addChild(stairs)
var delSkewX:Number
var delSkewY:Number
function drawStairPattern($stepCount,$graphic,$wid,$hei,$depth,$count){
$graphic.lineStyle(1,0×000000,1)
var initX=$wid*($stepCount-1);
var initY=$hei*($stepCount-1);
///////////////////////////////////////////////////////
$graphic.moveTo(initX,initY);
$graphic.lineTo(initX+$wid,initY);
$graphic.lineTo(initX+$wid,initY+$hei);
$graphic.lineTo(initX+$wid+delSkewX,initY+$hei-delSkewY);
$graphic.lineTo(initX+$wid+delSkewX,initY-delSkewY);
$graphic.lineTo(initX+delSkewX,initY-delSkewY);
$graphic.lineTo(initX,initY);
$graphic.moveTo(initX+$wid,initY);
$graphic.lineTo(initX+$wid+delSkewX,initY-delSkewY);
$graphic.moveTo(0,initY);
$graphic.lineTo(0,initY+$hei);
$graphic.moveTo(initX,$count*$hei);
$graphic.lineTo(initX+$wid,$count*$hei);
}
function drawStairs($graphic,$count){
var angle=35;
var wid=30;
var hei=20;
var depth=100;
var angleFactor=angle*Math.PI/180;
delSkewX=depth*Math.cos(angleFactor);
delSkewY=depth*Math.sin(angleFactor);
for(var i:int=1;i<=$count;i++){
drawStairPattern(i,$graphic,wid,hei,depth,$count)
}
}
drawStairs(stairs.graphics,10);
but i used more graphics class methods……….:( . If i post next version i will try to reduce. Lex idea very good.
Aha, you fool ! I have the ultimate solution :D.
1 line, 0 call to graphics, the exact stairs showed in example. I’m so good (and so funny ahaha).
1- Add stairs.gif to your library
2- Link it as a Stair class
function drawStairs(graphics, stairNum)
{
addChild(new Bitmap(new Stairs(0, 0)));
}
And you don’t even need parameters… If you want more stairs, change source image !
Thanks to everyone who posted their code, I didn’t expect this many responses…
@joseph smith heh
//////////3D stairs
var stairs:Sprite=new Sprite();addChild(stairs);
stairs.x=stage.stageWidth*.5;stairs.y=300;stairs.z=300
stairs.rotationY=45;
function drawStairs($gra,$count) {
var wid=30; var hei=30; var depth=100;
var front:Shape=new Shape();stairs.addChild(front);var back:Shape=new Shape();stairs.addChild(back);var behind:Shape=new Shape();stairs.addChild(behind)
front.graphics.beginFill(0×00ffff,.2);back.graphics.beginFill(0×00ffff,.2);behind.graphics.beginFill(0×000000,.2)
for (var i:int=0; i<$count; i++) {
var shp:Shape=new Shape();stairs.addChild(shp);
shp.graphics.beginFill(i%2?0xff6600:0xff0000,1);shp.graphics.drawRect(0,-depth,wid,depth);
var floorI=Math.floor(i*.5)
shp.rotationX=-90;shp.rotationZ=90*(i%2);
shp.x=wid*(floorI+i%2);shp.y=hei*(floorI);
front.graphics.lineTo(shp.x+wid*(1-i%2),shp.y+hei*(i%2));
back.graphics.lineTo(shp.x+wid*(1-i%2),shp.y+hei*(i%2));
}
back.z=depth
back.graphics.lineTo(0,$count*hei/2);back.graphics.lineTo(0,0);
front.graphics.lineTo(0,$count*hei/2);front.graphics.lineTo(0,0);
behind.graphics.drawRect(0,0,depth,$count*hei/2);
behind.rotationY=-90
}
drawStairs(stairs.graphics,8);
this.addEventListener(Event.ENTER_FRAME,function(){stairs.rotationY+=1});
Very nice c.Senthil Kumaran
My try
private function drawStairs(graphics : Graphics, stairNum : uint, stepWidth : Number, stepHeight : Number, depth : Number) : void
{
var index : uint = 0;
var commands : Vector. = new Vector.(100);
var coords : Vector. = new Vector.(200);
function lineTo(px : Number, py : Number) : void
{
commands[index] = 2;
coords[2 * index] = px; //x
coords[(2 * index) + 1] = py;
index++;
}
function moveTo(px : Number, py : Number) : void
{
commands[index] = 1;
coords[2*index] = px; //x
coords[(2*index)+1] = py;
index++;
}
var angle : Number = 45 * (180 / Math.PI);
graphics.lineStyle(2);
var sx : Number;
var sy : Number;
var bp : Point;
for (var i : int = 0;i < stairNum; i++)
{
sx = i * stepWidth;
sy = i * stepHeight;
bp = new Point(sx + (Math.cos(angle) * depth), sy + (Math.sin(angle) * depth));
lineTo(sx, sy);
lineTo(sx + stepWidth, sy);
lineTo(bp.x + stepWidth, bp.y);
lineTo(bp.x, bp.y);
lineTo(sx, sy);
moveTo(sx + stepWidth, sy);
lineTo(sx + stepWidth, sy + stepHeight);
moveTo(bp.x + stepWidth, bp.y);
lineTo(bp.x + stepWidth, bp.y + stepHeight);
lineTo(sx + stepWidth, sy + stepHeight);
}
moveTo(bp.x + stepWidth, bp.y + stepHeight);
lineTo((Math.cos(angle) * depth), (i * stepHeight) + (Math.sin(angle) * depth));
lineTo((Math.cos(angle) * depth), (Math.sin(angle) * depth));
graphics.drawPath(commands, coords);
}