Skip to content

Instantly share code, notes, and snippets.

@hohoonlee
Created February 15, 2019 14:46
Show Gist options
  • Save hohoonlee/c22c67a52baddda72e04d7088545c1b3 to your computer and use it in GitHub Desktop.
Save hohoonlee/c22c67a52baddda72e04d7088545c1b3 to your computer and use it in GitHub Desktop.
한붓그리기 1차
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<table id='t'></table>
<script>
const blockTypes = [0, 1, 2, 3, 4];
const minSelected = 3;
const Block = class {
static getInstance(type = parseInt(Math.random() * 5)) {return new Block(type);}
constructor(type) {
this._type = type;
}
// get image() { return `url('img/icon${this._type}.png');`;}
get image() { return `url('http://www.bsidesoft.com/summer/project/07_tower/img/block${this._type}.png');`;}
get type() { return this._type; }
};
const Game = (()=>{
const [stageWidth, stageHeight] = [8, 8];
const blockSize = 80;
const data = [];
let table;
let startBlock, currBlock, isDown;
const selected = [];
const init = tableId => {
table = document.querySelector(tableId);
for(let i = 0; i < stageHeight; i++) {
const row = [];
data.push(row);
for(let j = 0; j < stageWidth; j++) row[j] = Block.getInstance();
}
table.innerHTML = '';
data.forEach(row=>table.appendChild(row.reduce((tr, block)=>{
tr.appendChild(el('td'));
return tr;
}, el('tr'))));
table.addEventListener('mousedown', down);
table.addEventListener('mouseup', up);
table.addEventListener('mouseleave', up);
table.addEventListener('mousemove', move);
render();
};
const getBlock = (x,y)=> {
const {top:T, left:L} = table.getBoundingClientRect();
if(x < L || x > (L + blockSize * stageWidth) || y < T || y > (T + blockSize * stageHeight)) return null;
return data[parseInt((y-T)/blockSize)][parseInt((x-L)/blockSize)];
};
const isNext = curr => {
let r0, c0, r1, c1, cnt = 0;
data.some((row, i)=>{
let j;
if((j = row.indexOf(currBlock)) !== -1) r0 = i, c0 = j, cnt++; //마지막 선택블럭 위치
if((j = row.indexOf(curr)) !== -1) r1 = i, c1 = j, cnt++; //현재의 선택블럭 위치
return cnt === 2;
});
return curr != currBlock && Math.abs(r0 - r1) <= 1 && Math.abs(c0 - c1) <= 1;
}
const down = ({pageX:x, pageY:y})=>{
if(isDown) return;
const curr = getBlock(x,y);
if(!curr) return;
isDown = true;
selected.length = 0;
selected[0] = startBlock = currBlock = curr;
render();
};
const move = ({pageX:x, pageY:y})=>{
if(!isDown) return;
const curr = getBlock(x,y);
if(!curr || curr.type !== startBlock.type || !isNext(curr)) return;
if(selected.indexOf(curr) === -1) {
selected.push(curr);
}else if(selected[selected.length -2] === curr) {
selected.pop();
}
currBlock = curr;
render();
};
const up = ()=> selected.length >= minSelected?remove():reset();
const reset = ()=>{
startBlock = currBlock = null;
selected.length = 0;
isDown = false;
render();
}
const remove = ()=> {
data.forEach(r=>{
selected.forEach(v=>{
let i;
if((i = r.indexOf(v)) != -1) r[i] = null;
});
});
render();
setTimeout(drop, 300);
}
const drop = () => {
let isNext = false;
for(let j = 0; j < stageWidth; j++) {
for(let i = stageHeight -1; i > -1; i--) {
if(!data[i][j] && i) {
let k = i, isEmpty = true;
while(k--) {
if(data[k][j]) {
isEmpty = false;
break;
}
}
if(isEmpty) break;
isNext = true;
while(i--) {
data[i+1][j] = data[i][j];
data[i][j] = null;
}
break;
}
}
}
render();
isNext ? setTimeout(drop, 300):readyToFill();
};
const fills = [];
let fillCnt = 0;
const readyToFill = () => {
fills.length = 0;
data.some(row=>{
if(row.indexOf(null) === -1) return true;
const r = [...row].fill(null);
fills.push(r);
row.forEach((v,i)=>!v && (r[i] = Block.getInstance()));
});
fillCnt = 0;
setTimeout(fill, 300);
};
const fill = () => {
if(fillCnt > fills.length) {
isDown = false;
return;
}
for(let i = 0; i < fillCnt; i++) {
fills[fills.length -i -1].forEach((v,j)=>{
if(v) data[fillCnt - i -1][j] = v;
});
}
fillCnt++;
render();
setTimeout(fill, 300);
}
const el = tag => document.createElement(tag);
const render = () => {
data.forEach((row, i)=>{
const tr = table.rows[i];
row.forEach((block, j)=>{
tr.cells[j].style.cssText = `
${block?`background:${block.image};`:''};
background-size:${blockSize}px;
width:${blockSize}px;
height:${blockSize}px;
cursor:pointer;
background-color:${selected.indexOf(block) >= 0?'yellow':'white'};
`;
});
});
// table.innerHTML = '';
// data.forEach(row=>table.appendChild(row.reduce((tr, block)=>{
// tr.appendChild(el('td')).style.cssText = `
// ${block?`background:${block.image};`:''};
// background-size:${blockSize}px;
// width:${blockSize}px;
// height:${blockSize}px;
// cursor:pointer;
// `;
// return tr;
// }, el('tr'))));
};
return init;
})();
Game('#t');
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment