Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

266
Views
Use el lienzo para dibujar una línea segmentada en forma de píldora, dibuje una línea gruesa con esquinas redondeadas

Estoy trabajando en un juego de serpientes en JavaScript y el marco Phaser3 , y quiero dibujar una línea en forma de pastilla para usar en la serpiente. Así que quiero dibujar segmentos de línea redondeados llenos de un color (verde) y delineados con otro color (negro). No es una línea recta, sino varios segmentos de línea conectados. Todos están conectados en ángulo recto, es decir, 0, 90, 180 o 270 grados.

Vea la imagen simulada a continuación.

ingrese la descripción de la imagen aquí

Aquí está mi código para dibujar una línea, hay una matriz con las ubicaciones de la cuadrícula de las posiciones de los segmentos de línea:

 var TILE_SIZE = 32; var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); // points of each snake segment snake_segs = [ [9, 11], [10, 11], [10, 12], [11, 12], [11, 13], [12, 13], [12, 12] ]; // set line color ctx.strokeStyle = "#FFFF00"; ctx.beginPath(); // draw all line segments for (var i = 0; i < snake_segs.length-1; i++) { var xpos1 = snake_segs[i][0] * TILE_SIZE; var ypos1 = snake_segs[i][1] * TILE_SIZE; var xpos2 = snake_segs[i+1][0] * TILE_SIZE; var ypos2 = snake_segs[i+1][1] * TILE_SIZE; ctx.moveTo(xpos1, ypos1); ctx.lineTo(xpos2, ypos2); } ctx.stroke();

¿Cómo convertir esto en una línea redondeada en forma de píldora?

¿Cuál es el mejor enfoque para hacer esto? Esto es más difícil de lo que inicialmente pensé. ¿Existe un algoritmo para dibujar un contorno en forma de píldora? ¿O hay una forma inteligente de usar rectángulos redondeados que se superponen? ¿O es mejor dibujar el contorno en el sentido de las agujas del reloj? Pero entonces, ¿cómo encuentras la forma de ese contorno?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Bueno, solo usando Phaser, usaría el objeto de graphics Phaser, para una solución rápida y fácil . Es un poco engorroso, pero funciona.

Manifestación:
(para optimizar todo el dibujo [reducir uno for - loop], uno podría agregar un objeto gráfico adicional, y así uno podría dibujar todo en un for - loop, pero no quería hacer una demostración demasiado compleja)

 document.body.style = 'margin:0;'; var config = { type: Phaser.AUTO, width: 536, height: 183, scene: { create, update }, banner: false }; let foregroundGraphics; let backgroundGraphics; let snake_segs = [ [1,1], [2,1], [3,1], [3,2], [3,3], [4,3], [5,3]]; let length_seg = 20; function create () { backgroundGraphics = this.add.graphics(); foregroundGraphics = this.add.graphics(); } function update(){ drawSnake(0x00a000, 0xffffff, 3); } function drawSnake(fgColor, bgColor, padding){ foregroundGraphics.clear(); backgroundGraphics.clear(); drawCorners(fgColor, bgColor, padding); drawSegments(fgColor, bgColor, padding); } function drawCorners(fgColor, bgColor, padding){ foregroundGraphics.lineStyle(length_seg/4, fgColor); backgroundGraphics.lineStyle((length_seg + padding * 2)/4, bgColor); snake_segs.forEach( point => { backgroundGraphics.strokeCircle(point[0] * length_seg, point[1] * length_seg, (length_seg + padding * 2)/8); foregroundGraphics.strokeCircle(point[0] * length_seg, point[1] * length_seg, length_seg/8); }); } function drawSegments(fgColor, bgColor, padding){ backgroundGraphics.beginPath(); foregroundGraphics.beginPath(); backgroundGraphics.lineStyle((length_seg + padding * 2)/2, bgColor); foregroundGraphics.lineStyle(length_seg /2, fgColor); for(let idx = 0; idx < snake_segs.length; idx++){ let point = snake_segs[idx]; if(idx==0){ backgroundGraphics.moveTo(point[0] * length_seg, point[1] * length_seg); foregroundGraphics.moveTo(point[0] * length_seg, point[1] * length_seg); }else { backgroundGraphics.lineTo(point[0] * length_seg, point[1] * length_seg); foregroundGraphics.lineTo(point[0] * length_seg, point[1] * length_seg); } } backgroundGraphics.strokePath(); foregroundGraphics.strokePath(); } new Phaser.Game(config);
 <script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>

Descargo de responsabilidad: podría haber una mejor manera de resolver esto, pero esta fue la primera que se me ocurrió.

(Personalmente, intentaría adaptar este ejemplo a mis necesidades, ya que me gusta experimentar, y hasta ahora nunca tuve la oportunidad de usar las funciones de seguimiento y rutas en Phaser. Pero actualmente no estoy seguro, si estas funciones, podrían ser utilizado para resolver esta tarea)

about 4 years ago · Juan Pablo Isaza Report

0

Puede hacer esto muy fácilmente dibujando primero la serpiente usando su color de contorno con un grosor de línea de, por ejemplo, 18 píxeles y luego volviendo a dibujar la misma serpiente con su color de cuerpo y un grosor de línea más pequeño de, digamos, 15 píxeles.

Desafortunadamente, esto daría como resultado una serpiente de forma sólida con esquinas afiladas de 90°. Afortunadamente, CanvasRenderingContext2D tiene una propiedad adicional llamada lineCap que controla el aspecto de los extremos de las líneas. Si configura esto en 'round' , tiene su serpiente en forma de píldora.

Aquí hay un ejemplo:

 var TILE_SIZE = 32; var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); snake_segs = [ [9, 11], [10, 11], [10, 12], [11, 12], [11, 13], [12, 13], [12, 12] ]; ctx.fillStyle = "#00a000"; ctx.fillRect(0, 0, c.width, c.height) ctx.lineCap = "round"; function drawSnake(color, thickness) { ctx.beginPath(); ctx.lineWidth = thickness; ctx.strokeStyle = color; for (var i = 0; i < snake_segs.length - 1; i++) { var xpos1 = snake_segs[i][0] * TILE_SIZE; var ypos1 = snake_segs[i][1] * TILE_SIZE; var xpos2 = snake_segs[i + 1][0] * TILE_SIZE; var ypos2 = snake_segs[i + 1][1] * TILE_SIZE; ctx.moveTo(xpos1, ypos1); ctx.lineTo(xpos2, ypos2); } ctx.moveTo(xpos2, ypos2); ctx.closePath(); ctx.stroke(); } drawSnake("#ffff00", 18); drawSnake("#00c000", 15);
 <canvas id="myCanvas" width="500" height="500"> </canvas>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!