Search code examples
javascriptcanvassvgdrawing2d-games

How to clone/generalize a canvas drawing


I am working on a JavaScript game assignement, just tried to play with canvas a little. My task is laser game with laser-sources, mirrors and the goal object.

I've just made an ugly hard coded example:

'use strict';

function $(id) {
    return document.getElementById(id);
}

function draw() {
    let canvas = $('canvas');
    if(canvas.getContext) {
        let ctx = canvas.getContext("2d");
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'hsla(265, 18%, 26%, 0,80)';

        ctx.beginPath();
        ctx.moveTo(10,10);
        ctx.lineTo(10,60);
        ctx.moveTo(10,65);
        ctx.lineTo(10,115);
        ctx.moveTo(10,115);
        ctx.lineTo(60,115);
        ctx.moveTo(65,115);
        ctx.lineTo(115,115);
        ctx.moveTo(115,115);
        ctx.lineTo(115,65);
        ctx.moveTo(115,60);
        ctx.lineTo(115,10);
        ctx.moveTo(115,10);
        ctx.lineTo(65,10);
        ctx.moveTo(60,10);
        ctx.lineTo(10,10);          
        ctx.stroke();
    }
}

draw();  

https://jsfiddle.net/h9664oz4/

My question is: What solution would you suggest, so I can make an N*N table with rectangles like this (I needed the gap, so the lazer would travel through them).

This is the conception

I'll need to drop the elements inside the rectangles, but I want to have 2 gaps each side for the laser-path, not on the middle. This is just for clarification.

To be clear, I do not want a ready solution, I want to learn. Only would like some guidance where to move on. Would you suggest to dig into SVG instead? Are there some JS pattern conventions for these 2D games? Would you recommend to use classes for cleaner code architecture?

I'm a newbie with all of this.


Solution

  • Below is an SVG example using your 'rectangles', that are an SVG path element. Create a path to be cloned and place it in an SVG defs element.

    <!DOCTYPE HTML>
    <html>
    <head>
      <title>Cloned Paths</title>
    </head>
    
    <body onload=clonePaths()>
    <div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;'>
    <svg id="mySVG" width="400" height="400">
    <defs id=myDefs />
    </svg>
    </div>
    <script>
     var NS="http://www.w3.org/2000/svg"
    //---onload---
    function clonePaths()
    {
        //---create path for cloning---
        var myPath=document.createElementNS(NS,"path")
        myPath.id="pathClone"
        myPath.setAttribute("stroke-width",2)
        myPath.setAttribute("stroke","black")
        myPath.setAttribute("fill","none")
        var d="M10,10 L10,60 M10,65 L10,115 M10,115 L60,115 M65,115 L115,115 M115,115 L115,65 M115,60 L115,10 M115,10 L65,10 M60,10 L10,10"
        myPath.setAttribute("d",d)
        myDefs.appendChild(myPath)
    
        //---add clones---
        var pathClone=document.getElementById("pathClone")
    
        var path1=pathClone.cloneNode(true)
        path1.setAttribute("transform","translate(40,40)")
        mySVG.appendChild(path1)
    
        var path2=pathClone.cloneNode(true)
        path2.setAttribute("transform","translate(40,160)")
        mySVG.appendChild(path2)
    
        var path3=pathClone.cloneNode(true)
        path3.setAttribute("transform","translate(40,280)")
        mySVG.appendChild(path3)
    
    }
    </script>
    </body>
    
    </html>