簡體   English   中英

畫布2D fillStyle有時不更新顏色

[英]Canvas 2D fillStyle doesn't updates the color sometimes

我正在使用MDN2D突破教程來學習畫布,並且有一個練習:嘗試在每次擊球時將球的顏色更改為隨機顏色。

在拉球之前,我先檢查球是否在牆內。 如果它碰到球,首先我會生成一個隨機的十六進制顏色,然后用該顏色繪制球。

但它有時僅適用。 我已經記錄了ctx對象的fillStyle屬性,但有時它不會將值更改為新顏色。

 /* Reference to Canvas */ var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); /* Start Ball Position */ let x = canvas.width / 2; let y = canvas.height - 30; /* Move Ball */ let dx = 2; let dy = -2; /* Ball Dimensions */ let ballRadius = 10; /* Ball Color */ let ballColor = "#0095DD"; /* Draw Ball */ function drawBall() { ctx.beginPath(); ctx.arc(x, y, ballRadius, 0, Math.PI * 2); ctx.fillStyle = ballColor; ctx.fill(); ctx.closePath(); x += dx; y += dy; } /* Update Canvas */ function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); bouncing(); drawBall(); } /** * If the ball goes outside the boundaries, * change the direction to the opposite */ function bouncing() { if(x + dx < ballRadius || x + dx > canvas.width - ballRadius) { dx = -dx; randomColor(); } if(y + dy < ballRadius || y + dy > canvas.height - ballRadius) { dy = -dy; randomColor(); } } /* Change the ball color to a random hex value */ function randomColor() { const hexColor = ['#']; const letters = ['A', 'B', 'C', 'D', 'E', 'F']; for(let digit = 0; digit < 6; digit++) { let value = Math.floor(Math.random() * 16); if(value > 9) { value = letters[value - 9]; } hexColor.push(value); } ballColor = hexColor.join(''); } setInterval(draw, 10); 
 html { box-sizing: border-box; } *, *::before, *::after { box-sizing: inherit; padding: 0; margin: 0; } canvas { background: #eee; display: block; margin: 0 auto; } 
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>2D breakout game</title> <link rel="stylesheet" href="style.css"> </head> <body> <canvas id="myCanvas" width="480" height="170"></canvas> <script src="script.js"></script> </body> </html> 

問題出在行value = letters[value - 9]; 這應該是value = letters[value - 10];

這是因為您想要的映射是:

10 -> A (letters[0])
11 -> B (letters[1])
12 -> C (letters[2])
13 -> D (letters[3])
14 -> E (letters[4])
15 -> F (letters[5])

因此,您需要減去10而不是9。

您的代碼運行良好,每次球反彈時都會調用函數randomColor ,但是在顏色生成邏輯中,您可以獲得無效值,例如##A#AB ,可以輕松地將* 16更改為* 15並解決了該問題。

但也請注意,有時您的隨機顏色非常接近前一種顏色,因此看起來好像並沒有改變,但實際上確實發生了改變,這是我相信大多數時候都可以看到的顏色。

您可以想出一個“智能隨機”功能,該功能可以記住最近的2或3種顏色,並防止下一種與這些顏色相似,有關如何比較顏色的更多詳細信息,請參見此問題的答案:
如何比較兩種顏色的相似度/差異


在這里,我將您的randomColor的邏輯更改為包括色差邏輯,現在下一個顏色將真正顯示與前一個顏色的對比

 var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.font = "Bold 30px courier new"; let x = y = 40 let dx = dy = 2; let ballRadius = 40; let ballColor = "#0095DD"; /* Change the ball color to a random hex value */ function randomColor() { const hexColor = ['#']; const letters = ['A', 'B', 'C', 'D', 'E', 'F']; for(let digit = 0; digit < 6; digit++) { let value = Math.floor(Math.random() * 15); if(value > 9) { value = letters[value - 9]; } hexColor.push(value); } if (colorDif(ballColor, hexColor.join('')) > 50) ballColor = hexColor.join(''); else randomColor(); } function colorDif(color1, color2) { if (color1 == color2) return 0; function squaredDelta(v1, v2) { return Math.pow(v1 - v2, 2); } function hexToRgb(hex) { var result = /^#?([af\\d]{2})([af\\d]{2})([af\\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; } var sum = 0; var c1 = hexToRgb(color1); var c2 = hexToRgb(color2); sum += squaredDelta(c1.r, c2.r); sum += squaredDelta(c1.g, c2.g); sum += squaredDelta(c1.b, c2.b); var conversionIndex = 19.5075; return Math.sqrt(sum / conversionIndex); }; function drawBall() { ctx.beginPath(); ctx.fillText(ballColor,10,50); ctx.fillStyle = ballColor; ctx.arc(x, y, ballRadius, 0, Math.PI * 2); ctx.fill(); x += dx; y += dy; } function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); bouncing(); drawBall(); } function bouncing() { if(x + dx < ballRadius || x + dx > canvas.width - ballRadius) { dx = -dx; randomColor(); } if(y + dy < ballRadius || y + dy > canvas.height - ballRadius) { dy = -dy; randomColor(); } } setInterval(draw, 10); 
 *, *::before, *::after {margin: 0; } 
 <canvas id="myCanvas" width="480" height="170"></canvas> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM