2016-04-25 2 views
3

В принципе, я хочу нарисовать a slime from Dragon Quest (это похоже на каплю воды). Я сделал следующее, но я хотел бы знать, есть ли лучший способ сделать это. Может быть, использовать кривые Безье или что-то в этом роде?Рисование слизи из Dragon Quest

Update:

Я на самом деле есть все, чтобы выглядеть, как я хочу, для градиента для пятен свечения (белый)

Slime.prototype.drawEye = function(x,y,w,h) 
{ 

    ctx.save(); 
    ctx.lineWidth = 3; 

    ctx.beginPath(); 
    var c = []; 
    c.push("sclera"); 
    //c.push("iris"); 
    c.push("pupil"); 
    var wScale = [1,2.2,3]; 
    var hScale = [1,2,1.3]; 
    for (var i = 0; i < c.length; i++) 
    { 
     w /= wScale[i]; 
     h /= hScale[i]; 
     ctx.beginPath(); 
     ctx.ellipse(x,y,w,h,0,degreesToRadians(360),false); 
     ctx.fillStyle = this.colors[c[i]]; 
     ctx.fill(); 
     ctx.stroke(); 
    } 
    ctx.restore(); 

} 
Slime.prototype.drawMouth = function() 
{ 
    ctx.save(); 
    ctx.beginPath(); 

    var x = this.x+this.w/30; 
    var y = this.y+this.h/8; 
    var w = this.w; 
    var h = this.h/8; 
    var start = [x-w/3,y]; 
    var end = [x+w/8,y+h/5]; 

    // mouth 
    bezierCurve(start,[x-w/3.3,y+h*2.3],[x+w/8,y+h*1.8],end); 
    bezierCurveTo([x-w/10,y+h*0.6],[x-w/6,y+h*0.6],start); 
    ctx.lineCap = "round"; 
    ctx.lineWidth = 8; 
    ctx.stroke(); 
    ctx.clip(); 
    ctx.fillStyle = this.colors["mouth"]; 
    ctx.fill(); 

    start = [x-w/3.5,y+h*1]; 
    // tongue 
    ctx.beginPath(); 
    bezierCurve(start,[x-w/5,y+h*2.5],[x+w/6.5,y+h*1.6],[x+w/9,y+h*0.75]); 
    bezierCurveTo([x+w/10,y+h/4],[x-w/5,y],start); 
    ctx.fillStyle = this.colors["tongue"]; 
    ctx.fill(); 
    //ctx.stroke(); 

    ctx.restore(); 
} 
Slime.prototype.drawHealthBar = function() 
{ 
    ctx.beginPath(); 
    ctx.rect(this.x-this.w,this.y+this.h/2+30,this.w*2*this.health/this.maxHealth,20); 
    ctx.fillStyle = "#00ff00"; 
    ctx.fill(); 
    ctx.beginPath(); 
    ctx.rect(this.x-this.w+(this.w*2*this.health/this.maxHealth),this.y+this.h/2+30,(this.maxHealth-this.health)/this.maxHealth*this.w*2,20); 
    ctx.fillStyle = "#ff0000"; 
    ctx.fill(); 
    ctx.beginPath(); 
    ctx.rect(this.x-this.w,this.y+this.h/2+30,this.w*2,20); 
    ctx.strokeStyle = "#000000"; 
    ctx.stroke(); 
} 
Slime.prototype.drawBody = function() 
{ 
    ctx.save(); 
    ctx.fillStyle = this.colors["body"]; 
    ctx.beginPath(); 
    var x = this.x; 
    var y = this.y+this.h*0.4; 
    var w = this.w/2; 
    var h = this.h; 
    var left = [x-w*0.97,this.y+h/11]; 
    var bottom = [x,this.y+h*0.495]; 
    var right = [x+w*0.97,this.y+h/15]; 
    var top = [x+this.w/30,this.y-h/2+this.topOffset]; 
    bezierCurve(left,[x-w,y+h/10],[x-w/7,y+h/12],bottom); 
    bezierCurveTo([x+w*0.8,y+h/10],[x+w*1.05,y-h/7],right); 
    y = this.y - (y - this.y); 
    bezierCurveTo([x+w*0.75,y+h/15],[x+w*0.2,y+h/4.5],top); 
    bezierCurveTo([x-w*0.2,y+h/5],[x-w*0.8,y+h/10],left); 
    ctx.lineWidth = 3; 
    ctx.fill(); 
    ctx.strokeStyle = this.colors["bodyOutline"]; 
    ctx.stroke(); 
    ctx.clip(); 
    ctx.shadowColor = "#000033"; 
    ctx.shadowBlur = 40; 
    ctx.shadowOffsetX = ctx.shadowBlur/4; 
    ctx.shadowOffsetY = ctx.shadowOffsetX*-0.8; 
    ctx.lineWidth = 4; 
    for (var i = 0; i < 7; i++) 
    { 
     if (i%2==0) 
     { 
      ctx.shadowColor = "#000033"; 
     } 
     else 
     { 
      ctx.shadowColor = "rgba(0,0,80,0.5)"; 
     } 
     ctx.stroke(); 
    } 
    ctx.restore(); 
} 
Slime.prototype.drawGlow = function(x,y,r1,r2) 
{ 
    ctx.save(); 
    var g = ctx.createRadialGradient(x,y,r1,x,y,r2); 
    g.addColorStop(0.0,"#ffffff"); 
    g.addColorStop(1.0,this.colors["body"]); 
    ctx.beginPath(); 
    ctx.arc(x,y,r2,0,degreesToRadians(360),false); 
    ctx.fillStyle = g; 
    ctx.fill(); 
    ctx.restore(); 
} 
Slime.prototype.draw = function() 
{ 
    ctx.lineWidth = 2; 
    this.drawBody(); 
    this.drawMouth(); 
    var w = this.w/10; 
    var h = this.h/10; 
    var x = this.x; 
    var y = this.y; 
    this.drawEye(x-this.w/4.5,y-h/2.5,w,h); 
    this.drawEye(this.x+this.w/13,y-h/10,w,h); 
    this.drawGlow(this.x-this.w/2.5,this.y+this.h/12,this.w/50,this.w/16); 
    this.drawGlow(this.x+this.w/2*0.7,this.y+this.h/10,this.w/50,this.w/16); 
} 

Конец обновления

кроме Slime

ответ

2

Да, вы можете нарисовать контур капли, используя только 4 кубические кривые Безье.

Вот концепция доказательства правильности использования только 4 кривых C-Bez:

enter image description here

Почему! Зачем! Почему! .......... Мне понравилось создавать Слизь?

enter image description here

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 
var cw=canvas.width; 
 
var ch=canvas.height; 
 

 
drawDropletMan(20,20,'rgb(63,187,255)'); 
 
drawDropletMan(255,55,'rgb(255,180,155)'); 
 

 
function drawDropletMan(x,y,fill){ 
 
    ctx.translate(x,y); 
 
    drawBody(fill); 
 
    circularGlow(158,111,3,18,fill); 
 
    circularGlow(32,107,3,18,fill); 
 
    eye(65,87,17,10); 
 
    eye(120,90,17,10); 
 
    mouth(33,130); 
 
    ctx.translate(-x,-y); 
 
} 
 
// 
 
function drawBody(fillcolor){ 
 
    ctx.save(); 
 
    ctx.beginPath(); 
 
    ctx.moveTo(109,0); 
 
    ctx.bezierCurveTo(111,64,199,35,198,123); 
 
    ctx.bezierCurveTo(199,139,183,192,99,190); 
 
    ctx.bezierCurveTo(66,193,-4,167,1,110); 
 
    ctx.bezierCurveTo(9,47,97,45,109,1); 
 
    ctx.fillStyle=fillcolor; 
 
    ctx.fill(); 
 
    ctx.strokeStyle='black'; 
 
    ctx.lineWidth=2; 
 
    ctx.stroke(); 
 
    ctx.clip(); 
 
    ctx.shadowColor='black'; 
 
    ctx.shadowBlur=15; 
 
    ctx.lineWidth=1; 
 
    for(var i=0;i<8;i++){ctx.stroke();} 
 
    ctx.restore(); 
 
} 
 
// 
 
function circularGlow(x,y,r1,r2,fillcolor){ 
 
    var g=ctx.createRadialGradient(x,y,r1,x,y,r2); 
 
    g.addColorStop(0.00,'white'); 
 
    g.addColorStop(1.00,fillcolor); 
 
    ctx.beginPath(); 
 
    ctx.arc(x,y,r2,0,Math.PI*2); 
 
    ctx.fillStyle=g; 
 
    ctx.fill(); 
 
} 
 
// 
 
function eye(x,y,r1,r2){ 
 
    ctx.beginPath(); 
 
    ctx.arc(x,y,r1,0,Math.PI*2); 
 
    ctx.fillStyle='white'; 
 
    ctx.strokeStyle='black'; 
 
    ctx.fill(); 
 
    ctx.lineWidth=2; 
 
    ctx.stroke(); 
 
    // 
 
    ctx.beginPath(); 
 
    ctx.arc(x,y,r2,0,Math.PI*2); 
 
    ctx.fillStyle='black'; 
 
    ctx.fill(); 
 
} 
 
// 
 
function mouth(){ 
 
    ctx.save(); 
 
    ctx.translate(5,5); 
 
    ctx.beginPath(); 
 
    ctx.moveTo(44,120); 
 
    ctx.bezierCurveTo(56,136,112,132,128,123); 
 
    ctx.bezierCurveTo(138,123,143,123,132,138); 
 
    ctx.bezierCurveTo(113,165,49,169,39,127); 
 
    ctx.bezierCurveTo(41,128,32,122,44,120); 
 
    ctx.closePath(); 
 
    ctx.fillStyle='black'; 
 
    ctx.fill(); 
 
    ctx.clip(); 
 
    ctx.beginPath(); 
 
    ctx.arc(90,200,56,0,Math.PI*2); 
 
    ctx.fillStyle='coral'; 
 
    ctx.fill(); 
 
    ctx.restore(); 
 
}
body{ background-color: ivory; } 
 
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=500 height=300></canvas>

+1

Спасибо за ваш вклад и помочь! Я рад, что вам понравилось! –