Skip to content

Instantly share code, notes, and snippets.

@yunseop-kim
Last active February 17, 2019 15:40
Show Gist options
  • Save yunseop-kim/7f7c6d25d8a8496f5c28e4e4241d2ea7 to your computer and use it in GitHub Desktop.
Save yunseop-kim/7f7c6d25d8a8496f5c28e4e4241d2ea7 to your computer and use it in GitHub Desktop.
codespitz-s80-01
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Summer's Tower</title>
</head>
<body>
<style>
@keyframes blink {
50% {
opacity: 0.7;
}
}
.blink {
animation: blink 1s linear infinite;
}
table {
border-collapse: collapse;
margin: 30px auto 0
}
td {
background-size: contain;
background-position: center;
background-repeat: no-repeat;
user-select: none;
touch-callout: none
}
</style>
<section style="text-align:center">
<h1 style="color:#208AFB">BSIDE TOWER JAM</h1>
<table id="stage"></table>
</section>
<script>
'use strict';
const Game = (() => {
const Block = class {
static GET(type = parseInt(Math.random() * 5)) { return new Block(type); }
constructor(type) {
this._type = type;
}
get image() { return `url('http://www.bsidesoft.com/summer/project/07_tower/img/block${this._type}.png')`; }
get type() { return this._type; }
}
const column = 8, row = 8, blockSize = 80;
const data = [];
let table;
let startBlock, currBlock, isDown;
const selected = [];
const getBlock = (x, y) => {
const { top: T, left: L } = table.getBoundingClientRect();
if (x < L || x > (L + blockSize * row) || y < T || y > (T + blockSize * column)) 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 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 < column; j++) {
for (let i = row - 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.GET()));
});
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 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 > 2 ? remove() : reset();
const el = tag => document.createElement(tag)
const cellStyle = block => `
${block ? `background:${block.image};` : ""}
${selected.includes(block) ? "background-color: yellow;" : ""}
width:${blockSize}px;
height:${blockSize}px;
cursor:pointer;`;
const render = _ => {
if (table.innerHTML === '') {
data.forEach(row => table.appendChild(row.reduce((tr, block) => {
tr.appendChild(el('td')).style.cssText = cellStyle(block);
return tr;
}, el('tr'))));
} else {
data.forEach((row, i) => {
const tr = table.childNodes[i];
tr.childNodes.forEach((td, j) => {
const block = row[j];
td.style.cssText = cellStyle(block);
})
})
}
};
return tid => {
table = document.querySelector(tid);
for (let i = 0; i < row; i++) {
const r = [];
data.push(r);
for (let j = 0; j < column; j++) r[j] = Block.GET();
}
table.addEventListener('mousedown', down);
table.addEventListener('mouseup', up);
table.addEventListener('mouseleave', up);
table.addEventListener('mousemove', move);
render();
};
})();
Game('#stage');
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment