# AS Quiz #8

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..
```

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.

1. Posted January 20, 2010 at 10:56 am | Permalink

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

2. Posted January 20, 2010 at 11:01 am | Permalink

nice work… thanks for posting

3. Jamin
Posted January 20, 2010 at 11:21 am | Permalink

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();

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);
}

4. Posted January 20, 2010 at 11:40 am | Permalink

nicely done Jamin

5. Posted January 20, 2010 at 12:22 pm | Permalink

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));
}
}
}
}

6. Posted January 20, 2010 at 12:31 pm | Permalink

aww my code got screwed up, or at least it looks so in “awaiting moderation” preview. re-posted to http://wonderfl.net/code/5236b8b5f1fff575f657bfd0832be95914111fb5

7. Posted January 20, 2010 at 12:44 pm | Permalink

sorry about the messed up code… I really should fix that in wordpress… thanks for posting it on wondeful

8. Posted January 20, 2010 at 3:12 pm | Permalink

following the rules literally and being very cheeky…

function drawStairs( graphics, stairNum ) {
}

9. Posted January 20, 2010 at 6:38 pm | Permalink

that’s hilarious

10. Posted January 20, 2010 at 7:09 pm | Permalink

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);

}
drawStairs(null,10);

11. Posted January 20, 2010 at 7:31 pm | Permalink

ha… that’s awesome

12. Posted January 21, 2010 at 1:26 am | Permalink

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);

var stepsSide:Shape = new Shape();
stepsSide.graphics.lineStyle(4, 0×000000);
stepsSide.transform.matrix = new Matrix(1, -1, 0, 1, 0, 0);

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;
}

13. Posted January 21, 2010 at 2:17 am | Permalink

var stairs:Sprite=new Sprite();
stairs.x=100;
stairs.y=100
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);

14. Posted January 21, 2010 at 2:26 am | Permalink

but i used more graphics class methods……….:( . If i post next version i will try to reduce. Lex idea very good.

15. Joseph Smith
Posted January 21, 2010 at 2:46 am | Permalink

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).

2- Link it as a Stair class

function drawStairs(graphics, stairNum)
{
}

And you don’t even need parameters… If you want more stairs, change source image !

16. Posted January 21, 2010 at 9:48 am | Permalink

Thanks to everyone who posted their code, I didn’t expect this many responses…

@joseph smith heh

17. Posted January 23, 2010 at 1:00 am | Permalink

//////////3D 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;
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++) {
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);

18. Posted January 23, 2010 at 9:04 am | Permalink

Very nice c.Senthil Kumaran

19. Altschuler
Posted January 23, 2010 at 1:50 pm | Permalink

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);
}