简体   繁体   中英

How Do I Create Random Rows For HTML5 Canvas On a Grid?

I am trying to draw a random grid on an HTML5 canvas element, Ive been able to achieve the grid just fine but I am not able to randomly generate the tiles onto the grid. They just end up repeating the same row over and over or staggered repetitions. I have included an image of my result with this current code here : https://drive.google.com/open?id=1xK37qhP3TeDeAG32oPxeG7dMq6kcsxm3

    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>New Isometric Game Test With Canvas</title>
    <link rel="stylesheet" href="css/style.css" />
        <script src="js/jquery-2.1.1.js"></script>
        <script>

var IsometricMap = new Object();

      IsometricMap.tiles = [
        // "images/dirt.png",
        "images/dirtHigh.png",      // 0
        "images/grass.png",         // 1
        "images/water.png",         // 2
        "images/waterBeachCornerEast.png",  // 3
        "images/waterBeachCornerNorth.png", // 4
        "images/waterBeachCornerSouth.png", // 5
        "images/waterBeachCornerWest.png",  // 6
        "images/waterBeachEast.png",    // 7
        "images/waterBeachNorth.png",   // 8
        "images/waterBeachSouth.png",   // 9
        "images/waterBeachWest.png",    // 10
        "images/waterCornerEast.png",   // 11
        "images/waterCornerNorth.png",  // 12
        "images/waterCornerSouth.png",  // 13
        "images/waterCornerWest.png",   // 14
        "images/waterEast.png",     // 15
        "images/waterNorth.png",        // 16
        "images/waterSouth.png",        // 17
        "images/waterWest.png",     // 18
        "images/bridgeEast.png",        // 19
        "images/bridgeNorth.png",       // 20
        "images/crossroad.png",     // 21
        // "images/hillCornerEast.png",
        // "images/hillCornerNW.png",
        // "images/hillCornerSE.png",
        // "images/hillCornerWest.png",
        // "images/hillEast.png",
        // "images/hillNorth.png",
        // "images/hillRoadEast.png",
        // "images/hillRoadNorth.png",
        // "images/hillRoadSouth.png",
        // "images/hillRoadWest.png",
        // "images/hillSouth.png",
        // "images/hillWest.png",
        "images/lot.png",           // 22
        "images/lotCornerEast.png",     // 23
        "images/lotCornerNorth.png",    // 24
        "images/lotCornerSouth.png",    // 25
        "images/lotCornerWest.png",     // 26
        "images/lotEast.png",       // 27
        "images/lotExitEast.png",       // 28
        "images/lotExitNorth.png",      // 29
        "images/lotExitSouth.png",      // 30
        "images/lotExitWest.png",       // 31
        "images/lotNorth.png",      // 32
        "images/lotPark.png",       // 33
        "images/lotSouth.png",      // 34
        "images/lotWest.png",       // 35
        "images/roadCornerES.png",      // 36
        "images/roadCornerNE.png",      // 37
        "images/roadCornerNW.png",      // 38
        "images/roadCornerWS.png",      // 39
        "images/roadEast.png",      // 40
        "images/roadEndEast.png",       // 41
        "images/roadEndNorth.png",      // 42
        "images/roadEndSouth.png",      // 43
        "images/roadEndWest.png",       // 44
        "images/roadNorth.png",     // 45
        "images/roadTEast.png",     // 46
        "images/roadTNorth.png",        // 47
        "images/roadTSouth.png",        // 48
        "images/roadTWest.png"];    // 49   

var blockcount = (Math.floor(Math.random() * 5) + 1) * 2;
var bigblockcount = blockcount * blockcount; 
var columngen = new Array();
IsometricMap.map = new Array(); 



var i=0;
while(i < (bigblockcount)) { 
    var numberoftiles = IsometricMap.tiles.length;
    var terrainrandoms = (Math.floor(Math.random() * numberoftiles) + 0);   
    columngen.push(terrainrandoms); 
    i++;
}

x=0;
while (x < blockcount) {
    var chunk = columngen.slice(x, x+blockcount);
    var randomchunk = chunk[Math.floor(Math.random() * chunk.length)];
    IsometricMap.map.push(chunk);
x++;
}

alert("Line 1 = " + IsometricMap.map[0] + " Line 2 = " + IsometricMap.map[1] + " Line 3 = " + IsometricMap.map[2] + " Blockcount = " + blockcount); 


            // A simple isometric tile renderer
            var Isometric = {
              tileColumnOffset: 100, // pixels
              tileRowOffset: 50, // pixels

              originX: 0, // offset from left
              originY: 0, // offset from top

              Xtiles: 0, // Number of tiles in X-dimension
              Ytiles: 0, // Number of tiles in Y-dimension

              selectedTileX: -1,
              selectedTileY: -1,

              context: undefined,
              canvas: undefined,

              tileImages: undefined,

              showCoordinates: false,

              load: function() {
                this.tileImages = new Array();
                var loadedImages = 0;
                var totalImages = IsometricMap.tiles.length;

                // Load all the images before we run the app
                var self = this;
                for(var i = 0; i < IsometricMap.tiles.length; i++) {
                  this.tileImages[i] = new Image();
                  this.tileImages[i].onload = function() {
                    if(++loadedImages >= totalImages) {
                      self.run();
                    }
                  };
                  this.tileImages[i].src = IsometricMap.tiles[i];
                }
              },

              run: function() {
                this.canvas = $('#isocanvas');
                this.context = this.canvas[0].getContext("2d");

                this.Xtiles = IsometricMap.map.length;
                this.Ytiles = IsometricMap.map[0].length;

                var self = this;
                $(window).on('resize', function(){
                  self.updateCanvasSize();
                  self.redrawTiles();
                });




               $(window).on('mousemove', function(e) {
                 e.pageX = e.pageX - self.tileColumnOffset / 2 - self.originX;
                 e.pageY = e.pageY - self.tileRowOffset / 2 - self.originY;
                 tileX = Math.round(e.pageX / self.tileColumnOffset - e.pageY / self.tileRowOffset);
                 tileY = Math.round(e.pageX / self.tileColumnOffset + e.pageY / self.tileRowOffset);

                 self.selectedTileX = tileX;
                 self.selectedTileY = tileY;
                 self.redrawTiles();

                 // console.log(self.selectedTileX + ", " + self.selectedTileY);
               });

                $(window).on('click', function() {
                  self.showCoordinates = !self.showCoordinates;
                  self.redrawTiles();
                });

                this.updateCanvasSize();
                this.redrawTiles();
              },

              updateCanvasSize: function() {
                var width = $(window).width();
                var height = $(window).height();

                this.context.canvas.width  = width;
                this.context.canvas.height = height;

                this.originX = width / 2 - this.Xtiles * this.tileColumnOffset / 2;
                this.originY = height / 2;
              },

              redrawTiles: function() {
                this.context.canvas.width = this.context.canvas.width;

                for(var Xi = (this.Xtiles - 1); Xi >= 0; Xi--) {
                  for(var Yi = 0; Yi < this.Ytiles; Yi++) {
                    this.drawTile(Xi, Yi);
                  }
                }

                this.drawDiamond(this.selectedTileX, this.selectedTileY, 'yellow');
                if(this.showCoordinates && this.isCursorOnMap()) {
                  this.context.fillStyle = 'yellow';
                  var idx = IsometricMap.map[this.selectedTileX][this.selectedTileY];
                  this.context.font = '14pt Arial';
                  this.context.fillText(IsometricMap.tiles[idx].replace("/assets/tiles/",""), 20, 30);
                }
              },

              isCursorOnMap: function() {
                return (this.selectedTileX >= 0 && this.selectedTileX < this.Xtiles &&
                        this.selectedTileY >= 0 && this.selectedTileY < this.Ytiles);
              },

              drawTile: function(Xi, Yi) {
                var offX = Xi * this.tileColumnOffset / 2 + Yi * this.tileColumnOffset / 2 + this.originX;
                var offY = Yi * this.tileRowOffset / 2 - Xi * this.tileRowOffset / 2 + this.originY;

                var imageIndex = IsometricMap.map[Xi][Yi];
                this.context.drawImage(this.tileImages[imageIndex], offX, offY);

                if(this.showCoordinates) {
                  this.context.fillStyle = 'orange';
                  this.context.fillText(Xi + ", " + Yi, offX + this.tileColumnOffset/2 - 9, offY + this.tileRowOffset/2 + 3);
                }
              },

              drawDiamond: function(Xi, Yi, color) {
                var offX = Xi * this.tileColumnOffset / 2 + Yi * this.tileColumnOffset / 2 + this.originX;
                var offY = Yi * this.tileRowOffset / 2 - Xi * this.tileRowOffset / 2 + this.originY;

                this.drawLine(offX, offY + this.tileRowOffset / 2, offX + this.tileColumnOffset / 2, offY, color);
                this.drawLine(offX + this.tileColumnOffset / 2, offY, offX + this.tileColumnOffset, offY + this.tileRowOffset / 2, color);
                this.drawLine(offX + this.tileColumnOffset, offY + this.tileRowOffset / 2, offX + this.tileColumnOffset / 2, offY + this.tileRowOffset, color);
                this.drawLine(offX + this.tileColumnOffset / 2, offY + this.tileRowOffset, offX, offY + this.tileRowOffset / 2, color);
              },

              drawLine: function(x1, y1, x2, y2, color) {
                color = typeof color !== 'undefined' ? color : 'white';
                this.context.strokeStyle = color;
                this.context.beginPath();
                this.context.lineWidth = 1;
                this.context.moveTo(x1, y1);
                this.context.lineTo(x2, y2);
                this.context.stroke();
              },
            };


        </script>
        <script>$(function() { Isometric.load() });</script>
    </head>

    <body>

    <canvas id="isocanvas" width="1000" height="1000">
     Your browser doesn't include support for the canvas tag.
    </canvas>

    </body>
    </html>

    var IsometricMap = new Object();

      IsometricMap.tiles = [
        // "images/dirt.png",
        "images/dirtHigh.png",      // 0
        "images/grass.png",         // 1
        "images/water.png",         // 2
        "images/waterBeachCornerEast.png",  // 3
        "images/waterBeachCornerNorth.png", // 4
        "images/waterBeachCornerSouth.png", // 5
        "images/waterBeachCornerWest.png",  // 6
        "images/waterBeachEast.png",    // 7
        "images/waterBeachNorth.png",   // 8
        "images/waterBeachSouth.png",   // 9
        "images/waterBeachWest.png",    // 10
        "images/waterCornerEast.png",   // 11
        "images/waterCornerNorth.png",  // 12
        "images/waterCornerSouth.png",  // 13
        "images/waterCornerWest.png",   // 14
        "images/waterEast.png",     // 15
        "images/waterNorth.png",        // 16
        "images/waterSouth.png",        // 17
        "images/waterWest.png",     // 18
        "images/bridgeEast.png",        // 19
        "images/bridgeNorth.png",       // 20
        "images/crossroad.png",     // 21
        // "images/hillCornerEast.png",
        // "images/hillCornerNW.png",
        // "images/hillCornerSE.png",
        // "images/hillCornerWest.png",
        // "images/hillEast.png",
        // "images/hillNorth.png",
        // "images/hillRoadEast.png",
        // "images/hillRoadNorth.png",
        // "images/hillRoadSouth.png",
        // "images/hillRoadWest.png",
        // "images/hillSouth.png",
        // "images/hillWest.png",
        "images/lot.png",           // 22
        "images/lotCornerEast.png",     // 23
        "images/lotCornerNorth.png",    // 24
        "images/lotCornerSouth.png",    // 25
        "images/lotCornerWest.png",     // 26
        "images/lotEast.png",       // 27
        "images/lotExitEast.png",       // 28
        "images/lotExitNorth.png",      // 29
        "images/lotExitSouth.png",      // 30
        "images/lotExitWest.png",       // 31
        "images/lotNorth.png",      // 32
        "images/lotPark.png",       // 33
        "images/lotSouth.png",      // 34
        "images/lotWest.png",       // 35
        "images/roadCornerES.png",      // 36
        "images/roadCornerNE.png",      // 37
        "images/roadCornerNW.png",      // 38
        "images/roadCornerWS.png",      // 39
        "images/roadEast.png",      // 40
        "images/roadEndEast.png",       // 41
        "images/roadEndNorth.png",      // 42
        "images/roadEndSouth.png",      // 43
        "images/roadEndWest.png",       // 44
        "images/roadNorth.png",     // 45
        "images/roadTEast.png",     // 46
        "images/roadTNorth.png",        // 47
        "images/roadTSouth.png",        // 48
        "images/roadTWest.png"];    // 49   

var blockcount = (Math.floor(Math.random() * 5) + 1) * 2;
var bigblockcount = blockcount * blockcount; 
var columngen = new Array();
IsometricMap.map = new Array(); 



var i=0;
while(i < (bigblockcount)) { 
    var numberoftiles = IsometricMap.tiles.length;
    var terrainrandoms = (Math.floor(Math.random() * numberoftiles) + 0);   
    columngen.push(terrainrandoms); 
    i++;
}

x=0;
while (x < blockcount) {
    var chunk = columngen.slice(x, x+blockcount);
    var randomchunk = chunk[Math.floor(Math.random() * chunk.length)];
    IsometricMap.map.push(chunk);
x++;
}

alert("Line 1 = " + IsometricMap.map[0] + " Line 2 = " + IsometricMap.map[1] + " Line 3 = " + IsometricMap.map[2] + " Blockcount = " + blockcount); 


            // A simple isometric tile renderer
            var Isometric = {
              tileColumnOffset: 100, // pixels
              tileRowOffset: 50, // pixels

              originX: 0, // offset from left
              originY: 0, // offset from top

              Xtiles: 0, // Number of tiles in X-dimension
              Ytiles: 0, // Number of tiles in Y-dimension

              selectedTileX: -1,
              selectedTileY: -1,

              context: undefined,
              canvas: undefined,

              tileImages: undefined,

              showCoordinates: false,

              load: function() {
                this.tileImages = new Array();
                var loadedImages = 0;
                var totalImages = IsometricMap.tiles.length;

                // Load all the images before we run the app
                var self = this;
                for(var i = 0; i < IsometricMap.tiles.length; i++) {
                  this.tileImages[i] = new Image();
                  this.tileImages[i].onload = function() {
                    if(++loadedImages >= totalImages) {
                      self.run();
                    }
                  };
                  this.tileImages[i].src = IsometricMap.tiles[i];
                }
              },

              run: function() {
                this.canvas = $('#isocanvas');
                this.context = this.canvas[0].getContext("2d");

                this.Xtiles = IsometricMap.map.length;
                this.Ytiles = IsometricMap.map[0].length;

                var self = this;
                $(window).on('resize', function(){
                  self.updateCanvasSize();
                  self.redrawTiles();
                });




               $(window).on('mousemove', function(e) {
                 e.pageX = e.pageX - self.tileColumnOffset / 2 - self.originX;
                 e.pageY = e.pageY - self.tileRowOffset / 2 - self.originY;
                 tileX = Math.round(e.pageX / self.tileColumnOffset - e.pageY / self.tileRowOffset);
                 tileY = Math.round(e.pageX / self.tileColumnOffset + e.pageY / self.tileRowOffset);

                 self.selectedTileX = tileX;
                 self.selectedTileY = tileY;
                 self.redrawTiles();

                 // console.log(self.selectedTileX + ", " + self.selectedTileY);
               });

                $(window).on('click', function() {
                  self.showCoordinates = !self.showCoordinates;
                  self.redrawTiles();
                });

                this.updateCanvasSize();
                this.redrawTiles();
              },

              updateCanvasSize: function() {
                var width = $(window).width();
                var height = $(window).height();

                this.context.canvas.width  = width;
                this.context.canvas.height = height;

                this.originX = width / 2 - this.Xtiles * this.tileColumnOffset / 2;
                this.originY = height / 2;
              },

              redrawTiles: function() {
                this.context.canvas.width = this.context.canvas.width;

                for(var Xi = (this.Xtiles - 1); Xi >= 0; Xi--) {
                  for(var Yi = 0; Yi < this.Ytiles; Yi++) {
                    this.drawTile(Xi, Yi);
                  }
                }

                this.drawDiamond(this.selectedTileX, this.selectedTileY, 'yellow');
                if(this.showCoordinates && this.isCursorOnMap()) {
                  this.context.fillStyle = 'yellow';
                  var idx = IsometricMap.map[this.selectedTileX][this.selectedTileY];
                  this.context.font = '14pt Arial';
                  this.context.fillText(IsometricMap.tiles[idx].replace("/assets/tiles/",""), 20, 30);
                }
              },

              isCursorOnMap: function() {
                return (this.selectedTileX >= 0 && this.selectedTileX < this.Xtiles &&
                        this.selectedTileY >= 0 && this.selectedTileY < this.Ytiles);
              },

              drawTile: function(Xi, Yi) {
                var offX = Xi * this.tileColumnOffset / 2 + Yi * this.tileColumnOffset / 2 + this.originX;
                var offY = Yi * this.tileRowOffset / 2 - Xi * this.tileRowOffset / 2 + this.originY;

                var imageIndex = IsometricMap.map[Xi][Yi];
                this.context.drawImage(this.tileImages[imageIndex], offX, offY);

                if(this.showCoordinates) {
                  this.context.fillStyle = 'orange';
                  this.context.fillText(Xi + ", " + Yi, offX + this.tileColumnOffset/2 - 9, offY + this.tileRowOffset/2 + 3);
                }
              },

              drawDiamond: function(Xi, Yi, color) {
                var offX = Xi * this.tileColumnOffset / 2 + Yi * this.tileColumnOffset / 2 + this.originX;
                var offY = Yi * this.tileRowOffset / 2 - Xi * this.tileRowOffset / 2 + this.originY;

                this.drawLine(offX, offY + this.tileRowOffset / 2, offX + this.tileColumnOffset / 2, offY, color);
                this.drawLine(offX + this.tileColumnOffset / 2, offY, offX + this.tileColumnOffset, offY + this.tileRowOffset / 2, color);
                this.drawLine(offX + this.tileColumnOffset, offY + this.tileRowOffset / 2, offX + this.tileColumnOffset / 2, offY + this.tileRowOffset, color);
                this.drawLine(offX + this.tileColumnOffset / 2, offY + this.tileRowOffset, offX, offY + this.tileRowOffset / 2, color);
              },

              drawLine: function(x1, y1, x2, y2, color) {
                color = typeof color !== 'undefined' ? color : 'white';
                this.context.strokeStyle = color;
                this.context.beginPath();
                this.context.lineWidth = 1;
                this.context.moveTo(x1, y1);
                this.context.lineTo(x2, y2);
                this.context.stroke();
              },
            };

I want truly randomized tiles. Does this have something to do with me needing to nest one of these arrays? Please help. Thanks in advance.

I think you're getting it too complex. Here is a simple way to get a grid of random indices.


1D array

 const width=5, depth=5, ntiles=10; let map = Array(width*depth).fill().map(_=>Math.floor(Math.random()*ntiles)) console.log(map) 


2D array

 const width=5, depth=5, ntiles=10; let generate_row = _=> Array(depth).fill().map(_=>Math.floor(Math.random()*ntiles)) let map = Array(width).fill().map(generate_row) console.log(map) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM