【编程游戏】贺岁放礼花。(点燃续帖2-154楼ZhangYaoxing的焰火)

本文介绍了一种使用JavaScript实现烟花燃放效果的方法。通过物理引擎模拟真实世界中的烟花行为,包括上升、爆炸和轨迹绘制等过程。代码中详细定义了焰火的各种属性,如颜色、大小、速度及样式。

<script type="text/javascript"><!-- function viewPage(html) { var page = window.open('', '', ''); page.opener = null; page.document.write(html); page.document.close(); } window.onload = function() { var iframe = document.createElement("iframe"); iframe.width = "100%"; iframe.height = "400px"; iframe.frameBorder = "0"; iframe.marginHeight = "0"; iframe.src = "http://vote.youkuaiyun.com/VotePostSimple.aspx?voteid=993"; iframe.scrolling = "no"; var textarea = document.getElementsByTagName('textarea')[0]; textarea.parentNode.insertBefore(iframe, textarea); } // --></script>【编程游戏】贺岁放礼花。(第一名奖励10000可用分)
作者:avatar


点燃[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]
注释一下,大家可以根据自己喜好调整以下参数以达到理想的效果
var G = 6; // 重力加速度
var T_STEP = window.ActiveXObject ? 0.5 : 0.3; // 时间单位,越小画面越细腻
var MAIN_BLAZE_SIZE = 15; // 主焰火尺寸(px)
var BLAZE_SIZE = 15; // 炸开后单个焰火尺寸(px)
var BLAZE_COUNT = 20; // 炸开的焰火数量
var BLAZE_LASTS = 8; // 炸开焰火的持续时间
var BLAZE_MAX_SPEED = 20; // 炸开焰火的最大初速度
var TRACK_SIZE = 15; // 单个焰火轨迹尺寸
var TRACK_INTERVAL = 2; // 产生轨迹的时间间隔
var TRACK_LASTS = 2; // 轨迹持续时间
var FW_STYLE = [["*", "."], ["^", "."], ["*", "*"], [".", "."], ["o", "."], ["O", "o"]]; // 焰火样式。前面是焰火样式,后面是轨迹样式
var TOTAL_FIREWORKS = 2; // 屏幕上同时存在的焰火个数
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf8" /> <title>X Fireworks </title> <style> body { background-color:#000; overflow:hidden; } </style> <script type="text/javascript"> /*A zhangyx production. Enjoy it!*/ var H = document.documentElement.clientHeight; var W = document.documentElement.clientWidth; var G = 3; var OFFSET_BOTTOM = 50; var T_STEP = window.ActiveXObject ? 0.5 : 0.3; var MAIN_BLAZE_SIZE = 15; var MAIN_BLAZE_LASTS = Math.floor(Math.sqrt(2 * (H - OFFSET_BOTTOM) / G)); var BLAZE_SIZE = 15; var BLAZE_COUNT = 20; var BLAZE_ANGLE = 2 * Math.PI / BLAZE_COUNT; var BLAZE_LASTS = 12; var BLAZE_MAX_SPEED = 20; var TRACK_SIZE = 15; var TRACK_INTERVAL = 2; var TRACK_LASTS = 4; var FW_STYLE = [["*", "."], ["^", "."], ["*", "*"], [".", "."], ["o", "."], ["O", "o"]]; var TOTAL_FIREWORKS = 2; function Fireworks() { this.engine = new PhysicalEngine(); this.status = Fireworks.INIT; this.blazes = []; this.tracks = []; this.intervalCounter = 0; } Fireworks.INIT = 0 Fireworks.RISING = 1; Fireworks.PRE_BLAZE = 2; Fireworks.BLAZE = 3; Fireworks.DEAD = 4; Fireworks.prototype = { step: function() { switch (this.status) { case Fireworks.INIT: this.blazes.push(this.engine.getMainBlaze()); this.status = Fireworks.RISING; break; case Fireworks.RISING: this._commonManagement(); if (this.blazes[0].lasts <= 0) { this.status = Fireworks.PRE_BLAZE; } break; case Fireworks.PRE_BLAZE: this.engine.getBlazes(this.blazes); document.body.removeChild(this.blazes[0]); this.blazes.shift(); this.status = Fireworks.BLAZE; break; case Fireworks.BLAZE: this._commonManagement(); if (this.blazes[0].color.r <= 0) { this.status = Fireworks.DEAD; } break; case Fireworks.DEAD: var remove = function(con) { while (con.length != 0) { document.body.removeChild(con[0]); con.shift(); } }; remove(this.blazes); remove(this.tracks); break; } }, _commonManagement: function() { this.intervalCounter++; this.intervalCounter %= TRACK_INTERVAL; var length = this.blazes.length; for (var i = 0; i < length; i++) { var blaze = this.blazes[i]; this.engine.transBlaze(this.blazes[i]); if (this.intervalCounter == 0) { this.tracks.push(this.engine.getTrack(blaze)); } } var length = this.tracks.length; for (var i = 0; i < length; i++) { var track = this.tracks[i]; this.engine.transTrack(track); if (track.lasts <= 0) { this.tracks.shift(); length--; i--; document.body.removeChild(track); } } } }; function PhysicalEngine() { var style = FW_STYLE[Math.round((FW_STYLE.length - 1) * Math.random())]; this.blazeChar = style[0]; this.trackChar = style[1]; } PhysicalEngine.prototype = { getMainBlaze: function() { var blaze = document.createElement("div"); blaze.style.position = "absolute"; blaze.style.zIndex = 100; blaze.lasts = MAIN_BLAZE_LASTS * (1 + Math.random()) / 2; blaze.color = { r: 255 * Math.random(), g: 255 * Math.random(), b: 255 * Math.random() }; blaze.path = { x: Math.round(W * Math.random()), y: H - OFFSET_BOTTOM }; blaze.speed = { x: 0, y: - G * blaze.lasts }; blaze.size = MAIN_BLAZE_SIZE; blaze.color.rd = blaze.color.r / blaze.lasts * T_STEP; blaze.color.gd = blaze.color.g / blaze.lasts * T_STEP; blaze.color.bd = blaze.color.b / blaze.lasts * T_STEP; blaze.speed.xd = 0; blaze.speed.yd = G * T_STEP; blaze.innerHTML = this.blazeChar; this._setCSS(blaze); document.body.appendChild(blaze); return blaze; }, getBlazes: function(blazes) { var mainBlaze = blazes[0]; var speed = (1 + Math.random()) / 2 * BLAZE_MAX_SPEED; var speedType = Math.round(Math.random()); var accType = Math.round(Math.random()); for (var i = 0; i < BLAZE_COUNT; i++) { var blaze = document.createElement("div"); blaze.style.position = "absolute"; blaze.style.zIndex = 100; blaze.lasts = BLAZE_LASTS; blaze.color = { r: 255 * Math.random(), g: 255 * Math.random(), b: 255 * Math.random() }; blaze.path = { x: mainBlaze.path.x, y: mainBlaze.path.y }; if (speedType) { blaze.speed = { x: speed * Math.cos(BLAZE_ANGLE * i), y: speed * Math.sin(BLAZE_ANGLE * i) } } else { blaze.speed = { x: (1 + Math.random()) / 2 * BLAZE_MAX_SPEED * Math.cos(BLAZE_ANGLE * i), y: (1 + Math.random()) / 2 * BLAZE_MAX_SPEED * Math.sin(BLAZE_ANGLE * i) } } blaze.size = BLAZE_SIZE; blaze.color.rd = blaze.color.r / BLAZE_LASTS * T_STEP blaze.color.gd = blaze.color.g / BLAZE_LASTS * T_STEP blaze.color.bd = blaze.color.b / BLAZE_LASTS * T_STEP if (accType) { blaze.speed.xd = blaze.speed.x / BLAZE_LASTS * T_STEP; blaze.speed.yd = (blaze.speed.y / BLAZE_LASTS + G) * T_STEP; } else { blaze.speed.xd = 0; blaze.speed.yd = 0; } blaze.innerHTML = this.blazeChar; this._setCSS(blaze); document.body.appendChild(blaze); blazes.push(blaze); } }, getTrack: function(blaze) { var track = document.createElement("div"); track.style.position = "absolute"; track.style.zIndex = 50; track.lasts = TRACK_LASTS track.color = { r: blaze.color.r, g: blaze.color.g, b: blaze.color.b } track.path = { x: blaze.path.x, y: blaze.path.y }; track.size = TRACK_SIZE; track.color.rd = track.color.r / track.lasts * T_STEP; track.color.gd = track.color.g / track.lasts * T_STEP; track.color.bd = track.color.b / track.lasts * T_STEP; track.innerHTML = this.trackChar; this._setCSS(track); document.body.appendChild(track); return track; }, transBlaze: function(blaze) { blaze.color.r -= blaze.color.rd; blaze.color.g -= blaze.color.gd; blaze.color.b -= blaze.color.bd; blaze.path.x += blaze.speed.x * T_STEP; blaze.path.y += blaze.speed.y * T_STEP; blaze.speed.x += blaze.speed.xd; blaze.speed.y += blaze.speed.yd; blaze.lasts -= T_STEP; this._setCSS(blaze); }, transTrack: function(track) { track.color.r -= track.color.rd; track.color.g -= track.color.gd; track.color.b -= track.color.bd; track.lasts -= T_STEP; }, _setCSS: function(obj) { var style = obj.style; style.left = Math.floor(obj.path.x) + "px"; style.top = Math.floor(obj.path.y) + "px"; style.fontSize = obj.size + "px"; style.color = "rgb(" + Math.floor(obj.color.r) + "," + Math.floor(obj.color.g) + "," + Math.floor(obj.color.b) + ")"; } }; function setOut() { var container = []; for (var i = 0; i < TOTAL_FIREWORKS; i++) { container.push(new Fireworks()); } window.setInterval(function() { for (var i = 0; i < TOTAL_FIREWORKS; i++) { container[i].step(); if (container[i].status == Fireworks.DEAD) { container[i].step(); container[i] = new Fireworks(); } } }, 10); } </script> </head> <body onload="setOut();"> </body> </html>
点燃[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值