【编程游戏】贺岁霓虹灯。(第一名奖励10000可用分) 效果图 评分 参观 [目前Firefox中好使,其他浏览器需复制到本地,存为html文件看效果] <html> <head><title>贺岁霓虹灯 -- 新年快乐 -- 作者:zswang</title></head> <style> body{overflow:hidden;background-color:Black;} .bulb{position:absolute;} </style> <body> <script text="text/javascript"> function hsl2color(hsl) { if (hsl.h > 360 || hsl.h < 0 || hsl.s > 100 || hsl.s < 0 || hsl.l > 100 || hsl.l < 0) return "#000000"; var rgb = {r: 0, g: 0, b: 0}; if (hsl.h <= 60) { rgb.r = 255; rgb.g = 255 / 60 * hsl.h; } else if (hsl.h <= 120) { rgb.r = 255 - (255 / 60) * (hsl.h - 60); rgb.g = 255; } else if (hsl.h <= 180) { rgb.g = 255; rgb.b = (255 / 60) * (hsl.h - 120); } else if (hsl.h <= 240) { rgb.g = 255 - (255 / 60) * (hsl.h - 180); rgb.b = 255; } else if (hsl.h <= 300) { rgb.r = (255 / 60) * (hsl.h - 240); rgb.b = 255; } else if (hsl.h <= 360) { rgb.r = 255; rgb.b = 255 - (255 / 60) * (hsl.h - 300); } var sat = Math.abs((hsl.s - 100) / 100); rgb.r = rgb.r - (rgb.r - 128) * sat; rgb.g = rgb.g - (rgb.g - 128) * sat; rgb.b = rgb.b - (rgb.b - 128) * sat; var lum = (hsl.l - 50) / 50; if (lum > 0) { rgb.r = rgb.r + (255 - rgb.r) * lum; rgb.g = rgb.g + (255 - rgb.g) * lum; rgb.b = rgb.b + (255 - rgb.b) * lum; } else if (lum < 0) { rgb.r = rgb.r + rgb.r * lum; rgb.g = rgb.g + rgb.g * lum; rgb.b = rgb.b + rgb.b * lum; } return "#" + ("00000" + (Math.floor(rgb.r) * 256 * 256 + Math.floor(rgb.g) * 256 + Math.floor(rgb.b) ).toString(16)).replace(/^.*(.{6}$)/g, "$1"); } var charDatas = [ "10080A1C7F60004022401444FFFE0A487F4808480A4829884888890828081008", // 新 "080008081FFC1100210041101FF8110011001104FFFE01000100010001000100", // 年 "10801080108010885BFC54885088908810881FFE1080114011201210140E1804", // 快 "002000F01F0010001100110021047FFE01000100092009101108210C45040200" // 乐 ]; function data2Lattice(data) { var result = []; for (var i = 0; i < 16; i++) { var line = parseInt(data.substr(i * 4, 4), 16); var points = []; for (var j = 15; j >= 0; j--) points.push((1 << j & line) != 0); result.push(points); } return result; } function MoveDictate(command) { this.directions = []; this.isBreak = command.indexOf("B") >= 0; this.isTry = command.indexOf("T") >= 0; this.isEddy = command.indexOf("D") >= 0; this.point = [0, 0]; this.max = 1e7; var match = //[(/d+),(/d+)/]/.exec(command); if (match) { this.point[0] = +match[1]; this.point[1] = +match[2]; } var regex = /[nswe]|SW|SE|NE|NW/g; while (match = regex.exec(command)) { this.directions.push({ n: 0, s: 1, w: 2, e: 3, NW: 4, NE: 5, SW: 6, SE: 7}[match[0]]); } } function MagicBox(options) { options = options || {}; this.command = options.command || ""; this.size = options.size || 16; this.moveDictates = []; this.command = this.command.replace(/R/g, this.size - 1); this.current = [0, 0]; var match = //[(/d+),(/d+)/]/.exec(this.command.replace(//{.*?/}/g, "")); if (match) { this.current[0] = +match[1]; this.current[1] = +match[2]; } var regex = //{(.*?)/}/g; while (match = regex.exec(this.command)) this.moveDictates.push(new MoveDictate(match[1])); var dictate = 0; this.paths = []; this.paths.push([this.current[0], this.current[1]]); this.numbers = {}; this.numbers[this.current] = 1; for (var i = 2; i <= this.size * this.size; i++) { var next = [this.current[0], this.current[1]]; for (var j = 0; j < this.moveDictates.length; j++) { if (this.move(this.moveDictates[dictate], next)) { if (this.moveDictates[dictate].isBreak) { if (this.moveDictates[dictate].isEddy) this.moveDictates[dictate].max = 1e7; dictate = (dictate + 1) % this.moveDictates.length; } this.current = [next[0], next[1]]; break; } else { if (this.moveDictates[dictate].isEddy) this.moveDictates[dictate].max = 1e7; dictate = (dictate + 1) % this.moveDictates.length; } } this.numbers[this.current] = i; this.paths.push([this.current[0], this.current[1]]); } } MagicBox.prototype = { offsets: [[0, -1], [0, +1], [-1, 0], [+1, 0], [-1, -1], [+1, -1], [-1, +1], [+1, +1]], // 变化参数 ↑↓←→↖↗↙↘ move: function(moveDictate, dest) { do { var isBrack = true; for (var i = 0; i < moveDictate.directions.length; i++) { if (moveDictate.isEddy && i > moveDictate.max) break; var d = moveDictate.directions[i]; var temp = moveDictate.isTry ? [moveDictate.point[0], moveDictate.point[1]] : [dest[0], dest[1]]; temp[0] += this.offsets[d][0]; temp[1] += this.offsets[d][1]; if (temp[0] < 0 || temp[0] >= this.size) continue; if (temp[1] < 0 || temp[1] >= this.size) continue; if (!this.numbers[temp]) { dest[0] = temp[0]; dest[1] = temp[1]; if (moveDictate.isEddy) moveDictate.max = i; return true; } if (moveDictate.isTry) { moveDictate.point = [temp[0], temp[1]]; isBrack = false; break; } } } while (!isBrack); return false; } } // 霓虹灯 function Neon(options) { options = options || {}; this.interval = options.interval || 100; // 变化间隔时间,单位毫秒 this.parent = options.parent || document.body; // 容器 this.bulbSize = options.bulbSize || 20; this.rowCount = 16; // 行数 this.colCount = 16; // 列数 this.bulbHue = options.bulbHue || 240; this.snakeLength = options.snakeLength || 13; this.bulbs = {}; this.tickCount = 0; this.charIndex = 0 this.lattice = data2Lattice(charDatas[this.charIndex]); this.state = 0; this.magicBoxs = [ new MagicBox({command: "{es}{wn}"}), new MagicBox({command: "{eB}{SW}{sB}{NE}"}), new MagicBox({command: "{SW}{[0,0]esBT}"}), new MagicBox({command: "{SE}{[0,0]eBT}{SE}{[0,0]sBT}"}), new MagicBox({command: "[0,R]{eB}{wnD}{nB}{seD}"}), new MagicBox({command: "{ews}"}) ]; this.magicIndex = 0; this.magicTick = 0; var h = document.body.clientHeight || document.documentElement.clientHeight; var w = document.body.clientWidth || document.documentElement.clientWidth; for (var i = 0; i < this.rowCount; i++) { for (var j = 0; j < this.colCount; j++) { var bulb = new Bulb({ size: this.bulbSize, pos: {x: i * this.bulbSize, y: j * this.bulbSize}, hue: this.bulbHue }); this.bulbs[i + "," + j] = bulb; bulb.lightness = 0; bulb.doChange(); } } } Neon.prototype = { replay: function() { var self = this; setInterval(function() { self.tick(); }, this.interval); }, tick: function() { this.clear(); if (this.tickCount % 10 == 0) { this.bulbHue = Math.random() * 360; for (var i = 0; i < this.rowCount; i++) { for (var j = 0; j < this.colCount; j++) { bulb = this.bulbs[[i, j]]; bulb.hue = this.bulbHue; } } } for (var j = 0; j < this.colCount; j++) { for (var i = 0; i < this.rowCount; i++) { if (this.tickCount + j < 16 || this.tickCount + j >= 16 + 16) continue; if (!this.lattice[i][(j + this.tickCount) % this.rowCount]) continue; var bulb = this.bulbs[[j, i]]; bulb.lightness = 40; bulb.doChange(); } } if (this.tickCount >= 32) { this.charIndex = (this.charIndex + 1) % charDatas.length; this.lattice = data2Lattice(charDatas[this.charIndex]); this.tickCount = 0; } for (var i = 0; i < this.snakeLength; i++) { var paths = this.magicBoxs[this.magicIndex].paths; var bulb = this.bulbs[paths[(i + this.magicTick * 3) % paths.length]]; bulb.lightness = 100 * (i / this.snakeLength); bulb.doChange(); } if (this.magicTick * 3 + this.snakeLength >= 256) { this.magicIndex = (this.magicIndex + 1) % this.magicBoxs.length; this.magicTick = 0; } this.tickCount++; this.magicTick++; }, clear: function() { for (var i = 0; i < this.rowCount; i++) { for (var j = 0; j < this.colCount; j++) { bulb = this.bulbs[[i, j]]; bulb.setLightness(0); } } } } // 灯泡 function Bulb(options) { options = options || {}; this.parent = options.parent || document.body; // 容器 this.pos = options.pos || {}; // 位置 this.hue = options.hue || 100; // 色相 this.size = options.size || 20; // 大小 this.saturation = options.saturation || 100; // 饱和度 this.lightness = options.lightness || 50; // 亮度 this.div = document.createElement("div"); this.div.className = "bulb"; this.div.style.top = this.pos.y + "px"; this.div.style.left = this.pos.x + "px"; this.div.style.width = this.size; this.div.style.height = this.size; this.parent.appendChild(this.div); this.doChange(); } Bulb.prototype = { doChange: function() { this.div.style.backgroundColor = hsl2color( {h: this.hue, s: this.saturation, l: this.lightness} ); }, setLightness: function (value) { if (this.lightness == value) return; this.lightness = value; this.doChange(); } } new Neon().replay(); </script> </body> </html> 参观 [目前Firefox中好使,其他浏览器需复制到本地,存为html文件看效果]