1
\$\begingroup\$

An additional question regarding this : previous topic. Thankyou to @Blindman67 for all the help thus far.

The goal is to have a large pixelmap broken up into sections determined by user define-able variables. Within each of these sections I need to draw arrows that represent the flow through the section starting with the first tile and ending at the last.

User @Blindman67 helped out tremendously by getting me some code that works perfectly on the pixelmap as a whole, but doesn't allow me to break it up into user define-able sections.

jsFiddle for latest pixelmap script with broken up section flow.

/** CreateImage.js begin **/
//wall size
var wallx = 500;
var wally = 500;

//output size
var outputx = 250;
var outputy = 250;

// tile size
var tilex = 25;
var tiley = 25;

// vars for output limits evenly divisible by tile size    
var LCDoutputx = outputx;
var LCDoutputy = outputy;

//round down LCDoutputy to the next coordinate evenly divisible by a tile's y value.
if ((outputy % tiley) != 0){
    LCDoutputy = (Math.floor(outputy/tiley))*tiley;   
}
//round down LCDoutputx to the next coordinate evenly divisible by a tile's x value.
if ((outputx % tilex) != 0){
    LCDoutputx = (Math.floor(outputx/tilex))*tilex;   
}

// creates a blank image with 2d context
var createImage=function(w,h){var i=document.createElement("canvas");i.width=w;i.height=h;i.ctx=i.getContext("2d");return i;}

/** CreateImage.js end **/
var canvas = createImage(wallx, wally);
var ctx = canvas.ctx;
document.body.appendChild(canvas);

// constants for directions
const flows = {
    none : -1,
    right : 0,
    down : 1,
    left : 2,
    up : 3,
    end : 4,  // for end of flow
    start : 5,  // for start
    dirs : [[1,0],[0,1],[-1,0],[0,-1]], // x,y step for each direction
    // Maps are used to workout the flow laoutputy
    // x,y is the starting position with 0 as top or left and 1 as bottom or right
    // directions has an array for each direction. the first item is the travel
    // direction and the second item is the max number of steps befor turning
    map1 : { // top left start rigth, down, left, down 
        x : 0, y : 0,
        directions : [[0,Infinity],[1,1],[2,Infinity],[1,1]],
    },
    map2 : {  // top right start, left, down, right, down 
        x : 1, y : 0,
        directions : [[2,Infinity],[1,1],[0,Infinity],[1,1]],
    },
    map3 : {
        x : 0, y : 1, // bottom left start, up, right, down, right
        directions : [[3,Infinity],[0,1],[1,Infinity],[0,1]],
    },
    map4 : {
        x : 1, y : 1, // bottom right start, up, left, down, left
        directions : [[3,Infinity],[2,1],[1,Infinity],[2,1]],
    },
}
// colours
const col1 = "#FA6" //orng
const col2 = "#6AF" //l. blue
const col3 = "#03CEA4" //green
const col4 = "#FB4D3D" //red
const col5 = "#345995" //d.blue
var colA;
var colB;
// array of tiles
var tiles = [];
// number columns and rows
var rows;
var cols;
// number of outputs
var outputsW = Math.ceil(wallx/outputx);
var outputsH = Math.ceil(wally/outputy);
// number of cols/rows in each output
var outCols = Math.floor(outputx/tilex);
var outRows = Math.floor(outputy/tiley);
// reset or setup tiles
function reset(tiles){
    tiles.length = 0;
    rows = Math.floor(canvas.height / tiley);
    cols = Math.floor(canvas.width / tilex);
    for(var y = 0; y <= canvas.height-tiley; y+= tiley){ //changed < to <= 
        for(var x = 0; x <= canvas.width-tilex; x += tilex){ //changed < to <=
            var d = (Math.floor(y / LCDoutputy) % 2 + Math.floor(x / LCDoutputx) % 2) % 2; //added LCDoutputt for output background color to work. Was outputy. The entire map's output background colors were off by one row, showing an extra row beyond what the limits should be.
            //console.log("Y : "+y+" divided by Out Y Limit : "+outputy);
            //console.log("Y result : "+Math.floor(y/outputy) % 2);
            //console.log("X : "+x+" divided by Out X Limit : "+outputx);
            //console.log("X result : "+Math.floor(x/outputx) % 2);
            //console.log(d);
            var c = (Math.floor(y / tiley) % 2 + Math.floor(x / tilex) % 2) % 2;
            tiles.push({
                x,y,tilex,tiley,
                flow : flows.none,
                output : d ? (colA = col3, colB = col4) : (colA = col1, colB = col2),
                col : c ? colA : colB,

            })
        }    
    }
}
// Creates flow map for tiles. flow maps are in flows as flow.map1, map2... etc
function createFlow(tiles,flowMap){
    var i = 0;
    var prevtile, tile;
    var count = 0;
    var x = flowMap.x * (cols-1);
    var y = flowMap.y * (rows-1);
    var moving = true;
    while(moving){
        var ind = x + y * cols;
        prevtile = tile;
        var tile = tiles[ind];
        var dir = flowMap.directions[i % flowMap.directions.length];
        var nx = x + flows.dirs[dir[0]][0];
        var ny = y + flows.dirs[dir[0]][1];
        //console.log(count);
        //console.log("I : "+i+" X , Y : "+x+" , "+y);
        //console.log("IND : "+ind+" NX , NY : "+nx+" , "+ny);
        //console.log("DIR : "+dir);
        //console.log("Columns : "+cols+" Out Columns : "+outCols);
        //console.log("Rows : "+rows+" Out Rows : "+outRows);
        if(nx >= cols || nx >= outCols || nx < 0 || ny >= rows || ny >= outRows || ny < 0 || count >= dir[1]){//determine what tiles stop changing nx/ny/dir
            i += 1;
            dir = flowMap.directions[i % flowMap.directions.length];
            nx = x + flows.dirs[dir[0]][0];
            ny = y + flows.dirs[dir[0]][1];
            if(nx >= cols || nx >= outCols || nx < 0 || ny >= rows || ny >= outRows || ny < 0){//determine where flow stops
                tile.flow = flows.end;
                break;
            }
            count = 0;
        }
        if(tile === undefined){
            prevtile.flow = flows.end;
            break;
        }
        if(prevtile === undefined){
            tile.flow = flows.start;   
        }else{
            tile.flow = dir[0];
        }
        count += 1;
        x = nx;
        y = ny;
    }
}

// draws the tiles
function draw(tiles){
    function arrow(tile){
        if(tile.flow === flows.none){
            return;
        }
        if (tilex<tiley) {
            var step = tile.tilex * (1/4);
        } else {
            var step = tile.tiley * (1/4);   
        }
        //var step = tile.tilex * (1/4);
        var x = tile.x + tile.tilex -step;
        var y = tile.y + step
        ctx.strokeStyle = "white";
        ctx.lineWidth = 2;
        ctx.beginPath();
        if(tile.flow === flows.end){
            ctx.setTransform(1,0,0,1,x,y);
            ctx.moveTo(-step / 2, -step / 2);
            ctx.lineTo(step / 2, step / 2);
            ctx.moveTo(step / 2, -step / 2);
            ctx.lineTo(-step / 2, step / 2);

            ctx.stroke();
            ctx.setTransform(1,0,0,1,0,0);
            return;
        }else if(tile.flow === flows.start){
            ctx.setTransform(1,0,0,1,x,y);
            ctx.moveTo(step / 2, 0);
            ctx.arc(0,0, step / 2,0,Math.PI * 2);
            ctx.stroke();
            ctx.setTransform(1,0,0,1,0,0);
            return;
        }else if(tile.flow === flows.right){
            ctx.setTransform(1,0,0,1,x,y);
        } else if(tile.flow === flows.left){
            ctx.setTransform(-1,0,0,1,x,y);
        } else if(tile.flow === flows.down){
            ctx.setTransform(0,1,1,0,x,y);
        } else if(tile.flow === flows.up){
            ctx.setTransform(0,-1,1,0,x,y);
            //ctx.setTransform(0,1,-1,0,0,0);
        }
        ctx.moveTo(-step / 2, 0);
        ctx.lineTo(step / 2, 0);
        ctx.moveTo(step / 4, -step / 4);
        ctx.lineTo(step / 2, 0);
        ctx.lineTo(step / 4, step / 4);
        ctx.stroke();
        ctx.setTransform(1,0,0,1,0,0);
    }
    ctx.clearRect(0,0,canvas.width,canvas.height)
    var i = 0;
    while(i < tiles.length){
        var l = tiles[i++];
        ctx.fillStyle = l.col
        ctx.fillRect(l.x,l.y,l.tilex,l.tiley);
        arrow(l);
    }

}

var flowMaps = [flows.map1,flows.map2,flows.map3,flows.map4];
var currentFlow = 4;
function drawAll(){
    reset(tiles);
    draw(tiles);
    setTimeout(setFlow,1000);
}
function setFlow(){
    createFlow(tiles,flowMaps[(currentFlow++) % flowMaps.length]);
    draw(tiles);
    setTimeout(drawAll,4000); //comment out this line to stop map change cycle
}
drawAll();

Lines 130 and 135 seem to be where the restraints are set on when the flows end is determined but I'm having trouble figuring out how to stop the flow within a section of the map and then continue on again at the next section that doesn't have its flow drawn yet.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.