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

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.

This entry was posted in Graphics, Quiz and tagged , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

19 Comments

  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 :D

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

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

    nicely done Jamin

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

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

  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 :D

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

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

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

    that’s hilarious :D

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

    addChild(bmp);
    }
    drawStairs(null,10);

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

    ha… that’s awesome :D

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

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

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

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

    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 !

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

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

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*