所以我在我的游戏中有一个画布会显示一些文字,但是如果你曾经玩过 Clicker Heros ,当你点击了一些损坏文字但是它已经褪色了缓慢地向外移动,同时逐渐向上移动,我想在这里产生相同的效果
所以我所拥有的是当用户点击终端时调用的函数我需要文本来产生类似的行为但是我对画布很新,不知道如何在这里这样做是我目前的代码
var canvas = document.getElementById("terminalCanvas");
var terminal = canvas.getContext("2d");
terminal.fillStyle = "#000000";
terminal.fillRect(0,0,150,200);
function WriteToCanvas(){
if(Game.Player.HTMLSupport == 1){
var rand = Math.floor(Math.random() * 122) + 1;
var tag = htmltags[rand];
terminal.font = "20px Comic Sans MS";
terminal.fillStyle = "rgb(0,255,1)";
terminal.textAlign = "center";
terminal.fillText(tag, canvas.width/2, canvas.height/2);
ClearCanvas();
}
}
function ClearCanvas(){
terminal.clearRect(0,0,canvas.width,canvas.height);
terminal.fillStyle = "#000000";
terminal.fillRect(0,0,150,200);
}
答案 0 :(得分:1)
粒子系统就是您所需要的。代码顶部的波纹管是您需要做一个简单且内存有效的粒子系统。 使用粒子池。当他们的时间到了,死亡的粒子会进入游泳池。当需要新的粒子时,检查池中是否存在任何死亡粒子,如果是这样,则重新创建它们,否则创建一个新粒子。这避免了可怕的GC滞后,粒子系统可以使工作更加困难。
您可能不会使用fillText(因为它非常慢)来渲染粒子,但预渲染并使用drawImage。由你决定。
抱歉,我没有时间进行更深入的解释
/*=====================================================================================
ANSWER code start
=====================================================================================*/
const LIFETIME = 1 / 180; // 180 frames
const YDIST = -140; // number of pixels to move over the life
const MOVE_CURVE_SHAPE = 1.5;
const FADE_CURVE_SHAPE = 1.5;
const FADE_CURVE_ADVANCE = 0.25; // Want the fade not to start early on the fade curve
var particles = []; // array to hold live particles
var particlePool = []; // to hold the dead
// this function is called once a frame
function display(){ // put code in here
ctx.setTransform(1,0,0,1,0,0); // reset transform
ctx.globalAlpha = 1; // reset alpha
ctx.clearRect(0,0,w,h);
ctx.font = "40px Comic Sans MS";
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Click mouse to add particles",canvas.width/2, 30);
if(mouse.buttonRaw & 1){
var p;
if(particlePool.length){ // check if the are any dead particles in the pool
p = particlePool.shift(); // if so get the first on in out
}else{ // nothing in the pool so create a new on
p = {};
}
// set up the paticle
var text = (Math.floor(Math.random()* 10) *100) + "!"; // the text to display
p = createParticle(mouse.x,mouse.y,text,p); // set up the particle
particles.push(p); // push it onto the active array
mouse.buttonRaw = 0; // clear mouse down;
}
updateParticles(); // update particles
renderParticles(); // and draw them
}
// sets up a particle x,y startung pos, text the value to display, p and object to hold the data
function createParticle(x,y,text,p){
p.life = 1; // when this get down to zero it is dead
p.x = x;
p.y = y;
p.text = text;
return p;
}
// ease functions
var easeBell = function (x, pow) { // x 0-1 pos > 0
x = x * 2;
if( x > 1){
x = 1 - (x - 1);
var xx = Math.pow(x,pow);
return xx / (xx + Math.pow(1 - x, pow));
}else{
var xx = Math.pow(x,pow);
return xx / (xx + Math.pow(1 - x, pow));
}
}
var ease = function (x, pow) { // x 0-1 pos > 0
var xx = Math.pow(x,pow);
return xx / (xx + Math.pow(1 - x, pow));
}
function updateParticles(){ // update the life and death of the particles
for(var i = 0; i < particles.length; i ++){
var p = particles[i];
p.life -= LIFETIME;
if(p.life <= 0){ // time is up this particle is dead
// move it to the grave
particlePool.push(p);
particles.splice(i,1); // remove it from the array
i -= 1; // adjust i so we dont skip any
}
}
}
function renderParticles(){
ctx.font = "20px Comic Sans MS"
ctx.fillStyle = "#F00";
for(var i = 0; i < particles.length; i ++){ // for each active particle
var p = particles[i];
var fadeCurveVal = 1- p.life;
fadeCurveVal *= (1 - FADE_CURVE_ADVANCE); // scale it down
fadeCurveVal += FADE_CURVE_ADVANCE; // move it forward
ctx.globalAlpha = easeBell(fadeCurveVal,FADE_CURVE_SHAPE); // get the fade fx
var y = p.y + ease((1-p.life)/2,MOVE_CURVE_SHAPE) * YDIST * 2;
ctx.fillText(p.text,p.x,y);
}
}
/*=====================================================================================
ANSWER code End
=====================================================================================*/
/** SimpleFullCanvasMouse.js begin **/
const CANVAS_ELEMENT_ID = "canv";
const U = undefined;
var w, h, cw, ch; // short cut vars
var canvas, ctx, mouse;
var globalTime = 0;
var createCanvas, resizeCanvas, setGlobals;
var L = typeof log === "function" ? log : function(d){ console.log(d); }
createCanvas = function () {
var c,cs;
cs = (c = document.createElement("canvas")).style;
c.id = CANVAS_ELEMENT_ID;
cs.position = "absolute";
cs.top = cs.left = "0px";
cs.zIndex = 1000;
document.body.appendChild(c);
return c;
}
resizeCanvas = function () {
if (canvas === U) { canvas = createCanvas(); }
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx = canvas.getContext("2d");
if (typeof setGlobals === "function") { setGlobals(); }
}
setGlobals = function(){ cw = (w = canvas.width) / 2; ch = (h = canvas.height) / 2; }
mouse = (function(){
function preventDefault(e) { e.preventDefault(); }
var mouse = {
x : 0, y : 0, w : 0, alt : false, shift : false, ctrl : false, buttonRaw : 0,
over : false, // mouse is over the element
bm : [1, 2, 4, 6, 5, 3], // masks for setting and clearing button raw bits;
mouseEvents : "mousemove,mousedown,mouseup,mouseout,mouseover,mousewheel,DOMMouseScroll".split(",")
};
var m = mouse;
function mouseMove(e) {
var t = e.type;
m.x = e.offsetX; m.y = e.offsetY;
if (m.x === U) { m.x = e.clientX; m.y = e.clientY; }
m.alt = e.altKey; m.shift = e.shiftKey; m.ctrl = e.ctrlKey;
if (t === "mousedown") { m.buttonRaw |= m.bm[e.which-1]; }
else if (t === "mouseup") { m.buttonRaw &= m.bm[e.which + 2]; }
else if (t === "mouseout") { m.buttonRaw = 0; m.over = false; }
else if (t === "mouseover") { m.over = true; }
else if (t === "mousewheel") { m.w = e.wheelDelta; }
else if (t === "DOMMouseScroll") { m.w = -e.detail; }
if (m.callbacks) { m.callbacks.forEach(c => c(e)); }
e.preventDefault();
}
m.addCallback = function (callback) {
if (typeof callback === "function") {
if (m.callbacks === U) { m.callbacks = [callback]; }
else { m.callbacks.push(callback); }
} else { throw new TypeError("mouse.addCallback argument must be a function"); }
}
m.start = function (element, blockContextMenu) {
if (m.element !== U) { m.removeMouse(); }
m.element = element === U ? document : element;
m.blockContextMenu = blockContextMenu === U ? false : blockContextMenu;
m.mouseEvents.forEach( n => { m.element.addEventListener(n, mouseMove); } );
if (m.blockContextMenu === true) { m.element.addEventListener("contextmenu", preventDefault, false); }
}
m.remove = function () {
if (m.element !== U) {
m.mouseEvents.forEach(n => { m.element.removeEventListener(n, mouseMove); } );
if (m.contextMenuBlocked === true) { m.element.removeEventListener("contextmenu", preventDefault);}
m.element = m.callbacks = m.contextMenuBlocked = U;
}
}
return mouse;
})();
var done = function(){
window.removeEventListener("resize",resizeCanvas)
mouse.remove();
document.body.removeChild(canvas);
canvas = ctx = mouse = U;
L("All done!")
}
resizeCanvas(); // create and size canvas
mouse.start(canvas,true); // start mouse on canvas and block context menu
window.addEventListener("resize",resizeCanvas); // add resize event
function update(timer){ // Main update loop
globalTime = timer;
display(); // call demo code
// continue until mouse right down
if (!(mouse.buttonRaw & 4)) { requestAnimationFrame(update); } else { done(); }
}
requestAnimationFrame(update);
/** SimpleFullCanvasMouse.js end **/
&#13;