如何在网格上为HTML5画布创建随机行?

时间:2019-06-12 02:58:22

标签: javascript arrays html5-canvas

我正在尝试在HTML5画布元素上绘制随机网格,我已经能够很好地实现网格,但是我无法在网格上随机生成图块。他们只是一遍又一遍或交错重复地重复同一行。我在此处的当前代码中包含了我的结果的图片: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();
              },
            };

我想要真正随机的图块。这与我需要嵌套这些数组之一有关吗?请帮忙。预先感谢。

1 个答案:

答案 0 :(得分:1)

我认为您变得太复杂了。这是获取随机索引网格的简单方法。


一维数组

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


2D阵列

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)