1373 lines
43 KiB
JavaScript
1373 lines
43 KiB
JavaScript
'use strict';
|
||
play.coin={
|
||
init:function(){
|
||
if(lib.config.mode!='story'&&(lib.config.mode!='chess'||get.config('chess_mode')!='leader')){
|
||
_status.coin=0;
|
||
}
|
||
},
|
||
arenaReady:function(){
|
||
if(_status.video||_status.connectMode) return;
|
||
if(lib.config.mode!='story'&&(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){
|
||
if(typeof num=='number'&&ui.coin){
|
||
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;
|
||
mouse.y = e.pageY;
|
||
});
|
||
ui.window.addEventListener('touchmove',function(e){
|
||
mouse.x = e.touches[0].clientX;
|
||
mouse.y = e.touches[0].clientY;
|
||
});
|
||
|
||
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
|
||
* author:xuanfeng
|
||
* 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 - canvas.offsetLeft;
|
||
my = e.touches[0].clientY - 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 - canvas.offsetLeft;
|
||
my = e.pageY - 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'
|
||
}
|
||
}
|