【问题标题】:Creating a checkered board with pieces in HTML5 canvas在 HTML5 画布中创建带有棋子的棋盘
【发布时间】:2018-07-27 00:27:26
【问题描述】:

我正在用 HTML 和 JS 中的画布进行试验,并尝试绘制一个棋盘画布,每边有 16 个棋子。我能够创建国际象棋棋盘,但我一直坚持如何专门绘制每侧的 16 个棋子(这些棋子可以只是圆形,所以只有一侧有 16 个红色圆圈,一侧有 16 个蓝色圆圈)。

我不知道为什么这让我如此困惑,我知道您可能只需要一个 for 循环在特定坐标处停止,但要在每一侧获得不同颜色的块以及在某个部分停止给我带来麻烦.

我希望帮助我了解将棋子放在我的代码中的哪个位置。如果您可以修改我当前的代码并将 cmets 放在您进行更改的位置,以便我可以看到,那将非常感激。

这是我目前制作的跳棋板:

<canvas id="canvas" width="300" height="300"></canvas>

function drawCheckeredBackground(can, nRow, nCol) {
    var ctx = can.getContext("2d");
    var w = can.width;
    var h = can.height;

    nRow = nRow || 8;    
    nCol = nCol || 8;   

    w /= nCol;            
    h /= nRow;            

    for (var i = 0; i < nRow; ++i) {
        for (var j = 0, col = nCol / 2; j < col; ++j) {
            ctx.rect(2 * j * w + (i % 2 ? 0 : w), i * h, w, h);
        }
    }

    ctx.fill();
}

var canvas = document.getElementById("canvas");

drawCheckeredBackground(canvas);

这就是我想要的棋盘的样子,每边有 16 个棋子。我只是很快在油漆中制作了这个例子: https://i.imgur.com/BvbxzSZ.png

【问题讨论】:

    标签: javascript jquery html canvas


    【解决方案1】:

    这可能不是最漂亮的解决方案,但它应该提供一些基本的想法,并且可以使用您的 step 变量想法进行调整。很有可能,您需要在获取实际部件时进行重构。

    const drawBoard = (ctx, step) => {
      for (let i = 0; i < 8; i++) {
        for (let j = 0; j < 8; j++) {
          ctx.fillStyle = (i + j) & 1 ? "black" : "white";
          ctx.fillRect(j * step, i * step, step, step);
        }
      }
    };
    
    const drawPieces = (ctx, y, color, step) => {
      ctx.fillStyle = color;
      
      for (let i = y; i < 2 * step + y; i += step) {
        for (let j = step / 2; j < 8 * step; j += step) {
          ctx.beginPath();
          ctx.arc(j, i - step / 2, step / 3, 0, Math.PI * 2);
          ctx.fill();
        }
      }
    };
    
    const step = 60;
    const c = document.createElement("canvas");
    c.height = c.width = step * 8;
    document.body.appendChild(c);
    const ctx = c.getContext("2d");
    
    drawBoard(ctx, step);
    drawPieces(ctx, step, "red", step);
    drawPieces(ctx, step * 7, "blue", step);

    Play with it at JSFiddle.

    【讨论】:

    • ctx.arc 可用于在同一路径中绘制多个圆。最好将 beginPath 放在循环之前并在完成后填充。
    • 感谢您的提示。预先计算内循环计算也会更好,我敢肯定,数学可以简化。不过,我并不是要编写超高性能的代码。这只是一个简单的草图来演示该方法。画板例程被调用了两次,所以现在开始优化似乎还为时过早。
    【解决方案2】:

    <!doctype html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<style>
    			body {
    				background-color: black;
    			}
    			
    			canvas {
    				display: block;
    				margin: auto;
    				border: solid 1px white;
    				border-radius: 10px;
    			}
    		</style>
    	</head>
    	
    	<body>
    		<canvas id="canvas"></canvas>
    		<script type="application/javascript">
    		
    		// Self executing function
    		void function() {
    		
    			// Turn on strict js rules for this scope
    			"use strict";
    			
    			// Classes
    			
    			function ChessPeice(x,y,radius) {
    				this.x = x || 0.0;
    				this.y = y || 0.0;
    				this.radius = radius || 1.0;
    			}
    			
    			ChessPeice.prototype = {
    				tick: function() {
    				
    				},
    				
    				render: function(ctx) {
    					ctx.moveTo(
    						this.x + this.radius,
    						this.y
    					);
    				
    					ctx.arc(
    						this.x,
    						this.y,
    						this.radius,
    						0.0,
    						2.0 * Math.PI,
    						false
    					);
    				}
    			};
    			
    			// Constructor, when called with 'new' creates an object and puts it
    			// in the 'this' variable, new properties can then be added to it.
    			function Chessboard(width,height) {
    				this.boardWidth = width || 1;
    				this.boardHeight = height || 1;
    				this.tileWidth = this.boardWidth / this.H_TILE_COUNT;
    				this.tileHeight = this.boardHeight / this.V_TILE_COUNT;
    				this.whitePeices = [];
    				this.blackPeices = [];
    				
    				for (var y = 0; y < 2; ++y) {
    					for (var x = 0; x < this.V_TILE_COUNT; ++x) {
    						this.whitePeices.push(
    							new ChessPeice(
    								x * this.tileWidth + (this.tileWidth >> 1),
    								y * this.tileHeight + (this.tileHeight >> 1),
    								this.CHESS_PIECE_RADIUS
    							)
    						);
    						
    						this.blackPeices.push(
    							new ChessPeice(
    								x * this.tileWidth + (this.tileWidth >> 1),
    								(this.V_TILE_COUNT - 1 - y) * this.tileHeight + (this.tileHeight >> 1),
    								this.CHESS_PIECE_RADIUS
    							)
    						);
    					}
    				}
    			}
    			
    			// Prototype object, all objects created with 'new Chessboard()'
    			// will share the properties in the prototype, use it for constant values
    			// & class functions
    			Chessboard.prototype = {
    				H_TILE_COUNT: 8, // How many white & black tiles per axis?
    				V_TILE_COUNT: 8,
    				
    				EDGE_THICKNESS: 10.0,
    				EDGE_COLOUR: "#603E11FF",
    				WHITE_TILE_COLOUR: "#BBBBBBFF",
    				BLACK_TILE_COLOUR: "#555555FF",
    				
    				CHESS_PIECE_RADIUS: 5.0,
    				WHITE_PIECE_COLOUR: "#EEEEEEFF",
    				BLACK_PIECE_COLOUR: "#333333FF",
    				
    				tick: function() {
    					// You can add game logic here
    				},
    				
    				render: function(ctx) {
    					// Draw white tiles
    					var x = 0;
    					var y = 0;
    					var totalTiles = this.H_TILE_COUNT * this.V_TILE_COUNT;
    					
    					ctx.fillStyle = this.WHITE_TILE_COLOUR;
    					ctx.beginPath();
    					
    					for (var i = 0; i < totalTiles; ++i) {
    						ctx.rect(
    							x * this.tileWidth,
    							y * this.tileHeight,
    							this.tileWidth,
    							this.tileHeight
    						);
    						
    						x += 2;
    						
    						if (x >= this.H_TILE_COUNT) {
    							x = this.H_TILE_COUNT - x + 1;
    							++y;
    						}
    					}
    					
    					ctx.fill();
    					
    					// Draw black tiles
    					x = 1;
    					y = 0;
    					
    					ctx.fillStyle = this.BLACK_TILE_COLOUR;
    					ctx.beginPath();
    					
    					for (var i = 0; i < totalTiles; ++i) {
    						ctx.rect(
    							x * this.tileWidth,
    							y * this.tileHeight,
    							this.tileWidth,
    							this.tileHeight
    						);
    						
    						x += 2;
    						
    						if (x >= this.H_TILE_COUNT) {
    							x = this.H_TILE_COUNT - x + 1;
    							++y;
    						}
    					}
    					
    					ctx.fill();
    					
    					// Draw edge
    					ctx.lineWidth = this.EDGE_THICKNESS >> 1;
    					ctx.strokeStyle = this.EDGE_COLOUR;
    					ctx.beginPath();
    					ctx.rect(0,0,this.boardWidth,this.boardHeight);
    					ctx.stroke();
    					
    					// Draw white pieces
    					ctx.lineWidth = 2;
    					ctx.strokeStyle = "#000000FF";
    					ctx.fillStyle = this.WHITE_PIECE_COLOUR;
    					ctx.beginPath();
    					
    					for (var i = 0; i < this.whitePeices.length; ++i) {
    						this.whitePeices[i].render(ctx);
    					}
    					
    					ctx.fill();
    					ctx.stroke();
    					
    					// Draw black pieces
    					ctx.lineWidth = 2;
    					ctx.strokeStyle = "#000000FF";
    					ctx.fillStyle = this.BLACK_PIECE_COLOUR;
    					ctx.beginPath();
    					
    					for (var i = 0; i < this.blackPeices.length; ++i) {
    						this.blackPeices[i].render(ctx);
    					}
    					
    					ctx.fill();
    					ctx.stroke();
    				}
    			};
    			
    			// Variables
    			var canvasWidth = 160;
    			var canvasHeight = 160;
    			var canvas = null;
    			var ctx = null;
    			var board = null;
    			
    			// Game Loop
    			function loop() {
    				// Tick (Update game logic)
    				board.tick();
    				
    				// Render
    				ctx.fillStyle = "gray";
    				ctx.fillRect(0,0,canvasWidth,canvasHeight);
    				
    				board.render(ctx);
    				
    				//
    				requestAnimationFrame(loop);
    			}
    			
    			// Entry Point (Runs when the page loads)
    			onload = function() {
    				canvas = document.getElementById("canvas");
    				canvas.width = canvasWidth;
    				canvas.height = canvasHeight;
    				
    				ctx = canvas.getContext("2d");
    				board = new Chessboard(canvasWidth,canvasHeight);
    				
    				loop();
    			}
    		
    		}();
    		
    		</script>
    	</body>
    </html>

    【讨论】:

      猜你喜欢
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 2011-12-23
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多