2015-12-15 08:20:57 +00:00
'use strict' ;
2017-04-17 05:18:46 +00:00
game . import ( 'play' , function ( lib , game , ui , get , ai , _status ) {
2017-04-15 00:25:50 +00:00
return {
name : 'coin' ,
init : function ( ) {
if ( lib . config . mode != 'chess' || get . config ( 'chess_mode' ) != 'leader' ) {
_status . coin = 0 ;
2015-12-28 07:30:15 +00:00
}
2017-04-15 00:25:50 +00:00
} ,
arenaReady : function ( ) {
2018-04-17 07:32:43 +00:00
if ( _status . video || _status . connectMode ) return ;
2017-04-15 00:25:50 +00:00
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 == '开始' ) {
2015-12-30 04:00:49 +00:00
game . haveFun [ this . name ] ( ) ;
2017-04-15 00:25:50 +00:00
}
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 ;
2015-12-30 04:00:49 +00:00
}
2015-12-28 07:30:15 +00:00
}
2017-04-15 00:25:50 +00:00
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' ) ;
2015-12-28 07:30:15 +00:00
}
2017-04-15 00:25:50 +00:00
if ( item . bought ) {
if ( item . running ) {
buy . innerHTML = '停止' ;
if ( item . control ) {
var node = item . control ( ) ;
if ( node ) {
buy . parentNode . appendChild ( node , buy ) ;
}
2015-12-31 07:03:13 +00:00
}
}
2017-04-15 00:25:50 +00:00
else {
buy . innerHTML = '开始' ;
}
2015-12-28 09:08:52 +00:00
}
2017-04-15 00:25:50 +00:00
buy . name = i ;
buy . content = item ;
buy . listen ( clickBuy ) ;
2015-12-28 09:08:52 +00:00
}
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
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>' ) ;
2015-12-28 09:08:52 +00:00
}
2017-04-15 00:25:50 +00:00
uiintro . classList . add ( 'noleave' ) ;
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
return uiintro ;
} , 220 , 400 ) ;
2015-12-15 05:13:47 +00:00
}
2018-04-17 07:32:43 +00:00
} ,
2017-04-15 00:25:50 +00:00
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 ;
2015-12-30 04:00:49 +00:00
}
2017-04-15 00:25:50 +00:00
} ,
star : {
name : '星云' ,
cost : 10
} ,
blink : {
name : '闪烁' ,
cost : 10
2015-12-30 04:00:49 +00:00
}
} ,
2017-04-15 00:25:50 +00:00
alwaysSnow : function ( ) {
game . saveConfig ( 'snowFall' , ! lib . config . snowFall ) ;
game . reload ( ) ;
2015-12-30 04:00:49 +00:00
} ,
2017-04-15 00:25:50 +00:00
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
2015-12-30 04:00:49 +00:00
var W = ui . window . offsetWidth , H = ui . window . offsetHeight ;
canvas . width = W ;
canvas . height = H ;
2017-04-15 00:25:50 +00:00
lib . onresize . push ( function ( ) {
var W = ui . window . offsetWidth , H = ui . window . offsetHeight ;
canvas . width = W ;
canvas . height = H ;
} ) ;
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
var particles = [ ] ;
var mouse = { } ;
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
//Lets create some particles now
var particle _count = 25 ;
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
//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 ;
} ) ;
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
var particle = function ( )
2015-12-30 04:00:49 +00:00
{
2017-04-15 00:25:50 +00:00
//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 ) ;
2015-12-30 04:00:49 +00:00
}
2017-04-15 00:25:50 +00:00
for ( var i = 0 ; i < particle _count ; i ++ )
2015-12-30 04:00:49 +00:00
{
2017-04-15 00:25:50 +00:00
particles . push ( new particle ( ) ) ;
2015-12-30 04:00:49 +00:00
}
2017-04-15 00:25:50 +00:00
var draw = function ( )
2015-12-30 04:00:49 +00:00
{
2017-04-15 00:25:50 +00:00
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 ++ )
2015-12-30 04:00:49 +00:00
{
2017-04-15 00:25:50 +00:00
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 ( ) ;
}
2015-12-30 04:00:49 +00:00
}
2017-04-15 00:25:50 +00:00
requestAnimationFrame ( draw ) ;
2015-12-30 04:00:49 +00:00
}
2017-04-15 00:25:50 +00:00
draw ( ) ;
game . haveFun . blinkLoop = draw ;
game . haveFun . blinkStop = function ( ) {
game . haveFun . list . blink . running = false ;
}
2015-12-30 04:00:49 +00:00
}
2017-04-15 00:25:50 +00:00
} ,
star : function ( ) {
if ( game . haveFun . list . star . running ) return ;
game . haveFun . list . star . running = true ;
if ( game . haveFun . starLoop ) {
game . haveFun . starLoop ( ) ;
2015-12-30 04:00:49 +00:00
}
2017-04-15 00:25:50 +00:00
else {
//******************************************************
// Yet Another Particle Engine
var cos = Math . cos ,
2018-04-17 07:32:43 +00:00
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 ,
2017-04-15 00:25:50 +00:00
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 ) {
2018-04-17 07:32:43 +00:00
this . x += vector . x ;
this . y += vector . y ;
this . z += vector . z ;
return this ;
2017-04-15 00:25:50 +00:00
} ,
subtract : function ( vector ) {
2018-04-17 07:32:43 +00:00
this . x -= vector . x ;
this . y -= vector . y ;
this . z -= vector . z ;
return this ;
2017-04-15 00:25:50 +00:00
} ,
multiply : function ( another ) {
2018-04-17 07:32:43 +00:00
this . x /= another . x ;
this . y /= another . y ;
this . z /= another . z ;
return this ;
2017-04-15 00:25:50 +00:00
} ,
divide : function ( another ) {
2018-04-17 07:32:43 +00:00
this . x /= another . x ;
this . y /= another . y ;
this . z /= another . z ;
return this ;
2017-04-15 00:25:50 +00:00
} ,
scale : function ( factor ) {
2018-04-17 07:32:43 +00:00
this . x *= factor ;
this . y *= factor ;
this . z *= factor ;
return this ;
2017-04-15 00:25:50 +00:00
} ,
magnitude : function ( ) {
2018-04-17 07:32:43 +00:00
return sqrt ( sqr ( this . x + this . y ) ) ;
2017-04-15 00:25:50 +00:00
} ,
distance : function ( another ) {
2018-04-17 07:32:43 +00:00
return abs ( sqrt ( sqr ( this . x - another . x ) + sqr ( this . y - another . y ) ) ) ;
2017-04-15 00:25:50 +00:00
} ,
angle : function ( angle , magnitude ) {
2018-04-17 07:32:43 +00:00
if ( angle && magnitude )
return Vector . fromAngle ( angle , magnitude ) ;
return atan2 ( this . y , this . x ) ;
2017-04-15 00:25:50 +00:00
} ,
clone : function ( ) {
2018-04-17 07:32:43 +00:00
return new Vector ( this . x , this . y , this . z ) ;
2017-04-15 00:25:50 +00:00
} ,
equals : function ( another ) {
2018-04-17 07:32:43 +00:00
return this . x === another . x &&
2017-04-15 00:25:50 +00:00
this . y === another . y &&
this . z === another . z ;
} ,
random : function ( r ) {
2018-04-17 07:32:43 +00:00
this . x += ( random ( ) * r * 2 ) - r ;
this . y += ( random ( ) * r * 2 ) - r ;
return this ;
2017-04-15 00:25:50 +00:00
}
} ;
Vector . fromAngle = function ( angle , magnitude ) {
return new Vector (
2018-04-17 07:32:43 +00:00
magnitude * cos ( angle ) ,
magnitude * sin ( angle ) ,
magnitude * sin ( angle ) ) ;
2017-04-15 00:25:50 +00:00
} ;
//******************************************************
// 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 ++ ) {
2018-04-17 07:32:43 +00:00
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 ;
2017-04-15 00:25:50 +00:00
}
this . ac = new Vector ( totalAccelerationX , totalAccelerationY ) ;
totalAccelerationX = 0 ;
totalAccelerationY = 0 ;
for ( var i = 0 ; i < particles . length ; i ++ ) {
2018-04-17 07:32:43 +00:00
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 ) ;
}
2017-04-15 00:25:50 +00:00
}
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 ) {
2018-04-17 07:32:43 +00:00
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 ++ ;
2017-04-15 00:25:50 +00:00
}
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 ( ) +
2018-04-17 07:32:43 +00:00
this . ang - ( Math . random ( ) * this . ang * 2 ) ;
2017-04-15 00:25:50 +00:00
var magnitude = this . vc . magnitude ( ) ;
var position = this . pos . clone ( ) ;
2018-04-17 07:32:43 +00:00
position . add (
new Vector (
~ ~ ( ( Math . random ( ) * 100 ) - 50 ) * drawScale ,
~ ~ ( ( Math . random ( ) * 100 ) - 50 ) * drawScale
) ) ;
2017-04-15 00:25:50 +00:00
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 ;
} ;
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
var G = function ( data ) {
return 0.00674 * data ;
}
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
//******************************************************
var canvas = document . createElement ( 'canvas' ) ;
canvas . classList . add ( 'fun' ) ;
ui . window . appendChild ( canvas ) ;
var ctx = canvas . getContext ( '2d' ) ;
2015-12-30 04:00:49 +00:00
canvas . width = ui . window . offsetWidth ;
canvas . height = ui . window . offsetHeight ;
2017-04-15 00:25:50 +00:00
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 ;
} ) ;
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
var renderToCanvas = function ( width , height , renderFunction ) {
2018-04-17 07:32:43 +00:00
var buffer = document . createElement ( 'canvas' ) ;
buffer . width = width ;
buffer . height = height ;
renderFunction ( buffer . getContext ( '2d' ) ) ;
return buffer ;
2017-04-15 00:25:50 +00:00
} ;
maxParticles = 500 ;
emissionRate = 1 ;
drawScale = 1.3 ;
minParticleSize = 2 ;
emitters = [
//br
new ParticleEmitter (
2018-04-17 07:32:43 +00:00
new Vector (
canvasWidth / 2 * drawScale + 400 ,
canvasHeight / 2 * drawScale
) ,
Vector . fromAngle ( 2 , 5 ) ,
1
2017-04-15 00:25:50 +00:00
) ,
// // bl
// new ParticleEmitter(
// new Vector(
// canvasWidth / 2 * drawScale - 400,
// canvasHeight / 2 * drawScale + 400
// ),
// Vector.fromAngle(1.5, 1),
// 1
// ),
2018-04-17 07:32:43 +00:00
// tl
2017-04-15 00:25:50 +00:00
new ParticleEmitter (
2018-04-17 07:32:43 +00:00
new Vector (
canvasWidth / 2 * drawScale - 400 ,
canvasHeight / 2 * drawScale
) ,
Vector . fromAngle ( 5 , 5 ) ,
1
2017-04-15 00:25:50 +00:00
) ,
// // tr
// new ParticleEmitter(
// new Vector(
// canvasWidth / 2 * drawScale + 400,
// canvasHeight / 2 * drawScale - 400
// ),
// Vector.fromAngle(4.5, 1),
// 1
// )
] ;
forces = [
new Force (
2018-04-17 07:32:43 +00:00
new Vector ( ( canvasWidth / 2 * drawScale ) ,
( canvasHeight / 2 * drawScale ) ) , 1800 )
2017-04-15 00:25:50 +00:00
] ;
var loop = function ( ) {
if ( ! game . haveFun . list . star . running ) {
canvas . width = ui . window . offsetWidth ;
canvas . height = ui . window . offsetHeight ;
return ;
}
clear ( ) ;
update ( ) ;
draw ( ) ;
queue ( ) ;
2015-12-30 04:00:49 +00:00
}
2017-04-15 00:25:50 +00:00
game . haveFun . starLoop = loop ;
game . haveFun . starStop = function ( ) {
game . haveFun . list . star . running = false ;
} ;
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
var clear = function ( ) {
ctx . clearRect ( 0 , 0 , canvas . width , canvas . height ) ;
}
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
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 ( ) {
2018-04-17 07:32:43 +00:00
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 ) ?
2017-04-15 00:25:50 +00:00
( Math . random ( ) * 5 <= 1 ? c2 : rndc ( ) )
2018-04-17 07:32:43 +00:00
: rndc ( ) ;
p . mass = ~ ~ ( Math . random ( ) * 5 ) ;
particles . push ( p ) ;
ret += p . mass ;
ctr ++ ;
}
}
return ret ;
2017-04-15 00:25:50 +00:00
} ;
if ( collidedMass !== 0 ) {
2018-04-17 07:32:43 +00:00
while ( collidedMass !== 0 ) {
collidedMass -= _emit ( ) ;
collidedMass = collidedMass < 0 ? 0 : collidedMass ;
}
2017-04-15 00:25:50 +00:00
}
if ( particles . length > maxParticles )
2018-04-17 07:32:43 +00:00
return ;
2017-04-15 00:25:50 +00:00
_emit ( ) ;
}
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
var CLIPOFFSCREEN = 1 ,
2018-04-17 07:32:43 +00:00
BUFFEROFFSCREEN = 2 ,
LOOPSCREEN = 3 ;
2017-04-15 00:25:50 +00:00
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;
// }
}
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
var plotParticles = function ( boundsX , boundsY ) {
var currentParticles = [ ] ;
for ( var i = 0 ; i < particles . length ; i ++ ) {
2018-04-17 07:32:43 +00:00
var particle = particles [ i ] ;
particle . reactToForces ( forces ) ;
if ( ! isPositionAliveAndAdjust ( particle ) )
continue ;
particle . move ( ) ;
currentParticles . push ( particle ) ;
2017-04-15 00:25:50 +00:00
}
}
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
var offscreenCache = { } ;
var renderParticle = function ( p ) {
2018-04-17 07:32:43 +00:00
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 ) ;
2017-04-15 00:25:50 +00:00
}
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
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 ++ ) {
2018-04-17 07:32:43 +00:00
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 ( ) ;
2017-04-15 00:25:50 +00:00
}
for ( var i = 0 ; i < particles . length ; i ++ ) {
2018-04-17 07:32:43 +00:00
var p = particles [ i ] ;
renderParticle ( p ) ;
2017-04-15 00:25:50 +00:00
}
}
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
var draw = function ( ) {
renderScene ( ctx ) ;
}
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
var update = function ( ) {
addNewParticles ( ) ;
plotParticles ( canvas . width , canvas . height ) ;
}
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
var queue = function ( ) {
window . requestAnimationFrame ( loop ) ;
}
2015-12-30 04:00:49 +00:00
2017-04-15 00:25:50 +00:00
loop ( ) ;
2015-12-30 04:00:49 +00:00
2015-12-28 09:08:52 +00:00
}
2017-04-15 00:25:50 +00:00
} ,
snow : function ( ) {
game . haveFun . list . snow . running = true ;
if ( game . haveFun . snowStart ) {
game . haveFun . snowStart ( ) ;
2015-12-28 09:08:52 +00:00
}
2017-04-15 00:25:50 +00:00
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-继续下雪
2015-12-28 09:08:52 +00:00
}
2017-04-15 00:25:50 +00:00
// 兼容写法
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 )
2015-12-28 09:08:52 +00:00
}
2017-04-15 00:25:50 +00:00
// 停止下雪
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 ;
}
2015-12-28 09:08:52 +00:00
2017-04-15 00:25:50 +00:00
// 暂停下雪
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 )
} ) ;
}
} ;
2015-12-28 09:08:52 +00:00
2017-04-15 00:25:50 +00:00
// 创建画布
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 ;
2015-12-28 09:08:52 +00:00
}
2017-04-15 00:25:50 +00:00
// 雪运动对象
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 //步数
2015-12-28 09:08:52 +00:00
}
2017-04-15 00:25:50 +00:00
flakeMove . prototype . update = function ( ) {
var x = this . x ,
2018-04-17 07:32:43 +00:00
y = this . y ;
2015-12-28 09:08:52 +00:00
2017-04-15 00:25:50 +00:00
// 左右摆动(余弦)
this . velX *= 0.98 ;
if ( this . velY <= this . speed ) {
this . velY = this . speed
}
this . velX += Math . cos ( this . step += 0.05 ) * this . stepSize ;
2015-12-28 09:08:52 +00:00
2017-04-15 00:25:50 +00:00
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 ) )
}
2015-12-28 09:08:52 +00:00
}
2017-04-15 00:25:50 +00:00
// 画雪
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 ) ;
} ) ;
2015-12-28 09:08:52 +00:00
}
2017-04-15 00:25:50 +00:00
// 调用及控制方法
var snow = new snowFall ( ) ;
game . haveFun . snowStart = function ( ) {
snow . start ( ) ;
2015-12-30 04:00:49 +00:00
}
2017-04-15 00:25:50 +00:00
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 ) ;
2015-12-30 04:00:49 +00:00
}
2017-04-15 00:25:50 +00:00
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 ( ) ;
2015-12-30 04:00:49 +00:00
}
2017-04-15 00:25:50 +00:00
snow . start ( ) ;
2015-12-30 04:00:49 +00:00
}
2017-04-15 00:25:50 +00:00
} ,
firework : function ( ) {
if ( game . haveFun . list . firework . running ) return ;
game . haveFun . list . firework . running = true ;
if ( game . haveFun . fireworkLoop ) {
game . haveFun . fireworkLoop ( ) ;
2016-01-13 03:09:44 +00:00
}
2017-04-15 00:25:50 +00:00
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
2015-12-28 07:30:15 +00:00
canvas . width = cw ;
canvas . height = ch ;
2017-04-15 00:25:50 +00:00
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 ;
} ) ;
2015-12-28 07:30:15 +00:00
2017-04-15 00:25:50 +00:00
// now we are going to setup our function placeholders for the entire demo
2015-12-28 07:30:15 +00:00
2017-04-15 00:25:50 +00:00
// get a random number within a range
var random = function ( min , max ) {
return Math . random ( ) * ( max - min ) + min ;
}
2015-12-28 07:30:15 +00:00
2017-04-15 00:25:50 +00:00
// 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 ) ) ;
2015-12-28 07:30:15 +00:00
}
2017-04-15 00:25:50 +00:00
// 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
2015-12-28 07:30:15 +00:00
this . targetRadius = 1 ;
}
2017-04-15 00:25:50 +00:00
// 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 ;
}
2015-12-28 07:30:15 +00:00
}
2017-04-15 00:25:50 +00:00
// 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 ( ) ;
2015-12-28 07:30:15 +00:00
2017-04-15 00:25:50 +00:00
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 ( ) ;
2015-12-28 07:30:15 +00:00
}
2017-04-15 00:25:50 +00:00
// 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 ) ;
2015-12-28 07:30:15 +00:00
}
2017-04-15 00:25:50 +00:00
// 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 ) ;
}
2015-12-28 07:30:15 +00:00
}
2017-04-15 00:25:50 +00:00
// 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 ( ) ;
2015-12-28 07:30:15 +00:00
}
2017-04-15 00:25:50 +00:00
// 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 ) ) ;
}
2015-12-28 07:30:15 +00:00
}
2017-04-15 00:25:50 +00:00
// 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 ) ;
}
2015-12-28 07:30:15 +00:00
2017-04-15 00:25:50 +00:00
// 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 ) ;
2015-12-28 07:30:15 +00:00
}
2017-04-15 00:25:50 +00:00
// 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 ++ ;
2015-12-28 07:30:15 +00:00
}
}
2017-04-15 00:25:50 +00:00
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 ;
} ) ;
2015-12-28 07:30:15 +00:00
2017-04-15 00:25:50 +00:00
// toggle mousedown state and prevent canvas from being selected
ui . window . addEventListener ( 'mousedown' , function ( e ) {
e . preventDefault ( ) ;
mousedown = true ;
} ) ;
2015-12-28 07:30:15 +00:00
2017-04-15 00:25:50 +00:00
ui . window . addEventListener ( 'mouseup' , function ( e ) {
e . preventDefault ( ) ;
mousedown = false ;
} ) ;
}
2015-12-28 07:30:15 +00:00
2017-04-15 00:25:50 +00:00
// 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 ( ) ;
}
2015-12-28 07:30:15 +00:00
}
}
2017-04-15 00:25:50 +00:00
} ,
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'
2015-12-28 07:30:15 +00:00
}
2017-04-15 00:25:50 +00:00
} ;
2017-04-14 23:35:56 +00:00
} ) ;