noname/extension/coin/extension.js

1658 lines
47 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { lib, game, ui, get, ai, _status } from "../../noname.js";
game.import("play", function () {
return {
name: "coin",
init: function () {
if (
lib.config.mode != "chess" ||
get.config("chess_mode") != "leader"
) {
_status.coin = 0;
}
},
arenaReady: function () {
if (_status.video || _status.connectMode) return;
if (
lib.config.mode != "chess" ||
get.config("chess_mode") != "leader"
) {
var str;
if (lib.config.coin_display_playpackconfig == "text") {
str = "<span>" + lib.config.coin + "</span><span>金</span>";
} else {
str =
'<span style="position:absolute">㉤</span><span style="margin-left:18px;font-family:xinwei;line-height:10px">' +
lib.config.coin +
"</span>";
}
if (lib.config.coin_canvas_playpackconfig) {
ui.window.classList.add("canvas_top");
}
ui.coin = ui.create.system(str, null, true);
if (lib.config.snowFall) {
game.haveFun.list.snow.bought = true;
setTimeout(function () {
game.haveFun.snow();
}, 500);
}
lib.setPopped(
ui.coin,
function () {
var uiintro = ui.create.dialog("hidden");
uiintro.classList.add("coin_menu");
uiintro.add("商店");
uiintro.listen(function (e) {
e.stopPropagation();
});
var clickBuy = function () {
if (this.innerHTML == "停止") {
game.haveFun[this.name + "Stop"]();
} else if (this.innerHTML == "开始") {
game.haveFun[this.name]();
} else if (this.innerHTML.indexOf("金") != -1) {
if (lib.config.coin >= this.content.cost) {
this.content.bought = true;
game.changeCoin(-this.content.cost);
game.haveFun[this.name]();
if (this.content.onbuy) {
this.content.onbuy.call(this);
}
} else {
return;
}
}
ui.click.window();
};
for (var i in game.haveFun.list) {
var item = game.haveFun.list[i];
uiintro.add(
'<div class="coin_buy">' +
item.name +
'<div class="menubutton">' +
item.cost +
"金</span></div></div>"
);
var buy =
uiintro.content.lastChild.lastChild.lastChild;
if (lib.config.coin < item.cost && !item.bought) {
buy.classList.add("disabled");
}
if (item.bought) {
if (item.running) {
buy.innerHTML = "停止";
if (item.control) {
var node = item.control();
if (node) {
buy.parentNode.appendChild(
node,
buy
);
}
}
} else {
buy.innerHTML = "开始";
}
}
buy.name = i;
buy.content = item;
buy.listen(clickBuy);
}
if (!game.phaseNumber && !game.online) {
uiintro.add("下注");
uiintro.add(
'<div class="coin_buy">本局获胜<div class="menubutton">20金</span></div></div>'
);
var bet =
uiintro.content.lastChild.lastChild.lastChild;
bet.listen(function () {
if (_status.betWin) return;
_status.betWin = true;
game.changeCoin(-20);
this.innerHTML = "已下注";
});
if (_status.betWin) {
bet.innerHTML = "已下注";
}
} else if (_status.betWin) {
uiintro.add("下注");
uiintro.add(
'<div class="coin_buy">本局获胜<div class="menubutton">已下注</span></div></div>'
);
}
uiintro.classList.add("noleave");
return uiintro;
},
220,
400
);
}
},
game: {
changeCoin: function (num, toast, audio) {
if (typeof num == "number" && ui.coin) {
if (num != 0 && toast !== false) {
ui.create.toast(
`${num > 0 ? "获得" : "花费"}&nbsp;${Math.abs(
num
)}&nbsp;金币`
);
}
if (audio !== false) {
game.playAudio(
"effect",
num > 0 ? "coin" : "coin_cost"
);
}
game.saveConfig("coin", lib.config.coin + num);
var str;
if (lib.config.coin_display_playpackconfig == "text") {
str =
"<span>" +
lib.config.coin +
"</span><span>金</span>";
} else {
str =
'<span style="position:absolute">㉤</span><span style="margin-left:18px;font-family:xinwei;line-height:10px">' +
lib.config.coin +
"</span>";
}
ui.coin.innerHTML = str;
}
},
haveFun: {
list: {
firework: {
name: "烟花",
cost: 50,
},
snow: {
name: "下雪",
cost: 20,
size: "large",
control: function () {
var size = ui.create.div(".menubutton");
if (game.haveFun.list.snow.size == "small") {
size.innerHTML = "大雪";
} else {
size.innerHTML = "小雪";
}
size.listen(game.haveFun.snowSize);
return size;
},
},
star: {
name: "星云",
cost: 10,
},
blink: {
name: "闪烁",
cost: 10,
},
},
alwaysSnow: function () {
game.saveConfig("snowFall", !lib.config.snowFall);
game.reload();
},
blink: function () {
if (game.haveFun.list.blink.running) return;
game.haveFun.list.blink.running = true;
if (game.haveFun.blinkLoop) {
game.haveFun.blinkLoop();
} else {
var canvas = document.createElement("canvas");
ui.window.appendChild(canvas);
canvas.classList.add("fun");
canvas.style.zIndex = 20;
var ctx = canvas.getContext("2d");
//Make the canvas occupy the full page
var W = ui.window.offsetWidth,
H = ui.window.offsetHeight;
canvas.width = W;
canvas.height = H;
lib.onresize.push(function () {
var W = ui.window.offsetWidth,
H = ui.window.offsetHeight;
canvas.width = W;
canvas.height = H;
});
var particles = [];
var mouse = {};
//Lets create some particles now
var particle_count = 25;
//finally some mouse tracking
ui.window.addEventListener("mousemove", function (e) {
//since the canvas = full page the position of the mouse
//relative to the document will suffice
mouse.x = e.pageX / game.documentZoom;
mouse.y = e.pageY / game.documentZoom;
});
ui.window.addEventListener("touchmove", function (e) {
mouse.x = e.touches[0].clientX / game.documentZoom;
mouse.y = e.touches[0].clientY / game.documentZoom;
});
var particle = function () {
//speed, life, location, life, colors
//speed.x range = -2.5 to 2.5
//speed.y range = -15 to -5 to make it move upwards
//lets change the Y speed to make it look like a flame
this.speed = {
x: -2.5 + Math.random() * 5,
y: -5 + Math.random() * 10,
};
this.speed.x /= 4;
this.speed.y /= 4;
//location = mouse coordinates
//Now the flame follows the mouse coordinates
if (mouse.x && mouse.y) {
this.location = { x: mouse.x, y: mouse.y };
} else {
this.location = { x: W / 2, y: H / 2 };
}
//radius range = 10-30
this.radius = 10 + Math.random() * 20;
//life range = 20-30
this.radius /= 4;
this.life = 20 + Math.random() * 10;
this.life *= 4;
this.remaining_life = this.life;
//colors
this.r = Math.round(Math.random() * 255);
this.g = Math.round(Math.random() * 255);
this.b = Math.round(Math.random() * 255);
};
for (var i = 0; i < particle_count; i++) {
particles.push(new particle());
}
var draw = function () {
if (!game.haveFun.list.blink.running) {
canvas.width = W;
canvas.height = H;
return;
}
ctx.clearRect(0, 0, W, H);
//Painting the canvas black
//Time for lighting magic
//particles are painted with "lighter"
//In the next frame the background is painted normally without blending to the
//previous frame
ctx.globalCompositeOperation = "lighter";
for (var i = 0; i < particles.length; i++) {
var p = particles[i];
ctx.beginPath();
//changing opacity according to the life.
//opacity goes to 0 at the end of life of a particle
p.opacity =
Math.round(
(p.remaining_life / p.life) * 100
) / 100;
//a gradient instead of white fill
var gradient = ctx.createRadialGradient(
p.location.x,
p.location.y,
0,
p.location.x,
p.location.y,
p.radius
);
gradient.addColorStop(
0,
"rgba(" +
p.r +
", " +
p.g +
", " +
p.b +
", " +
p.opacity +
")"
);
gradient.addColorStop(
0.5,
"rgba(" +
p.r +
", " +
p.g +
", " +
p.b +
", " +
p.opacity +
")"
);
gradient.addColorStop(
1,
"rgba(" +
p.r +
", " +
p.g +
", " +
p.b +
", 0)"
);
ctx.fillStyle = gradient;
ctx.arc(
p.location.x,
p.location.y,
p.radius,
Math.PI * 2,
false
);
ctx.fill();
//lets move the particles
p.remaining_life--;
p.radius -= 0.2;
p.location.x += p.speed.x;
p.location.y += p.speed.y;
//regenerate particles
if (p.remaining_life < 0 || p.radius < 0) {
//a brand new particle replacing the dead one
particles[i] = new particle();
}
}
requestAnimationFrame(draw);
};
draw();
game.haveFun.blinkLoop = draw;
game.haveFun.blinkStop = function () {
game.haveFun.list.blink.running = false;
};
}
},
star: function () {
if (game.haveFun.list.star.running) return;
game.haveFun.list.star.running = true;
if (game.haveFun.starLoop) {
game.haveFun.starLoop();
} else {
//******************************************************
// Yet Another Particle Engine
var cos = Math.cos,
sin = Math.sin,
sqrt = Math.sqrt,
abs = Math.abs,
atan2 = Math.atan2,
log = Math.log,
random = Math.random,
PI = Math.PI,
sqr = function (v) {
return v * v;
},
particles = [],
drawScale = 1,
emitters = [],
forces = [],
collidedMass = 0,
maxParticles = 100,
emissionRate = 1,
minParticleSize = 2;
//-------------------------------------------------------
// Vectors, and not the kind you put stuff in
var Vector = function (x, y, z) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
};
Vector.prototype = {
add: function (vector) {
this.x += vector.x;
this.y += vector.y;
this.z += vector.z;
return this;
},
subtract: function (vector) {
this.x -= vector.x;
this.y -= vector.y;
this.z -= vector.z;
return this;
},
multiply: function (another) {
this.x /= another.x;
this.y /= another.y;
this.z /= another.z;
return this;
},
divide: function (another) {
this.x /= another.x;
this.y /= another.y;
this.z /= another.z;
return this;
},
scale: function (factor) {
this.x *= factor;
this.y *= factor;
this.z *= factor;
return this;
},
magnitude: function () {
return sqrt(sqr(this.x + this.y));
},
distance: function (another) {
return abs(
sqrt(
sqr(this.x - another.x) +
sqr(this.y - another.y)
)
);
},
angle: function (angle, magnitude) {
if (angle && magnitude)
return Vector.fromAngle(angle, magnitude);
return atan2(this.y, this.x);
},
clone: function () {
return new Vector(this.x, this.y, this.z);
},
equals: function (another) {
return (
this.x === another.x &&
this.y === another.y &&
this.z === another.z
);
},
random: function (r) {
this.x += random() * r * 2 - r;
this.y += random() * r * 2 - r;
return this;
},
};
Vector.fromAngle = function (angle, magnitude) {
return new Vector(
magnitude * cos(angle),
magnitude * sin(angle),
magnitude * sin(angle)
);
};
//******************************************************
// A thing with mass, position, and velocity - like your mom
var Particle = function (pt, vc, ac, mass) {
this.pos = pt || new Vector(0, 0);
this.vc = vc || new Vector(0, 0);
this.ac = ac || new Vector(0, 0);
this.mass = mass || 1;
this.alive = true;
};
Particle.prototype.move = function () {
this.vc.add(this.ac);
this.pos.add(this.vc);
};
Particle.prototype.reactToForces = function (fields) {
var totalAccelerationX = 0;
var totalAccelerationY = 0;
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var vectorX = field.pos.x - this.pos.x;
var vectorY = field.pos.y - this.pos.y;
var distance = this.pos.distance(field.pos);
if (distance < 1) field.grow(this);
if (distance < 100) this.doubleSize = true;
var force = G(
this.forceBetween(field, distance)
);
totalAccelerationX += vectorX * force;
totalAccelerationY += vectorY * force;
}
this.ac = new Vector(
totalAccelerationX,
totalAccelerationY
);
totalAccelerationX = 0;
totalAccelerationY = 0;
for (var i = 0; i < particles.length; i++) {
var field = particles[i];
if (field === this || !field.alive) continue;
var vectorX = field.pos.x - this.pos.x;
var vectorY = field.pos.y - this.pos.y;
var distance = this.pos.distance(field.pos);
if (distance < 1) {
if (this.mass >= field.mass) {
var massRatio = this.mass / field.mass;
if (
particles.length <= maxParticles &&
this.mass > 40
) {
this.alive = false;
this.nova = true;
collidedMass += this.mass;
} else this.grow(field);
} else this.alive = false;
}
if (this.alive) {
var force = G(
this.forceBetween(field, distance)
);
totalAccelerationX += vectorX * G(force);
totalAccelerationY += vectorY * G(force);
}
}
var travelDist = this.pos.distance(
this.lastPos ? this.lastPos : this.pos
);
this.velocity =
travelDist -
(this.lastDistance
? this.lastDistance
: travelDist);
this.lastDistance = travelDist;
this.lastPos = this.pos.clone();
this.ac.add(
new Vector(
totalAccelerationX,
totalAccelerationY
)
);
this.lastPos = this.pos.clone();
// if(this.mass > 20) {
// var chance = 1 / (this.mass - 20);
// if(Math.random()>chance) {
// this.supernova = true;
// this.supernovaDur = 10;
// this.alive = false;
// if(particles.length <= maxParticles) collidedMass += this.mass;
// delete this.size;
// }
// }
};
Particle.prototype.grow = function (another) {
this.mass += another.mass;
this.nova = true;
another.alive = false;
delete this.size;
};
Particle.prototype.breakApart = function (
minMass,
maxParts
) {
if (!minMass) minMass = 1;
if (!maxParts) maxParts = 2;
var remainingMass = this.mass;
var num = 0;
while (remainingMass > 0) {
var np = new Particle(
this.pos.clone().random(this.mass),
new Vector(0, 0)
);
np.mass =
1 + Math.random() * (remainingMass - 1);
if (num >= maxParts - 1)
np.mass = remainingMass;
np.mass = np.mass < minMass ? minMass : np.mass;
remainingMass -= np.mass;
num++;
}
this.nova = true;
delete this.size;
this.alive = false;
};
Particle.prototype.forceBetween = function (
another,
distance
) {
var distance = distance
? distance
: this.pos.distance(another.pos);
return (this.mass * another.mass) / sqr(distance);
};
//******************************************************
//This certainly doesn't *sub*mit to particles, that's for sure
var ParticleEmitter = function (pos, vc, ang) {
// to do config options for emitter - random, static, show emitter, emitter color, etc
this.pos = pos;
this.vc = vc;
this.ang = ang || 0.09;
this.color = "#999";
};
ParticleEmitter.prototype.emit = function () {
var angle =
this.vc.angle() +
this.ang -
Math.random() * this.ang * 2;
var magnitude = this.vc.magnitude();
var position = this.pos.clone();
position.add(
new Vector(
~~(Math.random() * 100 - 50) * drawScale,
~~(Math.random() * 100 - 50) * drawScale
)
);
var velocity = Vector.fromAngle(angle, magnitude);
return new Particle(position, velocity);
};
//******************************************************
// Use it, Luke
// to do collapse functionality into particle
var Force = function (pos, m) {
this.pos = pos;
this.mass = m || 100;
};
Force.prototype.grow = function (another) {
this.mass += another.mass;
this.burp = true;
another.alive = false;
};
var G = function (data) {
return 0.00674 * data;
};
//******************************************************
var canvas = document.createElement("canvas");
canvas.classList.add("fun");
ui.window.appendChild(canvas);
var ctx = canvas.getContext("2d");
canvas.width = ui.window.offsetWidth;
canvas.height = ui.window.offsetHeight;
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
lib.onresize.push(function () {
canvas.width = ui.window.offsetWidth;
canvas.height = ui.window.offsetHeight;
canvasWidth = canvas.width;
canvasHeight = canvas.height;
});
var renderToCanvas = function (
width,
height,
renderFunction
) {
var buffer = document.createElement("canvas");
buffer.width = width;
buffer.height = height;
renderFunction(buffer.getContext("2d"));
return buffer;
};
maxParticles = 500;
emissionRate = 1;
drawScale = 1.3;
minParticleSize = 2;
emitters = [
//br
new ParticleEmitter(
new Vector(
(canvasWidth / 2) * drawScale + 400,
(canvasHeight / 2) * drawScale
),
Vector.fromAngle(2, 5),
1
),
// // bl
// new ParticleEmitter(
// new Vector(
// canvasWidth / 2 * drawScale - 400,
// canvasHeight / 2 * drawScale + 400
// ),
// Vector.fromAngle(1.5, 1),
// 1
// ),
// tl
new ParticleEmitter(
new Vector(
(canvasWidth / 2) * drawScale - 400,
(canvasHeight / 2) * drawScale
),
Vector.fromAngle(5, 5),
1
),
// // tr
// new ParticleEmitter(
// new Vector(
// canvasWidth / 2 * drawScale + 400,
// canvasHeight / 2 * drawScale - 400
// ),
// Vector.fromAngle(4.5, 1),
// 1
// )
];
forces = [
new Force(
new Vector(
(canvasWidth / 2) * drawScale,
(canvasHeight / 2) * drawScale
),
1800
),
];
var loop = function () {
if (!game.haveFun.list.star.running) {
canvas.width = ui.window.offsetWidth;
canvas.height = ui.window.offsetHeight;
return;
}
clear();
update();
draw();
queue();
};
game.haveFun.starLoop = loop;
game.haveFun.starStop = function () {
game.haveFun.list.star.running = false;
};
var clear = function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);
};
var ctr = 0;
var c = [
"rgba(255,255,255,",
"rgba(0,150,255,",
"rgba(255,255,128,",
"rgba(255,255,255,",
];
var rndc = function () {
return c[~~(Math.random() * c.length - 1)];
};
var c2 = "rgba(255,64,32,";
var addNewParticles = function () {
var _emit = function () {
var ret = 0;
for (var i = 0; i < emitters.length; i++) {
for (var j = 0; j < emissionRate; j++) {
var p = emitters[i].emit();
p.color =
ctr % 10 === 0
? Math.random() * 5 <= 1
? c2
: rndc()
: rndc();
p.mass = ~~(Math.random() * 5);
particles.push(p);
ret += p.mass;
ctr++;
}
}
return ret;
};
if (collidedMass !== 0) {
while (collidedMass !== 0) {
collidedMass -= _emit();
collidedMass =
collidedMass < 0 ? 0 : collidedMass;
}
}
if (particles.length > maxParticles) return;
_emit();
};
var CLIPOFFSCREEN = 1,
BUFFEROFFSCREEN = 2,
LOOPSCREEN = 3;
var isPositionAliveAndAdjust = function (
particle,
check
) {
return true;
// var pos = particle.pos;
// if(!check) check = BUFFEROFFSCREEN;
// if(check === CLIPOFFSCREEN) {
// return !(!particle.alive ||
// pos.x < 0 ||
// (pos.x / drawScale) > boundsX ||
// pos.y < 0 ||
// (pos.y / drawScale) > boundsY);
// } else if(check === BUFFEROFFSCREEN) {
// return !(!particle.alive ||
// pos.x < -boundsX * drawScale ||
// pos.x > 2 * boundsX * drawScale ||
// pos.y < -boundsY * drawScale ||
// pos.y > 2 * boundsY * drawScale);
// } else if(check === LOOPSCREEN) {
// if (pos.x < 0) pos.x = boundsX * drawScale;
// if ((pos.x / drawScale) > boundsX) pos.x = 0;
// if (pos.y < 0) pos.y = boundsY * drawScale;
// if ((pos.y / drawScale) > boundsY) pos.y = 0;
// return true;
// }
};
var plotParticles = function (boundsX, boundsY) {
var currentParticles = [];
for (var i = 0; i < particles.length; i++) {
var particle = particles[i];
particle.reactToForces(forces);
if (!isPositionAliveAndAdjust(particle))
continue;
particle.move();
currentParticles.push(particle);
}
};
var offscreenCache = {};
var renderParticle = function (p) {
var position = p.pos;
if (!p.size) p.size = Math.floor(p.mass / 100);
if (!p.opacity) p.opacity = 0.05;
if (p.velocity > 0) {
if (p.opacity <= 0.18) p.opacity += 0.04;
}
if (p.opacity > 0.08) p.opacity -= 0.02;
var actualSize = p.size / drawScale;
actualSize =
actualSize < minParticleSize
? minParticleSize
: actualSize;
if (p.mass > 8) actualSize *= 2;
if (p.nova) {
actualSize *= 4;
p.nova = false;
}
if (p.doubleSize) {
p.doubleSize = false;
actualSize *= 2;
}
// if(p.supernova) {
// actualSize *= 6;
// opacity = 0.15;
// p.supernovaDur = p.supernovaDur - 1;
// if(p.supernovaDur === 0)
// p.supernova = false;
// }
var cacheKey =
actualSize + "_" + p.opacity + "_" + p.color;
var cacheValue = offscreenCache[cacheKey];
if (!cacheValue) {
cacheValue = renderToCanvas(
actualSize * 32,
actualSize * 32,
function (ofsContext) {
var opacity = p.opacity;
var fills = [
{
size: actualSize / 2,
opacity: 1,
},
{
size: actualSize,
opacity: opacity,
},
{
size: actualSize * 2,
opacity: opacity / 2,
},
{
size: actualSize * 4,
opacity: opacity / 3,
},
{
size: actualSize * 8,
opacity: opacity / 5,
},
{
size: actualSize * 16,
opacity: opacity / 16,
},
];
ofsContext.beginPath();
for (var f in fills) {
f = fills[f];
ofsContext.fillStyle =
p.color + f.opacity + ")";
ofsContext.arc(
actualSize * 16,
actualSize * 16,
f.size,
0,
Math.PI * 2,
true
);
ofsContext.fill();
}
ofsContext.closePath();
}
);
offscreenCache[cacheKey] = cacheValue;
}
var posX = p.pos.x / drawScale;
var posY = p.pos.y / drawScale;
ctx.drawImage(cacheValue, posX, posY);
};
var fills = [
{ size: 15, opacity: 1 },
{ size: 25, opacity: 0.3 },
{ size: 50, opacity: 0.1 },
];
var renderScene = function (ofsContext) {
for (var i = 0; i < forces.length; i++) {
var p = forces[i];
var position = p.pos;
var opacity = 1;
ofsContext.beginPath();
for (var f in fills) {
f = fills[f];
var o = p.burp === true ? 1 : f.opacity;
p.burp = false;
// ofsContext.fillStyle = 'rgba(255,255,255,' + o + ')';
// ofsContext.arc(position.x / drawScale,
// position.y / drawScale,
// f.size / drawScale, 0, Math.PI*2, true);
// ofsContext.fill();
}
ofsContext.closePath();
}
for (var i = 0; i < particles.length; i++) {
var p = particles[i];
renderParticle(p);
}
};
var draw = function () {
renderScene(ctx);
};
var update = function () {
addNewParticles();
plotParticles(canvas.width, canvas.height);
};
var queue = function () {
window.requestAnimationFrame(loop);
};
loop();
}
},
snow: function () {
game.haveFun.list.snow.running = true;
if (game.haveFun.snowStart) {
game.haveFun.snowStart();
} else {
/*
* 自由下雪 snowFall
* authorxuanfeng
* time: 2014-01-11
*/
// 控制下雪
var canvas;
var snowFall = function (snow) {
// 可配置属性
snow = snow || {};
this.maxFlake = snow.maxFlake || 200; //最多片数
this.flakeSize = snow.flakeSize || 10; //雪花形状
this.fallSpeed = snow.fallSpeed || 2; //坠落速度
this.status = 0; //0-初始化、1-开始下雪、2-停止下雪、3-暂停下雪、4-继续下雪
};
// 兼容写法
var requestAnimationFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
function (callback) {
setTimeout(callback, 1000 / 60);
};
var cancelAnimationFrame =
window.cancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.msCancelAnimationFrame ||
window.oCancelAnimationFrame;
// 开始下雪
snowFall.prototype.start = function () {
if (this.status == 1 || this.status == 4) {
// 已经在下雪则不作处理
return false;
}
this.status = 1;
// 创建画布
snowCanvas.apply(this);
// 创建雪花形状
createFlakes.apply(this);
// 画雪
drawSnow.apply(this);
};
// 停止下雪
snowFall.prototype.stop = function () {
if (
this.status == 2 ||
this.status == 0 ||
!this.canvas
) {
return false;
}
// 停止动画循环
this.pause();
this.status = 2;
// 删除画布
this.canvas.parentNode.removeChild(this.canvas);
this.canvas = null;
};
// 暂停下雪
snowFall.prototype.pause = function () {
if (this.status == 3) {
return false;
}
this.status = 3;
cancelAnimationFrame(this.loop);
};
// 继续下雪
snowFall.prototype.resume = function () {
if (this.status == 3 && this.canvas) {
this.status = 4;
// 动画的计时控制
var that = this;
this.loop = requestAnimationFrame(function () {
drawSnow.apply(that);
});
}
};
// 创建画布
var snowCanvas = function () {
// 添加Dom结点
var snowcanvas = document.createElement("canvas");
snowcanvas.classList.add("fun");
snowcanvas.id = "snowfall";
ui.window.appendChild(snowcanvas);
canvas = snowcanvas;
this.canvas = snowcanvas;
this.ctx = snowcanvas.getContext("2d");
// 窗口大小改变的处理
lib.onresize.push(function () {
snowcanvas.width = ui.window.offsetWidth;
snowcanvas.height = ui.window.offsetHeight;
});
snowcanvas.width = ui.window.offsetWidth;
snowcanvas.height = ui.window.offsetHeight;
};
// 雪运动对象
var flakeMove = function (
canvasWidth,
canvasHeight,
flakeSize,
fallSpeed
) {
this.x = Math.floor(Math.random() * canvasWidth); //x坐标
this.y = Math.floor(Math.random() * canvasHeight); //y坐标
this.size = Math.random() * flakeSize + 2; //形状
this.maxSize = flakeSize; //最大形状
this.speed = Math.random() * 1 + fallSpeed; //坠落速度
this.fallSpeed = fallSpeed; //坠落速度
this.velY = this.speed; //Y方向速度
this.velX = 0; //X方向速度
this.stepSize = Math.random() / 30; //步长
this.step = 0; //步数
};
flakeMove.prototype.update = function () {
var x = this.x,
y = this.y;
// 左右摆动(余弦)
this.velX *= 0.98;
if (this.velY <= this.speed) {
this.velY = this.speed;
}
this.velX +=
Math.cos((this.step += 0.05)) * this.stepSize;
this.y += this.velY;
this.x += this.velX;
// 飞出边界的处理
if (
this.x >= canvas.width ||
this.x <= 0 ||
this.y >= canvas.height ||
this.y <= 0
) {
this.reset(canvas.width, canvas.height);
}
};
// 飞出边界-放置最顶端继续坠落
flakeMove.prototype.reset = function (width, height) {
this.x = Math.floor(Math.random() * width);
this.y = 0;
this.size = Math.random() * snow.flakeSize + 2;
this.speed = Math.random() * 1 + snow.fallSpeed;
this.velY = this.speed;
this.velX = 0;
};
// 渲染雪花-随机形状
flakeMove.prototype.render = function (ctx) {
var snowFlake = ctx.createRadialGradient(
this.x,
this.y,
0,
this.x,
this.y,
this.size
);
snowFlake.addColorStop(
0,
"rgba(255, 255, 255, 0.9)"
);
snowFlake.addColorStop(
0.5,
"rgba(255, 255, 255, 0.5)"
);
snowFlake.addColorStop(1, "rgba(255, 255, 255, 0)");
ctx.save();
ctx.fillStyle = snowFlake;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
};
// 创建雪花-定义形状
var createFlakes = function () {
var maxFlake = this.maxFlake,
flakes = (this.flakes = []),
canvas = this.canvas;
for (var i = 0; i < 200; i++) {
flakes.push(
new flakeMove(
canvas.width,
canvas.height,
this.flakeSize,
this.fallSpeed
)
);
}
};
// 画雪
var drawSnow = function () {
var maxFlake = this.maxFlake,
flakes = this.flakes;
var ctx = this.ctx,
canvas = this.canvas,
that = this;
// 清空雪花
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var e = 0; e < maxFlake; e++) {
flakes[e].update();
flakes[e].render(ctx);
}
// 一帧一帧的画
this.loop = requestAnimationFrame(function () {
drawSnow.apply(that);
});
};
// 调用及控制方法
var snow = new snowFall();
game.haveFun.snowStart = function () {
snow.start();
};
game.haveFun.snowStop = function () {
game.haveFun.list.snow.running = false;
snow.stop();
};
game.haveFun.snowSize = function () {
if (game.haveFun.list.snow.size == "large") {
game.haveFun.list.snow.size = "small";
snow.maxFlake = 80;
snow.flakeSize = 3;
snow.fallSpeed = 1;
if (this && this.innerHTML) {
this.innerHTML = "大雪";
}
game.saveConfig("coinSnowSize", true);
} else {
game.haveFun.list.snow.size = "large";
snow.maxFlake = 200;
snow.flakeSize = 10;
snow.fallSpeed = 2;
if (this && this.innerHTML) {
this.innerHTML = "小雪";
}
game.saveConfig("coinSnowSize", false);
}
};
if (lib.config.coinSnowSize) {
game.haveFun.snowSize();
}
snow.start();
}
},
firework: function () {
if (game.haveFun.list.firework.running) return;
game.haveFun.list.firework.running = true;
if (game.haveFun.fireworkLoop) {
game.haveFun.fireworkLoop();
} else {
// when animating on canvas, it is best to use requestAnimationFrame instead of setTimeout or setInterval
// not supported in all browsers though and sometimes needs a prefix, so we need a shim
var requestAnimFrame = (function () {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
}
);
})();
// now we will setup our basic variables for the demo
var canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d"),
// full screen dimensions
cw = ui.window.offsetWidth,
ch = ui.window.offsetHeight,
// firework collection
fireworks = [],
// particle collection
particles = [],
// starting hue
hue = 120,
// when launching fireworks with a click, too many get launched at once without a limiter, one launch per 5 loop ticks
limiterTotal = 5,
limiterTick = 0,
// this will time the auto launches of fireworks, one launch per 80 loop ticks
timerTotal = 80,
timerTick = 0,
mousedown = false,
// mouse x coordinate,
mx,
// mouse y coordinate
my;
// set canvas dimensions
canvas.width = cw;
canvas.height = ch;
ui.window.appendChild(canvas);
canvas.classList.add("fun");
lib.onresize.push(function () {
cw = ui.window.offsetWidth;
ch = ui.window.offsetHeight;
canvas.width = cw;
canvas.height = ch;
});
// now we are going to setup our function placeholders for the entire demo
// get a random number within a range
var random = function (min, max) {
return Math.random() * (max - min) + min;
};
// calculate the distance between two points
var calculateDistance = function (p1x, p1y, p2x, p2y) {
var xDistance = p1x - p2x,
yDistance = p1y - p2y;
return Math.sqrt(
Math.pow(xDistance, 2) + Math.pow(yDistance, 2)
);
};
// create firework
var Firework = function (sx, sy, tx, ty) {
// actual coordinates
this.x = sx;
this.y = sy;
// starting coordinates
this.sx = sx;
this.sy = sy;
// target coordinates
this.tx = tx;
this.ty = ty;
// distance from starting point to target
this.distanceToTarget = calculateDistance(
sx,
sy,
tx,
ty
);
this.distanceTraveled = 0;
// track the past coordinates of each firework to create a trail effect, increase the coordinate count to create more prominent trails
this.coordinates = [];
this.coordinateCount = 3;
// populate initial coordinate collection with the current coordinates
while (this.coordinateCount--) {
this.coordinates.push([this.x, this.y]);
}
this.angle = Math.atan2(ty - sy, tx - sx);
this.speed = 2;
this.acceleration = 1.05;
this.brightness = random(50, 70);
// circle target indicator radius
this.targetRadius = 1;
};
// update firework
Firework.prototype.update = function (index) {
// remove last item in coordinates array
this.coordinates.pop();
// add current coordinates to the start of the array
this.coordinates.unshift([this.x, this.y]);
// cycle the circle target indicator radius
if (this.targetRadius < 8) {
this.targetRadius += 0.3;
} else {
this.targetRadius = 1;
}
// speed up the firework
this.speed *= this.acceleration;
// get the current velocities based on angle and speed
var vx = Math.cos(this.angle) * this.speed,
vy = Math.sin(this.angle) * this.speed;
// how far will the firework have traveled with velocities applied?
this.distanceTraveled = calculateDistance(
this.sx,
this.sy,
this.x + vx,
this.y + vy
);
// if the distance traveled, including velocities, is greater than the initial distance to the target, then the target has been reached
if (
this.distanceTraveled >= this.distanceToTarget
) {
createParticles(this.tx, this.ty);
// remove the firework, use the index passed into the update function to determine which to remove
fireworks.splice(index, 1);
} else {
// target not reached, keep traveling
this.x += vx;
this.y += vy;
}
};
// draw firework
Firework.prototype.draw = function () {
ctx.beginPath();
// move to the last tracked coordinate in the set, then draw a line to the current x and y
ctx.moveTo(
this.coordinates[
this.coordinates.length - 1
][0],
this.coordinates[this.coordinates.length - 1][1]
);
ctx.lineTo(this.x, this.y);
ctx.strokeStyle =
"hsl(" +
hue +
", 100%, " +
this.brightness +
"%)";
ctx.stroke();
ctx.beginPath();
// draw the target for this firework with a pulsing circle
ctx.arc(
this.tx,
this.ty,
this.targetRadius,
0,
Math.PI * 2
);
ctx.stroke();
};
// create particle
var Particle = function (x, y) {
this.x = x;
this.y = y;
// track the past coordinates of each particle to create a trail effect, increase the coordinate count to create more prominent trails
this.coordinates = [];
this.coordinateCount = 5;
while (this.coordinateCount--) {
this.coordinates.push([this.x, this.y]);
}
// set a random angle in all possible directions, in radians
this.angle = random(0, Math.PI * 2);
this.speed = random(1, 10);
// friction will slow the particle down
this.friction = 0.95;
// gravity will be applied and pull the particle down
this.gravity = 1;
// set the hue to a random number +-20 of the overall hue variable
this.hue = random(hue - 20, hue + 20);
this.brightness = random(50, 80);
this.alpha = 1;
// set how fast the particle fades out
this.decay = random(0.015, 0.03);
};
// update particle
Particle.prototype.update = function (index) {
// remove last item in coordinates array
this.coordinates.pop();
// add current coordinates to the start of the array
this.coordinates.unshift([this.x, this.y]);
// slow down the particle
this.speed *= this.friction;
// apply velocity
this.x += Math.cos(this.angle) * this.speed;
this.y +=
Math.sin(this.angle) * this.speed +
this.gravity;
// fade out the particle
this.alpha -= this.decay;
// remove the particle once the alpha is low enough, based on the passed in index
if (this.alpha <= this.decay) {
particles.splice(index, 1);
}
};
// draw particle
Particle.prototype.draw = function () {
ctx.beginPath();
// move to the last tracked coordinates in the set, then draw a line to the current x and y
ctx.moveTo(
this.coordinates[
this.coordinates.length - 1
][0],
this.coordinates[this.coordinates.length - 1][1]
);
ctx.lineTo(this.x, this.y);
ctx.strokeStyle =
"hsla(" +
this.hue +
", 100%, " +
this.brightness +
"%, " +
this.alpha +
")";
ctx.stroke();
};
// create particle group/explosion
var createParticles = function (x, y) {
// increase the particle count for a bigger explosion, beware of the canvas performance hit with the increased particles though
var particleCount = 30;
while (particleCount--) {
particles.push(new Particle(x, y));
}
};
// main demo loop
var loop = function () {
// if(lib.config.coin_free_playpackconfig&&!_status.imchoosing){
// canvas.style.display='none';
// }
// else{
// canvas.style.display='';
// }
// this function will run endlessly with requestAnimationFrame
if (!game.haveFun.list.firework.running) {
canvas.width = cw;
canvas.height = ch;
return;
} else {
requestAnimFrame(loop);
}
// increase the hue to get different colored fireworks over time
hue += 0.5;
// normally, clearRect() would be used to clear the canvas
// we want to create a trailing effect though
// setting the composite operation to destination-out will allow us to clear the canvas at a specific opacity, rather than wiping it entirely
ctx.globalCompositeOperation = "destination-out";
// decrease the alpha property to create more prominent trails
ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
ctx.fillRect(0, 0, cw, ch);
// change the composite operation back to our main mode
// lighter creates bright highlight points as the fireworks and particles overlap each other
ctx.globalCompositeOperation = "lighter";
// loop over each firework, draw it, update it
var i = fireworks.length;
while (i--) {
fireworks[i].draw();
fireworks[i].update(i);
}
// loop over each particle, draw it, update it
var i = particles.length;
while (i--) {
particles[i].draw();
particles[i].update(i);
}
// launch fireworks automatically to random coordinates, when the mouse isn't down
if (timerTick >= timerTotal) {
if (!mousedown) {
// start the firework at the bottom middle of the screen, then set the random target coordinates, the random y coordinates will be set within the range of the top half of the screen
fireworks.push(
new Firework(
cw / 2,
ch,
random(0, cw),
random(0, ch / 2)
)
);
timerTick = 0;
}
} else {
timerTick++;
}
// limit the rate at which fireworks get launched when mouse is down
if (limiterTick >= limiterTotal) {
if (mousedown) {
// start the firework at the bottom middle of the screen, then set the current mouse coordinates as the target
fireworks.push(
new Firework(cw / 2, ch, mx, my)
);
limiterTick = 0;
}
} else {
limiterTick++;
}
};
if (lib.config.touchscreen) {
ui.window.addEventListener(
"touchmove",
function (e) {
mx =
e.touches[0].clientX /
game.documentZoom -
canvas.offsetLeft;
my =
e.touches[0].clientY /
game.documentZoom -
canvas.offsetTop;
}
);
ui.window.addEventListener(
"touchstart",
function (e) {
mousedown = true;
}
);
ui.window.addEventListener(
"touchend",
function (e) {
mousedown = false;
}
);
} else {
// mouse event bindings
// update the mouse coordinates on mousemove
ui.window.addEventListener(
"mousemove",
function (e) {
mx =
e.pageX / game.documentZoom -
canvas.offsetLeft;
my =
e.pageY / game.documentZoom -
canvas.offsetTop;
}
);
// toggle mousedown state and prevent canvas from being selected
ui.window.addEventListener(
"mousedown",
function (e) {
e.preventDefault();
mousedown = true;
}
);
ui.window.addEventListener("mouseup", function (e) {
e.preventDefault();
mousedown = false;
});
}
// once the window loads, we are ready for some fireworks!
game.haveFun.fireworkLoop = loop;
(game.haveFun.fireworkStop = function () {
game.haveFun.list.firework.running = false;
}),
loop();
}
},
},
},
help: {
富甲天下:
"<ul><li>每完成一次对局,可获得一定数量的金币" +
"<li>战斗胜利可额外获得20金币每杀死一个敌人可获得10金币托管无效" +
"<li>使用的武将越强,获得的金币数越少" +
"<li>执行以下操作时,将扣除金币:<ul><li>作弊20金币<li>换将卡3金币<li>" +
"自由选将10金币<li>手气卡3金币<li>换人10金币</ul>" +
"<li>金币可用于购买烟花等游戏特效(点击右上角的金币按钮)" +
"<li>修改金币:<br>game.changCoin" +
"<li>默认下雪:<br>game.haveFun.alwaysSnow",
},
};
});