테트리스 턴 35 (3)
본문
function erase() { let index = 0; if (position.x >= 0 && position.x <= width - 1) {
if (position.y >= -3 && position.y <= height - 1) {
for (let y = position.y; y < position.y + 3; y++) {
for (let x = position.x; x < position.x + 3;
x++, index++) {
if (current[index] == 1) {
let id = "square_x" + x + "y" + y;
let square = document.getElementById(id);
if (square) {
if (true) { // well[x] && well[y]
well[x][y] = 0;
if (x == 0 || x == width - 1 ) { }
else {
square.style.backgroundColor
= color.background;
}
}
}
}
}
}
}
}
}
타락한 블록을 우물에 붙여 넣기
블록이 "타락"한 것으로 간주되면 블록이 물리적으로 웰 어레이에 붙여집니다.
이 솔리드 블록은 well 배열에서 1이 됩니다. 이것은 다음 번에 다음 테트로미노에서 충돌을 검사 할 때 (위에서 이미 작성한 충돌 감지 알고리즘을 사용하여)이 영역은 솔리드로 간주되며 블록은 다른 블록과 충돌합니다.
벽돌이 벽이나 다른 벽돌과 충돌하면 우물에“붙여 넣기”되어 고체로 표시됩니다.
행 분리 알고리즘
이것은 테트리스와 관련하여 가장 복잡한 코드입니다. 이 알고리즘은
1) 제거 할 행이 있는지 확인합니다.
2) 전체 행을 제거하지 않고 웰을 다시 빌드하여 취소하고 블록 축소 환상을 만듭니다.
내 버전에서는 블록이 지워진 것을 시각적으로 명확하게 하기 위해 강조 애니메이션을 추가했습니다. 이 데모의 최종 버전에서 볼 수 있습니다.
단 몇 줄의 코드 로이 기능을 최적화 된 미친 버전으로 만들 수 있습니다. 그러나 그렇게 하면 논리가 추상화 되어 따르고 배우기가 어려워 질 것입니다.
배열 및 for 루프와 같은 간단한 JavaScript 구문을 사용하여 논리를 살펴 보는 것이 좋습니다. 나중에 코드를 더 짧게 만들도록 최적화 할 수 있습니다.
// Check if a row needs to be cleared
function clear_row() {
// Placeholder for new rows
let placeholder = [];
// How many rows cleared?
let rows_cleared = 0;
// Scan the well one row at a time and capture any
// non-filled rows in placeholder
// (except the last row)
for (let y = 0; y < height - 1; y++) { let start = y * width;
let scanned = scan_row(y);
let total = scanned[0];
let row_data = scanned[1]; // Skip all horizontal rows that are completely filled
if (total != width) { // Memorize only uncleared rows
let len = placeholder.length;
placeholder[len] = row_data; } else {
start_highlight(y);
rows_cleared++;
}
}
// If at least one row was cleared, update the well
if (rows_cleared > 0) { // Clear the well, except last row (well's bottom)
for (let y = 0; y < height - 1; y++) { // Clear all except walls ([0] and [width - 1])
for (let x = 1; x < width - 1; x++) {
well[x][y] = 0; // Paint empty square
let square =
document.getElementById("square_x" + x + "y" + y);
if (square)
square.style.backgroundColor = color.background;
}
}
// Paste captured placeholder rows onto the well
// but from bottom up
let r = height - 2;
for (let i = placeholder.length - 1; i > 0; i--) {
let row = placeholder[i];
for (let x = 0; x < width; x++) {
if (row[x] != 0) {
well[x][r] = 3;
if (x != 0 && x != width - 1) {
let square =
document.getElementById("square_x"+x+"y"+r);
if (square)
square.style.backgroundColor = color.solid;
}
}
}
r--;
}
}
}
테트리스 인 더 다크 (소스 코드에 포함되어 있습니다!)
전략 비디오 게임에는 전쟁이 필요합니다. 탐험 되지 않은 지형 영역을 검게 표시합니다.
빛 추가
밝은 점을 만들기 위해 먼저 우물과 동일한 치수를 공유하는 보조 그리드를 만들어 오버레이로 사용했습니다. 기본적으로 해당 그리드의 모든 DIV 사각형은 검은 색과 불투명도 1로 설정되었습니다.
보조 그리드의 각 사각형에는 fog_x1y3의 ID가 할당되었습니다 (해당 그리드의 x = 1 및 y = 3에서 사각형에 액세스하려는 경우).
그런 다음 라이트 스팟 데이터를 별도의 배열에 저장했습니다.
// light position
let light = { x: 0, y: 0 };// lightspot data
let light_mask = [
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,4,4,0,0,0,0,0,0,
0,0,0,2,3,4,5,5,4,3,2,0,0,0,
0,0,2,3,4,5,6,6,5,4,3,2,0,0,
0,2,3,4,5,6,7,7,6,5,4,3,2,0,
0,3,4,5,6,7,8,8,7,6,5,4,3,0,
0,4,5,6,7,8,9,9,8,7,6,5,4,0,
0,4,5,6,7,8,9,9,8,7,6,5,4,0,
0,3,4,5,6,7,8,8,7,6,5,4,3,0,
0,2,3,4,5,6,7,7,6,5,4,3,2,0,
0,0,2,3,4,5,6,6,5,4,3,2,0,0,
0,0,0,2,3,4,5,5,4,3,2,0,0,0,
0,0,0,0,0,0,4,4,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
];
여기서 0에서 9 사이의 값은 0.0-0.9 CSS 불투명도를 나타냅니다.
이번에는 draw_light() 함수를 사용하여 간단한 for-loop를 사용하여 이 데이터를 어두운 격자에 붙여 넣었습니다.
function draw_light() {
let index = 0;
for (let y = 0; y < 14; y++) {
for (let x = 0; x < 14; x++, index++) {
let posx = x + position.x;
let posy = y + position.y;
let id = "fog_x" + (posx - 6) + "y" + (posy - 6);
let square = document.getElementById(id);
if (square) {
let type = light_mask[index];
if (type == 9) square.style.opacity = '0';
if (type == 8) square.style.opacity = '0.1';
if (type == 7) square.style.opacity = '0.2';
if (type == 6) square.style.opacity = '0.3';
if (type == 5) square.style.opacity = '0.4';
if (type == 4) square.style.opacity = '0.5';
if (type == 3) square.style.opacity = '0.7';
if (type == 2) square.style.opacity = '0.8';
if (type == 1) square.style.opacity = '0.9';
if (type == 0) square.style.opacity = '1.0';
}
}
}
}
이로 인해 빛이 어둠으로 사라지는 환상이 생겼습니다.
주요 행 애니메이션
행 구분 애니메이션은 다른 모든 것과 별도로 수행됩니다. 우물의 모든 높이에서 긴 수평 DIV 요소의 목록 일 뿐입니다.
행을 끊어야 할 경우 clear_row () 함수 (앞에 표시)는 지워야 하는 각 행의 Y 좌표를 추적합니다.
그런 다음 setInterval 함수는 해당 DIV의 상태가 1인지 판별합니다. 그렇다면 DIV를 흰색 배경색으로 설정하고 시간에 따른 불투명도를 줄여 애니메이션을 재생합니다.
최종 결과
같은 주제를 오랫동안 사용하면 약간 지루 해져 깨어나는 혁신을 하게 됩니다.
결론 : 게임 개발자로서 나는 약간의 전쟁의 안개를 추가하여 이 재미있는 버전의 테트리스를 만들기로 결정했습니다. 모든 실험이 좋은 것은 아닙니다. 그러나 결과에 매우 만족합니다.
소스 코드? Tetris GitHub 리포지토리에서 가져올 수 있습니다.
- 이전글자신 만의 React 커스텀 훅 작성 (1) 19.08.09
- 다음글테트리스 턴 35 (2) 19.08.09