• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

222
Vistas
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 3 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

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 3 years ago · Juan Pablo Isaza Denunciar

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 3 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda