config.scoreLevel.innerHTML = computed.level;
},
/**
- 点击事件操作
*/
mouseClick: function() {
var tileSet = config.tileSet,
choose = computed.choose,
baseScore = config.baseScore,
stepScore = config.stepScore,
el = config.el,
self = this,
len = choose.length;
if (!computed.flag || len <= 1) {
return;
}
computed.flag = false;
computed.tempTile = null;
var score = 0;
for (var i = 0; i < len; i++) {
score += baseScore + i * stepScore;
}
new CountUp(config.scoreCurrent, computed.totalScore, computed.totalScore += score).start();
for (var i = 0; i < len; i++) {
setTimeout(function(i) {
tileSet[choose[i].row][choose[i].col] = null;
el.removeChild(choose[i]);
}, i * 100, i);
}
setTimeout(function() {
self.move();
//判断结束
setTimeout(function() {
if (self.isFinish()) {
self.clear();
if (computed.totalScore >= config.targetScore) {
new CountUp(config.scoreTarget, config.targetScore, config.targetScore += (computed.level - 1) * computed
.stepTargetScore)
.start();
new CountUp(config.scoreLevel, computed.level, computed.level += 1).start();
alert(“恭喜获胜”);
console.log(“恭喜获胜”)
} else {
config.targetScore = config.scoreTarget = 2000;
computed.level = computed.totalScore = 0;
alert(“游戏失败”);
console.log(“游戏失败”)
}
computed.flag = true;
} else {
choose = [];
computed.flag = true; //在所有动作都执行完成之后释放锁
self.mouseOver(computed.tempTile);
}
}, 300 + choose.length * 150);
}, choose.length * 100);
},
/**
- 闯关成功或失败清除(清除二维数组和el的子节点)操作
*/
clear: function() {
var tileSet = config.tileSet,
rows = tileSet.length,
el = config.el;
var temp = [];
for (var i = rows - 1; i >= 0; i–) {
for (var j = tileSet[i].length - 1; j >= 0; j–) {
if (tileSet[i][j] === null) {
continue;
}
temp.push(tileSet[i][j])
tileSet[i][j] = null;
}
}
for (var k = 0; k < temp.length; k++) {
setTimeout(function(k) {
el.removeChild(temp[k]);
if(k>=temp.length-1){
setTimeout(function(k) {
new PopStar();
},1000)
}
}, k * 100, k);
}
},
/**
-
是否游戏结束
-
@returns {boolean}
*/
isFinish: function() {
var tileSet = config.tileSet,
rows = tileSet.length;
for (var i = 0; i < rows; i++) {
var row = tileSet[i].length;
for (var j = 0; j < row; j++) {
var temp = [];
this.checkLink(tileSet[i][j], temp);
if (temp.length > 1) {
return false;
}
}
}
return true;
},
/**
- 消除星星后的移动操作
*/
move: function() {
var rows = config.tableRows,
tileSet = config.tileSet;
//向下移动
for (var i = 0; i < rows; i++) {
var pointer = 0; //pointer指向小方块,当遇到null的时候停止,等待上面的小方块落到这里来
for (var j = 0; j < rows; j++) {
if (tileSet[j][i] != null) {
if (j !== pointer) {
tileSet[pointer][i] = tileSet[j][i];
tileSet[j][i].row = pointer;
tileSet[j][i] = null;
}
pointer++;
}
}
}
//横向移动(最下面一行其中有无空列)
for (var i = 0; i < tileSet[0].length;) {
if (tileSet[0][i] == null) {
for (var j = 0; j < rows; j++) {
tileSet[j].splice(i, 1);
}
continue;
}
i++;
}
this.refresh()
},
/**
-
鼠标移入时的闪烁操作
-
@param obj
*/
mouseOver: function(obj) {
if (!computed.flag) { //处于锁定状态不允许有操作
computed.tempTile = obj;
return;
}
this.clearFlicker();
var choose = [];
this.checkLink(obj, choose);
computed.choose = choose;
if (choose.length <= 1) {
choose = [];
return;
}
this.flicker(choose);
this.computeScore(choose);
},
/**
-
计算已选中的星星分数
-
@param arr
*/
computeScore: function(arr) {
var score = 0,
len = arr.length,
baseScore = config.baseScore,
stepScore = config.stepScore;
for (var i = 0; i < len; i++) {
score += baseScore + i * stepScore
}
if (score <= 0) {
return;
}
computed.score = score;
config.scoreSelect.style.opacity = ‘1’;
config.scoreSelect.innerHTML = arr.length + "连消 " + score + “分”;
setTimeout(function() {
config.scoreSelect.style.opacity = ‘0’;
}, 1200)
},
/**
- 鼠标移出时的消除星星闪烁的操作
*/
clearFlicker: function() {
var tileSet = config.tileSet;
for (var i = 0; i < tileSet.length; i++) {
for (var j = 0; j < tileSet[i].length; j++) {
var div = tileSet[i][j];
if (div === null) {
continue;
}
div.classList.remove(“scale”);
}
}
},
/**
-
星星闪烁
-
@param arr
*/
flicker: function(arr) {
for (var i = 0; i < arr.length; i++) {
var div = arr[i];
div.classList.add(“scale”);
}
},
/**
-
检查鼠标移入的这个星星是否有相连着的相同的星星,
-
@param obj star
-
@param arr choose
*/
checkLink: function(obj, arr) {
if (obj === null) {
return;
}
arr.push(obj);
/**
-
检查左边方块是否可以加入到选入的可消除星星行列:
-
选中的星星不能是最左边的,
-
选中的星星左边要有星星,
-
选中的星星左边的星星的跟选中的星星一样,
-
选中的星星左边的星星没有被选中过
*/
var tileSet = config.tileSet,
rows = config.tableRows;
if (obj.col > 0 && tileSet[obj.row][obj.col - 1] && tileSet[obj.row][obj.col - 1].number === obj.number && arr.indexOf(
tileSet[obj.row][obj.col - 1]) === -1) {
this.checkLink(tileSet[obj.row][obj.col - 1], arr);
}
if (obj.col < rows - 1 && tileSet[obj.row][obj.col + 1] && tileSet[obj.row][obj.col + 1].number === obj.number &&
arr.indexOf(tileSet[obj.row][obj.col + 1]) === -1) {
this.checkLink(tileSet[obj.row][obj.col + 1], arr);
}
if (obj.row < rows - 1 && tileSet[obj.row + 1][obj.col] && tileSet[obj.row + 1][obj.col].number === obj.number &&
arr.indexOf(tileSet[obj.row + 1][obj.col]) === -1) {
this.checkLink(tileSet[obj.row + 1][obj.col], arr);
}
if (obj.row > 0 && tileSet[obj.row - 1][obj.col] && tileSet[obj.row - 1][obj.col].number === obj.number && arr.indexOf(
tileSet[obj.row - 1][obj.col]) === -1) {
this.checkLink(tileSet[obj.row - 1][obj.col], arr);
}
},
/**
- 初始化二维数组
*/
initTileSet: function() {
var rows = config.tableRows,
arr = config.tileSet;
for (var i = 0; i < rows; i++) {
arr[i] = [];
for (var j = 0; j < rows; j++) {
arr[i][j] = [];
}
}
},
/**
- 初始化el的子节点
*/
initBlocks: function() {
var tileSet = config.tileSet,
self = this,
el = config.el,
cols = tileSet.length;
for (var i = 0; i < cols; i++) {
var rows = tileSet[i].length;
for (var j = 0; j < rows; j++) {
var tile = this.createBlock(Math.floor(Math.random() * 5), i, j);
tile.onmouseover = function() {
self.mouseOver(this)
};
tile.onclick = function() {
self.mouseClick();
};
tileSet[i][j] = tile;
el.appendChild(tile);
}
}
this.refresh()
},
/**
- 渲染el的子节点
*/
refresh: function() {
var tileSet = config.tileSet;
for (var i = 0; i < tileSet.length; i++) {
var row = tileSet[i].length;
for (var j = 0; j < row; j++) {
var tile = tileSet[i][j];
if (tile == null) {
continue;
}
tile.row = i;
tile.col = j;
tile.style.left = tileSet[i][j].col * config.tileWidth + “rem”;
tile.style.bottom = tileSet[i][j].row * config.tileHeight + “rem”;
tile.style.backgroundImage = “url('./images/” + tileSet[i][j].number + “.png’)”;
}
}
},
/**
-
创建星星子节点的函数
-
@param number
-
@param row
-
@param col
-
@returns {HTMLElement}
*/
createBlock: function(number, row, col) {
return new Block(number, row, col);
},
};
PopStar.prototype.init.prototype = PopStar.prototype;
window.PopStar = PopStar;
})();
index.js
(function()
{function u(a,b,c)
{
var d=document.createElement(“li”);
d.width=e.tileWidth;d.height=e.tileHeight;
d.number=a;
d.row=b;d.col=c;return d}
function m()
{return new m.prototype.init
}
var e={tileWidth:.75,tileHeight:.75,tileSet: [],
tableRows:10,baseScore:5,
stepScore:10,
targetScore:2E3,
el:document.querySelector(“#starList”),
scoreTarget:document.querySelector(“#scoreTarget”),
scoreCurrent:document.querySelector(“#scoreCurrent”),
scoreSelect:document.querySelector(“#scoreSelect”),
scoreLevel:document.querySelector(“#scoreLevel”)
},
n=!0,t=[],p=0,r=null,q=1;
m.prototype={
init:function(){this.initTable()
}
,initTable:function(){
this.initScore();
this.initTileSet();
this.initBlocks()
}
,
initScore:function(){
(new CountUp(e.scoreTarget,e.targetScore,e.targetScore)).start();
e.scoreCurrent.innerHTML=p;e.scoreLevel.innerHTML=q
},
mouseClick:function(){
var a=e.tileSet,b=t,c=e.baseScore,d=e.stepScore,f=e.el,g=this,h=b.length;if(n&&!(1>=h)){
n=!1;r=null;
for(var l=0,k=0;
k<h;k++)l+=c+k*d;(new CountUp(e.scoreCurrent,p,p+=l)).start();
for(k=0;k<h;k++)
setTimeout(function©{a[b[c].row][b[c].col]=
null;
f.removeChild(b[c])},100*k,k);
setTimeout(function(){g.move();
setTimeout(function()
{g.isFinish()?(g.clear(),p>=e.targetScore?((new CountUp(e.scoreTarget,e.targetScore,e.targetScore+=1E3*(q-1))).start(),(new CountUp(e.scoreLevel,q,q+=1)).start(),alert(“\u606d\u559c\u83b7\u80dc”),console.log(“\u606d\u559c\u83b7\u80dc”)):(e.targetScore=e.scoreTarget=2E3,q=p=0,alert(“\u6e38\u620f\u5931\u8d25”),console.log(“\u6e38\u620f\u5931\u8d25”)),n=!0):(b=[],n=!0,g.mouseOver®)},300+150b.length)},100b.length)}},
clear:function()
{for(var a=e.tileSet,b=e.el,c=[],
d=a.length-1;0<=d;d–)
for(var f=a[d].length-1;0<=f;f–)
null!==a[d][f]&&(c.push(a[d][f]),a[d][f]=null);
for(a=0;a<c.length;a++)
setTimeout(function(a)
{b.removeChild(c[a]);
a>=c.length-1&&setTimeout(function(a){new m},1E3)},100*a,a)},isFinish:function()
{for(var a=e.tileSet,b=a.length,c=0;c<b;c++)
for(var d=a[c].length,f=0;f<d;f++)
{var g=[];this.checkLink(a[c][f],g);
if(1<g.length)
return!1}return!0},
move:function()
{for(var a=e.tableRows,b=e.tileSet,c=0;
c<a;c++)for(var d=
0,f=0;f<a;f++)null!=b[f][c]&&(f!==d&&(b[d][c]=b[f][c],b[f][c].row=d,b[f][c]=null),d++);
for(c=0;c<b[0].length;
)if(null==b[0][c])
for(f=0;f<a;f++)b[f].splice(c,1);else c++;this.refresh()},
mouseOver:function(a){if(n)
{this.clearFlicker();
var b=[];
this.checkLink(a,b);
t=b;1>=b.length||(this.flicker(b),this.computeScore(b))}
else r=a
},
computeScore:function(a)
{for(var b=0,c=a.length,d=e.baseScore,f=e.stepScore,g=0;
g<c;g++)b+=d+g*f;
0>=b||(e.scoreSelect.style.opacity=“1”,e.scoreSelect.innerHTML=a.length+"\u8fde\u6d88 "+
b+“\u5206”,setTimeout(function(){
e.scoreSelect.style.opacity=“0”},1200))
},clearFlicker:function(){
for(var a=e.tileSet,b=0;b<a.length;b++)
for(var c=0;c<a[b].length;c++){var d=a[b][c];null!==d&&d.classList.remove(“scale”)}},flicker:function(a){for(var b=0;b<a.length;b++)a[b].classList.add(“scale”)
},
checkLink:function(a,b){
if(null!==a){
b.push(a);var c=e.tileSet,d=e.tableRows;0<a.col&&c[a.row][a.col-1]&&c[a.row][a.col-1].number=a.number&&-1=b.indexOf(c[a.row][a.col-1])&&this.checkLink(c[a.row][a.col-
1],b);a.col<d-1&&c[a.row][a.col+1]&&c[a.row]
[a.col+1].number=a.number&&-1=b.indexOf(c[a.row][a.col+1])&&this.checkLink(c[a.row][a.col+1],b);a.row<d-1&&c[a.row+1][a.col]&&c[a.row+1][a.col].number=a.number&&-1=b.indexOf(c[a.row+1][a.col])&&this.checkLink(c[a.row+1][a.col],b);0<a.row&&c[a.row-1][a.col]&&c[a.row-1][a.col].number=a.number&&-1=b.indexOf(c[a.row-1][a.col])&&this.checkLink(c[a.row-1][a.col],b)}},
initTileSet:function(){
for(var a=e.tableRows,b=e.tileSet,c=0;c<a;c++){b[c]=[];
for(var d= 0;d<a;d++)b[c][d]=[]}},
initBlocks:function()
{
for(var a=e.tileSet,b=this,c=e.el,d=a.length,f=0;f<d;f++)
for(var g=a[f].length,h=0;h<g;h++){
var l=this.createBlock(Math.floor(5*Math.random()),f,h);
l.οnmοuseοver=function(){b.mouseOver(this)};
l.οnclick=function(){b.mouseClick()};
a[f][h]=l;
c.appendChild(l)}
this.refresh()},
refresh:function()
{for(var a=e.tileSet,b=0;b<a.length;b++)
for(var c=a[b].length,d=0;d<c;d++)
{var f=a[b][d];
null!=f&&(f.row=b,f.col=d,f.style.left=a[b][d].col*e.tileWidth+“rem”,f.style.bottom=
a[b][d].row*e.tileHeight+“rem”,f.style.backgroundImage=“url('./images/”+a[b][d].number+“.png’)”)
}
}
,createBlock:function(a,b,c){return new u(a,b,c)
}
}
;m.prototype.init.prototype=m.prototype;window.PopStar=m
})();
resize.js
// JavaScript Document
(function px2rem(doc, win) {
var docEl = doc.documentElement,
resizeEvt = ‘orientationchange’ in window ? ‘orientationchange’ : ‘resize’,
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
docEl.style.fontSize = 100 * (clientWidth / 750) + ‘px’;
/*
-
100 -> html,body { font-size:100px; }
-
750 -> 此处以 iPhone6 两倍设计稿 宽度750px 布局页面
-
根据具体情况改变这两个数值
*/
};
if (!doc.addEventListener) return;
// 窗口大小发生变化,初始化
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener(‘DOMContentLoaded’, recalc, false);
//防止在html未加载完毕时执行,保证获取正确的页宽
setTimeout(function(){
px2rem(doc, win);
}, 200);
})(document, window);
countUp.js
(function(root, factory) {
if (typeof define === ‘function’ && define.amd) {
define(factory);
} else if (typeof exports === ‘object’) {
module.exports = factory(require, exports, module);
} else {
root.CountUp = factory();
}
}(this, function(require, exports, module) {
/*
countUp.js
by @inorganik
*/
// target = id of html element or var of previously selected html element where counting occurs
// startVal = the value you want to begin at
// endVal = the value you want to arrive at
// decimals = number of decimal places, default 0
// duration = duration of animation in seconds, default 2
// options = optional object of options (see below)
var CountUp = function(target, startVal, endVal, decimals, duration, options) {
var self = this;
self.version = function () { return ‘1.9.3’; };
// default options
self.options = {
useEasing: true, // toggle easing
useGrouping: true, // 1,000,000 vs 1000000
separator: ‘,’, // character to use as a separator
decimal: ‘.’, // character to use as a decimal
easingFn: easeOutExpo, // optional custom easing function, default is Robert Penner’s easeOutExpo
formattingFn: formatNumber, // optional custom formatting function, default is formatNumber above
prefix: ‘’, // optional text before the result
suffix: ‘’, // optional text after the result
numerals: [] // optionally pass an array of custom numerals for 0-9
};
// extend default options with passed options object
if (options && typeof options === ‘object’) {
for (var key in self.options) {
if (options.hasOwnProperty(key) && options[key] !== null) {
self.options[key] = options[key];
}
}
}
if (self.options.separator === ‘’) {
self.options.useGrouping = false;
}
else {
// ensure the separator is a string (formatNumber assumes this)
self.options.separator = ‘’ + self.options.separator;
}
// make sure requestAnimationFrame and cancelAnimationFrame are defined
// polyfill for browsers without native support
// by Opera engineer Erik Möller
var lastTime = 0;
var vendors = [‘webkit’, ‘moz’, ‘ms’, ‘o’];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+‘RequestAnimationFrame’];
window.cancelAnimationFrame = window[vendors[x]+‘CancelAnimationFrame’] || window[vendors[x]+‘CancelRequestAnimationFrame’];
}
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}
function formatNumber(num) {
var neg = (num < 0),
x, x1, x2, x3, i, len;
num = Math.abs(num).toFixed(self.decimals);
num += ‘’;
x = num.split(‘.’);
x1 = x[0];
x2 = x.length > 1 ? self.options.decimal + x[1] : ‘’;
if (self.options.useGrouping) {
x3 = ‘’;
for (i = 0, len = x1.length; i < len; ++i) {
if (i !== 0 && ((i % 3) === 0)) {
x3 = self.options.separator + x3;
}
x3 = x1[len - i - 1] + x3;
}
x1 = x3;
}
// optional numeral substitution
if (self.options.numerals.length) {
x1 = x1.replace(/[0-9]/g, function(w) {
return self.options.numerals[+w];
})
x2 = x2.replace(/[0-9]/g, function(w) {
return self.options.numerals[+w];
})
}
return (neg ? ‘-’ : ‘’) + self.options.prefix + x1 + x2 + self.options.suffix;
}
// Robert Penner’s easeOutExpo
function easeOutExpo(t, b, c, d) {
return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b;
}
function ensureNumber(n) {
return (typeof n === ‘number’ && !isNaN(n));
}
self.initialize = function() {
if (self.initialized) return true;
self.error = ‘’;
self.d = (typeof target === ‘string’) ? document.getElementById(target) : target;
if (!self.d) {
self.error = ‘[CountUp] target is null or undefined’
return false;
}
self.startVal = Number(startVal);
self.endVal = Number(endVal);
// error checks
if (ensureNumber(self.startVal) && ensureNumber(self.endVal)) {
self.decimals = Math.max(0, decimals || 0);
self.dec = Math.pow(10, self.decimals);
self.duration = Number(duration) * 1000 || 2000;
self.countDown = (self.startVal > self.endVal);
self.frameVal = self.startVal;
self.initialized = true;
return true;
}
else {
self.error = ‘[CountUp] startVal (’+startVal+‘) or endVal (’+endVal+‘) is not a number’;
return false;
}
};
// Print value to target
self.printValue = function(value) {
var result = self.options.formattingFn(value);
if (self.d.tagName === ‘INPUT’) {
this.d.value = result;
}
else if (self.d.tagName === ‘text’ || self.d.tagName === ‘tspan’) {
this.d.textContent = result;
}
else {
this.d.innerHTML = result;
}
};
self.count = function(timestamp) {
if (!self.startTime) { self.startTime = timestamp; }
self.timestamp = timestamp;
var progress = timestamp - self.startTime;
self.remaining = self.duration - progress;
// to ease or not to ease
if (self.options.useEasing) {
if (self.countDown) {
self.frameVal = self.startVal - self.options.easingFn(progress, 0, self.startVal - self.endVal, self.duration);
} else {
self.frameVal = self.options.easingFn(progress, self.startVal, self.endVal - self.startVal, self.duration);
}
} else {
if (self.countDown) {
self.frameVal = self.startVal - ((self.startVal - self.endVal) * (progress / self.duration));
} else {
self.frameVal = self.startVal + (self.endVal - self.startVal) * (progress / self.duration);
}
}
// don’t go past endVal since progress can exceed duration in the last frame
if (self.countDown) {
self.frameVal = (self.frameVal < self.endVal) ? self.endVal : self.frameVal;
} else {
self.frameVal = (self.frameVal > self.endVal) ? self.endVal : self.frameVal;
}
// decimal
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
f.startVal - self.endVal, self.duration);
} else {
self.frameVal = self.options.easingFn(progress, self.startVal, self.endVal - self.startVal, self.duration);
}
} else {
if (self.countDown) {
self.frameVal = self.startVal - ((self.startVal - self.endVal) * (progress / self.duration));
} else {
self.frameVal = self.startVal + (self.endVal - self.startVal) * (progress / self.duration);
}
}
// don’t go past endVal since progress can exceed duration in the last frame
if (self.countDown) {
self.frameVal = (self.frameVal < self.endVal) ? self.endVal : self.frameVal;
} else {
self.frameVal = (self.frameVal > self.endVal) ? self.endVal : self.frameVal;
}
// decimal
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-NvnMWuyP-1715487636731)]
[外链图片转存中…(img-QVBajEqp-1715487636731)]
[外链图片转存中…(img-LCJP8pEW-1715487636732)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!