我正在制作一张电子贺卡,其中五彩纸屑和烟花从屏幕底部飞起来。两者的逻辑几乎相同:
我为烟花和五彩纸屑制作一个空数组,然后用对象填充它们,使用我的GetRandom(混合,最大)函数创建每个具有随机值的数据:
//fill confetti object array
for (i = 0; i < NUM_CONFETTI; i++) {
ConfettiArray.push(new Confetti(GetRandom(0,canvas.width), GetRandom(-200,-10), GetRandom(10,30), GetRandom(10,30), colorChoices[GetRandom(0,NUM_COLORS)], GetRandom(0,2*Math.PI),GetRandom(50,80)));
}
//fill firework object array
for (i = 0; i < NUM_FIREWORKS; i++) {
FireworkArray.push(new Firework(GetRandom(0,canvas.width), canvas.height, GetRandom(4,20), colorChoices[GetRandom(0,NUM_COLORS)], GetRandom(30,100), GetRandom(-10,10), GetRandom(50,200)));
}
然后以特定方式绘制和更新它们,每个方法首先将context.fillStyle和.strokeStyle设置为当前对象的颜色值:
//confetti.draw
Draw: function(x, y, width, height, color, rotationAngle) {
context.translate(x,y)
context.rotate(rotationAngle)
context.strokeStyle = color;
context.fillStyle = color;
context.beginPath();
context.rect(0, 0, width, height);
context.fill();
context.closePath();
context.resetTransform();
},
//firework.draw
Draw: function(x, y, lineWidth, color, speedY, swayX, blastRadius) {
context.fillStyle = color;
context.strokeStyle = color;
context.moveTo(x,y);
context.lineTo(x-swayX,y-speedY);
context.stroke();
},
然后他们每个都更新:
//confetti.update
Update: function(modifier) {
this.y = this.y + (this.fallSpeed * modifier);
if (this.y > canvas.height) {this.x = GetRandom(0,canvas.width);this.y = GetRandom(-100,0);}
},
//firework.update
Update: function(modifier) {
this.x = this.x - this.swayX;
this.y = this.y - this.speedY;
if (this.y < -10) {this.x = GetRandom(0,canvas.width);this.y = canvas.height;this.speedY = GetRandom(30,100);this.swayX = GetRandom(-10,10)}
},
我一遍又一遍地搜索代码,我似乎无法理解为什么五彩纸屑都有随机大小,角度,堕落和颜色,而且烟花都有随机的swayX和speedY值但是所有相同的颜色。如果有人想要完整运行它,那么完整的代码如下:
//james gossling multimedia for web design spring 2018
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d');
var GetRandom = function(min, max) {
//set mins and maxes for ball speed to change angle slightly after ball reset
min = min;
max = max;
return Math.floor(Math.random() * (max - min + 1) + min);
};
//game classes go here
var Background = function(context,color) {
this.context = context;
this.color = color;
};
Background.prototype = {
DrawBackground: function() {
//for testing
//console.log('here')
context.strokeStyle = this.color;
context.fillStyle = this.color;
context.beginPath();
context.rect(0,0,canvas.width,canvas.height);
context.stroke(); // invoke stroke
context.fill(); // invoke fill
context.closePath();
},
};
Confetti = function(x, y, width, height, color, rotationAngle, fallSpeed) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
this.rotationAngle = rotationAngle;
this.fallSpeed = fallSpeed;
};
Confetti.prototype = {
Draw: function(x, y, width, height, color, rotationAngle) {
context.translate(x,y)
context.rotate(rotationAngle)
context.strokeStyle = color;
context.fillStyle = color;
context.beginPath();
context.rect(0, 0, width, height);
context.fill();
context.closePath();
context.resetTransform();
},
GetX: function() {
return this.x;
},
GetY: function() {
return this.y;
},
GetWidth: function() {
return this.width;
},
GetHeight: function() {
return this.height;
},
GetColor: function() {
return this.color;
},
GetRotationAngle: function() {
return this.rotationAngle;
},
GetFallSpeed: function() {
return this.fallSpeed;
},
Update: function(modifier) {
this.y = this.y + (this.fallSpeed * modifier);
if (this.y > canvas.height) {this.x = GetRandom(0,canvas.width);this.y = GetRandom(-100,0);}
},
};
var DrawConfetti = function() {
for (i = 0; i < NUM_CONFETTI; i++) {
ConfettiArray[i].Draw(ConfettiArray[i].GetX(),ConfettiArray[i].GetY(),ConfettiArray[i].GetWidth(),ConfettiArray[i].GetHeight(),ConfettiArray[i].GetColor(),ConfettiArray[i].GetRotationAngle());
}
}
var UpdateConfetti = function(modifier) {
for (i = 0; i < NUM_CONFETTI; i++) {
ConfettiArray[i].Update(modifier);
}
};
Firework = function(x, y, lineWidth, color, speedY, swayX, blastRadius) {
this.x = x;
this.y = y;
this.lineWidth = lineWidth;
this.color = color;
this.speedY = speedY;
this.swayX = swayX;
//this.rotationAngle = rotationAngle;
this.blastRadius = blastRadius;
};
Firework.prototype = {
Draw: function(x, y, lineWidth, color, speedY, swayX, blastRadius) {
context.fillStyle = color;
context.strokeStyle = color;
context.moveTo(x,y);
context.lineTo(x-swayX,y-speedY);
context.stroke();
},
GetX: function() {
return this.x;
},
GetY: function() {
return this.y;
},
GetLineWidth: function() {
return this.lineWidth;
},
GetColor: function() {
return this.color;
},
GetSpeedY: function() {
return this.speedY;
},
GetSwayX: function() {
return this.swayX;
},
GetRotationAngle: function() {
return this.rotationAngle;
},
GetBlastRadius: function() {
return this.blastRadius;
},
Update: function(modifier) {
this.x = this.x - this.swayX;
this.y = this.y - this.speedY;
if (this.y < -10) {this.x = GetRandom(0,canvas.width);this.y = canvas.height;this.speedY = GetRandom(30,100);this.swayX = GetRandom(-10,10)}
},
};
var DrawFireworks = function() {
//create confetti object array
for (i = 0; i < NUM_FIREWORKS; i++) {
FireworkArray[i].Draw(FireworkArray[i].GetX(), FireworkArray[i].GetY(), FireworkArray[i].GetLineWidth(), FireworkArray[i].GetColor(), FireworkArray[i].GetSpeedY(), FireworkArray[i].GetSwayX(), FireworkArray[i].GetBlastRadius());
}
};
var UpdateFireworks = function(modifier) {
for (i = 0; i < NUM_FIREWORKS; i++) {
FireworkArray[i].Update(modifier);
}
};
UncleSam = function() {
};
UncleSam.prototype = {
};
Text = function(context,title,x,y,color) {
this.context = context;
this.title = title;
this.x = x;
this.y = y;
this.color = color;
this.lineWidth = 2;
this.lineHeight =(this.context.measureText('W').width) + Math.pow((this.context.measureText('W').width),2);
this.font = '70pt Times New Roman';
//GET METRICS
this.metrics = this.context.measureText(this.title);
this.width = this.metrics.width;
this.maxWidth = canvas.width;
this.GradChangeSpeed = .5;
this.GradChangeOffset = .3;
this.debugCounter = 0;
};
Text.prototype = {
SetAttributes: function() {
context.font
context.textAlign = 'center'
context.font = this.font;
context.lineWidth = this.lineWidth;
context.lineHeight = this.GetHeight;
context.fillStyle = TextGradient;
context.strokeStyle = this.color;
//shadow attributes
context.shadowColor = undefined;
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.shadowBlur = 0;
},
//GETTTERS SETTERS///////////////////
GetTextX: function() {
return this.x;
},
GetTextY: function() {
return this.y;
},
GetTextLineHeight: function() {
return this.lineHeight;
},
GetTextWidth: function() {
return this.width;
},
//GETTERS SETTERS////////////
SetColorGradient: function() {
TextGradient.addColorStop(0,"red");
TextGradient.addColorStop(this.GradChangeOffset,"white");
TextGradient.addColorStop(.8,"blue");
},
Update: function(modifier) {
this.GradChangeOffset = this.GradChangeOffset + (this.GradChangeSpeed * modifier);
//GRADIENT DEBUGGERS
context.strokeText(this.GradChangeOffset.toFixed(2),canvas.width/2,canvas.height/2);
//GRADIENT DEBUGGERS
if (this.GradChangeOffset > .7 || this.GradChangeOffset < .2) {this.GradChangeSpeed = -(this.GradChangeSpeed);}
},
DrawText: function() {
this.WrapText(this.context, this.title, this.x, this.y, this.maxWidth, this.lineHeight);
},
WrapText: function(context, title, x, y, maxWidth, lineHeight) {
var words = title.split(' ');
var line = '';
for(var n = 0; n < words.length; n++) {
var testLine = line + words[n] + ' ';
var metrics = context.measureText(testLine);
var testWidth = metrics.width;
if (testWidth > maxWidth && n > 0) {
context.fillText(line, x, y);
context.strokeText(line, x, y);
line = words[n] + ' ';
y += lineHeight;
}
else {
line = testLine;
}
}
context.fillText(line, x, y);
context.strokeText(line, x, y);
},
};
//other functions
var ClearScreen = function() {
context.clearRect(0, 0, canvas.width, canvas.height);
};
var DrawObjects = function() {
ClearScreen();
Background1.DrawBackground();
Text1.SetAttributes();
Text1.SetColorGradient();
Text1.DrawText();
DrawFireworks();
DrawConfetti();
};
var UpdateObjects = function(modifier) {
//Text1.Update(modifier);
UpdateFireworks(modifier);
UpdateConfetti(modifier);
};
var Reset = function() {
};
//MAIN GAME LOOP FXN///////////////////
// The main game loop
var main = function() {
var now = Date.now();
var delta = now - then;
var frameRateAdjust = delta/1000;
DrawObjects(frameRateAdjust);
UpdateObjects(frameRateAdjust);
then = now;
//possibly do RESET
// Request to do this again ASAP
requestAnimationFrame(main);
};
// Cross-browser support for requestAnimationFrame
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
//START ECARD
//create variables
var then = Date.now();
var colorChoices = ["red","white","blue","deeppink","orange","limegreen","darkred"];
var NUM_CONFETTI = 25;
var NUM_FIREWORKS = 10;
var NUM_COLORS = colorChoices.length;
//create arrays for objects
var ConfettiArray = [];
var FireworkArray = [];
//create objects
Background1 = new Background(context,'black');
var Text1 = new Text(context,'Happy 4th of July!',canvas.width/2,canvas.height/10,'red');
var TextGradient = context.createLinearGradient(Text1.GetTextX(),Text1.GetTextY(),Text1.GetTextX()+Text1.GetTextWidth(),Text1.GetTextY()+Text1.GetTextLineHeight()/2)
//fill confetti object array
for (i = 0; i < NUM_CONFETTI; i++) {
ConfettiArray.push(new Confetti(GetRandom(0,canvas.width), GetRandom(-200,-10), GetRandom(10,30), GetRandom(10,30), colorChoices[GetRandom(0,NUM_COLORS)], GetRandom(0,2*Math.PI),GetRandom(50,80)));
}
//fill firework object array
for (i = 0; i < NUM_FIREWORKS; i++) {
FireworkArray.push(new Firework(GetRandom(0,canvas.width), canvas.height, GetRandom(4,20), colorChoices[GetRandom(0,NUM_COLORS)], GetRandom(30,100), GetRandom(-10,10), GetRandom(50,200)));
}
//start eCard animations
Reset();
main();
答案 0 :(得分:0)
原因是因为你要从所有烟花线中创建一条路径。
//firework.draw
Draw: function(x, y, lineWidth, color, speedY, swayX, blastRadius) {
context.fillStyle = color;
context.strokeStyle = color; // sets the stroke color
context.moveTo(x,y); // adds another line
context.lineTo(x-swayX,y-speedY);
context.stroke(); // stroke all lines up to this point
},
每次调用笔划时,所有烟花线都会渲染到该点。
结果是最后一个笔划调用再次绘制了最后一个烟花的颜色。
修复很简单。只需使用ctx.beginPath()
//firework.draw
Draw: function(x, y, lineWidth, color, speedY, swayX, blastRadius) {
context.fillStyle = color;
context.strokeStyle = color; // sets the stroke color
//========================================================
context.beginPath(); // start a new path
//========================================================
context.moveTo(x,y);
context.lineTo(x-swayX,y-speedY);
context.stroke();
},