라라리라
2023.10.17 / Step 6 [DOM_테트리스] - 코딩 70 일차 본문
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tetris Game</title>
<style>
#center {
margin: 0 auto;
text-align: center;
}
#myTetris {
border-collapse: collapse;
}
#myTetris td {
width: 30px;
height: 30px;
}
#tetnext {
margin: 0 auto;
border-collapse: collapse;
text-align: left;
vertical-align: top;
}
#tet td {
border: 1px solid black;
width: 50px;
height: 30px;
}
#nextblock {
border-collapse: collapse;
}
#nextblock td {
width: 30px;
height: 30px;
border: 1px solid black;
}
.gray { background-color: #3a3a3a; }
.green { background-color: green; }
.red { background-color: red; }
.purple { background-color: purple; }
.orange { background-color: orange; }
.blue { background-color: blue; }
.yellow { background-color: yellow; }
.skyblue { background-color: skyblue; }
.white { background-color: black; }
</style>
</head>
<body>
<table id="center">
<tr>
<td>
<h1>테트리스</h1>
</td>
</tr>
<tr>
</td>
<td id="tetrisCenter"></td>
<td id="tetnext">
<h3>TETRIS</h3>
<h4 id="tetscore">Score : 0</h4>
<h4 id="tetlv">Level : 0</h4>
<h4 id="tetline">Line : 0</h4>
<td id="nextblock">
</td>
</td>
</tr>
</table>
<script>
let col = 12;
let row = 22;
let $data = [];
let $center = document.querySelector(`#tetrisCenter`);
let $table = document.createElement(`table`);
let $tr = document.createElement(`tr`);
let $td = document.createElement(`td`);
let colorList = ["white", "green", "red", "purple", "orange", "blue", "yellow", "skyblue", "gray", ""];
const GRAY = 8;
const WHITE = 0;
const BLACK = 9;
const BLOCK = GRAY;
let Gameover = false;
let myInterval = null;
let curY = 0; //블록생성 Y좌표
let curX = 0; //블록생성 X좌표
let curblock = null; //현재 블록의 정보
let nextblock = null;
let line = 0;
let blockList = [
{
name: "s",
color: 1,
shape:
[
[0, 0, 0],
[0, 1, 1],
[1, 1, 0]
]
},
{
name: "z",
color: 2,
shape:
[
[0, 0, 0],
[1, 1, 0],
[0, 1, 1]
]
},
{
name: "t",
color: 3,
shape:
[
[0, 0, 0],
[1, 1, 1],
[0, 1, 0]
]
},
{
name: "l",
color: 4,
shape:
[
[0, 1, 0],
[0, 1, 0],
[0, 1, 1]
]
},
{
name: "j",
color: 5,
shape:
[
[0, 1, 0],
[0, 1, 0],
[1, 1, 0]
]
},
{
name: "o",
color: 6,
shape:
[
[1, 1],
[1, 1]
]
},
{
name: "i",
color: 7,
shape:
[
[0, 0, 0, 0],
[1, 1, 1, 1],
[0, 0, 0, 0],
[0, 0, 0, 0],
]
}
];
function init(){
$table = document.createElement(`table`)
$table.id = `myTetris`;
for(let i = 0; i < row; i++){
$tr = document.createElement(`tr`);
$temp = [];
for(let j = 0; j < col; j++){
$td = document.createElement(`td`);
$temp.push(WHITE);
$tr.append($td);
}
$data.push($temp)
$table.append($tr);
}
$center.append($table);
$table = document.querySelector(`#myTetris`);
for(let i = 0 ; i < col; i++){
$data[0][i] = GRAY
$data[row - 1][i] = GRAY
$table.children[0].children[i].setAttribute(`class`, `gray`);
$table.children[row - 1].children[i].setAttribute(`class`, `gray`);
}
for(let i = 0 ; i < row; i++){
$data[i][0] = GRAY
$data[i][col - 1] = GRAY
$table.children[i].children[0].setAttribute(`class`, `gray`);
$table.children[i].children[col - 1].setAttribute(`class`, `gray`);
}
for(let i = 0; i < row; i++){
for(let j = 0; j < col; j++){
//$table.children[i].children[j].innerText = $data[i][j];
}
}
let $nextblock = document.querySelector(`#nextblock`)
$table = document.createElement(`table`)
$table.id = `nextIndex`
for(let i = 0; i < 4; i++){ //넥스트만들기
$tr = document.createElement(`tr`);
for(let j = 0; j < 4; j++){
$td = document.createElement(`td`);
$tr.append($td);
}
$table.append($tr);
}
$nextblock.append($table);
myInterval = setInterval(Gameplay, 500)
}
window.addEventListener(`keydown`, (a)=>{ //테트리스창에 키다운 이벤트생성
let key = a.code; //key는 입력값
if(key == `ArrowLeft`) Left(); //왼쪽화살표 == Left();함수실행
else if(key == `ArrowRight`) Right(); //오른쪽화살표 == Right(); 함수실행
else if(key == `ArrowDown`) { //아래쪽화살표 == Down()함수의 값이 false면 NewBlock함수실행
if(Down() == false){
lineClear();
NewBlock();
fn_cleannext()
fn_nextblock()
}
}
else if(key == `Space`) {
while(Down()){}//Down함수를 반복실행(return값으로 False를 받을때까지)
if(Down() == false){
lineClear();
NewBlock(); //리턴값이 False가 나올때까지 실행하였으므로(바닥이나 다른블록에 닿을때까지) 새 블록을 만든다.
fn_cleannext()
fn_nextblock()
}
}
else if(key == `ArrowUp`) Rotate();
print();
})
function fn_nextblock(){
let nextId = document.querySelector(`#nextIndex`);
let r = Math.floor(Math.random() * blockList.length);
nextblock = blockList[r];
let shape = nextblock.shape;
let colorindex = nextblock.color;
for(let i = 0; i < shape.length; i++){
for(let j = 0; j < shape[i].length; j++){
if(shape[i][j] == 1){
nextId.children[i].children[j].setAttribute(`class`, colorList[colorindex])
}
}
}
}
function fn_cleannext(){
let nextId = document.querySelector(`#nextIndex`);
for(let i = 0; i < 4; i++){
for(let j = 0; j < 4; j++){
nextId.children[i].children[j].removeAttribute(`class`, colorList[0])
}
}
}
function NewBlock(){ //블록생성
curY = 1; //블록생성위치Y값을 1로 지정
curX = 4; //블록생성위치X값을 4로 지정
curblock = nextblock //blockList[r]을 현재 블록정보에 저장
fn_Gameover();
let shape = curblock.shape; // 현재블록(curblock)의 모양을 shape변수로 지정
for(let y = 0; y < shape.length; y++){
for(let x = 0; x < shape[y].length; x++){ //현재블록의 모양(shape)만큼 반복문
if(shape[y][x] == 1){ //블록모양의 값에서 1인 부분 (0, 1)
$data[curY + y][curX + x] = nextblock.color //블록생성위치의 데이터값에 블록리스트[r]의 색깔값을 입력
}
}
}
print();
}
function print(){ //화면에 $data내용대로 출력
$table = document.querySelector(`#myTetris`) //$table = myTetris
$tetline = document.querySelector(`#tetline`)
$tetscore = document.querySelector(`#tetscore`)
$tetlv = document.querySelector(`#tetlv`);
for(let i = 0; i < row; i++){
for(let j = 0; j < col; j++){
// $table.children[i].children[j].innerText = $data[i][j]; //table 안의 텍스트값 = $data값
if($data[i][j] != BLACK ){
$table.children[i].children[j].setAttribute(`class`, colorList[$data[i][j]]) //$data값과 동일하게 class 지정
}
}
}
$tetline.innerHTML = `Line : ${line}`
$tetscore.innerHTML = `Score : ${line * 1000}`
$tetlv.innerHTML = `Level : ${parseInt(line / 10) + 1}`
}
function BlockIndex(shape){ //블록인덱스(shape값)함수
let temp = []; //임시배열
for(let i = 0; i < shape.length; i++){
for(let j = 0; j < shape[i].length; j++){
if(shape[i][j] == 1){ //shape에서 1인 index를 임시배열에 저장
temp.push([i + curY, j + curX]);
}
}
}
return temp;
}
function Movable(BlockIndex, nextY, nextX){ //Movable 함수지정(blockIndex, 다음Y값, 다음X값)
for(let i = 0; i < BlockIndex.length; i++){ //BlockIndex 배열의 길이만큼 반복
let y = BlockIndex[i][0]; //Y = 블록인덱스[i]의 Y값
let x = BlockIndex[i][1]; //X = 블록인덱스[j]의 X값
if($data[y + nextY][x + nextX] >= BLOCK){ //블록인덱스[i]의 Y값 , nextY 블록인덱스[i]의 X값이 BLOCK(8)보다 크거나 같을경우(크면 9=BLACK)
return false; //false를 리턴한다
}
}
return true;
}
function Left(){
let nextY = 0; //좌측버튼을 눌렀을때 변하게 될 Y값
let nextX = -1; //좌측버튼을 눌렀을때 변하게 될 X값
let shape = curblock.shape; //현재블록의 모양을 shape변수에 저장
let Index = BlockIndex(shape); //현재블록의 index값을 리턴받음
let move = Movable(Index, nextY, nextX); //현재블록의 index값에 이동시킬 Y X값을 적용시켜 이동이 가능한지 True False로 알려줌
if(move == true){
Update(Index, 0, 0, WHITE);
Update(Index, nextY, nextX, curblock.color);
curX--;
}
}
function Right(){
let nextY = 0; //좌측버튼을 눌렀을때 변하게 될 Y값
let nextX = 1; //좌측버튼을 눌렀을때 변하게 될 X값
let shape = curblock.shape; //현재블록의 모양을 shape변수에 저장
let Index = BlockIndex(shape); //현재블록의 index값을 리턴받음
let move = Movable(Index, nextY, nextX); //현재블록의 index값에 이동시킬 Y X값을 적용시켜 이동이 가능한지 True False로 알려줌
if(move == true){
Update(Index, 0, 0, WHITE);
Update(Index, nextY, nextX, curblock.color);
curX++;
}
}
function Down(){
let nextY = 1; //좌측버튼을 눌렀을때 변하게 될 Y값
let nextX = 0; //좌측버튼을 눌렀을때 변하게 될 X값
let shape = curblock.shape; //현재블록의 모양을 shape변수에 저장
let Index = BlockIndex(shape); //현재블록의 index값을 리턴받음
let move = Movable(Index, nextY, nextX); //현재블록의 index값에 이동시킬 Y X값을 적용시켜 이동이 가능한지 True False로 알려줌
if(move == true){
Update(Index, 0, 0, WHITE);
Update(Index, nextY, nextX, curblock.color);
curY++;
} else if (move == false){
Update2(Index, 0, 0, curblock.color);
}
return move;
}
function Rotate(){
let shape = curblock.shape;
let tempshape = [];
let OldIndex = BlockIndex(shape);
for(let i = 0; i < shape.length; i++){
let temp = [];
for(let j = 0; j < shape[i].length; j++){
temp.push(shape[shape.length -1 -j][i])
}
tempshape.push(temp);
}
let Index = BlockIndex(tempshape);
let move = Movable(Index, 0, 0);
if(move == true){
Update(OldIndex, 0, 0, WHITE);
Update(Index, 0, 0, curblock.color);
curblock.shape = tempshape;
console.log(curblock.shape);
}
}
function Update(BlockIndex, inputY, inputX, color){ //BlockIndex에서 반환받은 temp배열과 입력받은Y값, 입력받은X값, 지정색
for(let i = 0; i < BlockIndex.length; i++){ //BlockIndex의 Temp배열의 길이만큼 반복
let y = BlockIndex[i][0]; //Y = 블록인덱스[i]의 Y값
let x = BlockIndex[i][1]; //X = 블록인덱스[i]의 X값
$data[y + inputY][x + inputX] = color; //블록인덱스[i]의 Y,X값 + 입력받은Y,X값의 데이터를 지정받은 색상의 값으로 변경
}
}
function Update2(BlockIndex, inputY, inputX, color){ //BlockIndex에서 반환받은 temp배열과 입력받은Y값, 입력받은X값, 지정색
for(let i = 0; i < BlockIndex.length; i++){ //BlockIndex의 Temp배열의 길이만큼 반복
let y = BlockIndex[i][0]; //Y = 블록인덱스[i]의 Y값
let x = BlockIndex[i][1]; //X = 블록인덱스[i]의 X값
$data[y + inputY][x + inputX] = BLACK; //블록인덱스[i]의 Y,X값 + 입력받은Y,X값의 데이터를 지정받은 색상의 값으로 변경
$table.children[y + inputY].children[x + inputX].setAttribute(`class`, colorList[curblock.color])
}
}
function lineClear(){
let delID = [];
for(let i = 1; i < row - 1; i++){
let count = 0;
for(let j = 1; j < col - 1; j++){
if($data[i][j] != WHITE){
count++;
}
}
if(count == 10){
delID.push(i);
line++;
}
}
for(let i = 0; i < delID.length; i++){
$data.splice(delID[i], 1);
$data.splice(0, 1);
$data.unshift([BLOCK,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,BLOCK]);
$data.unshift([BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK]);
}
}
function Gameplay(){
if(Gameover == true){
clearInterval(myInterval);
alert(`패배!! 게임을 종료합니다.`)
restart();
}
if(Down() == false){
if(Down() == false){
lineClear();
NewBlock();
}
}
print();
}
function fn_Gameover(){
let block = BlockIndex(curblock.shape);
for(let i = 0; i < block.length; i++){
if($data[block[i][0]][block[i][1]] == 9 ){
Gameover = true;
break;
}
}
console.log(Gameover);
return Gameover;
}
function restart(){
$nextblock = document.querySelector(`#nextblock`);
$table = document.querySelector(`#myTetris`);
$table.remove();
$data = [];
Gameover = false;
myInterval = null;
curY = 0; //블록생성 Y좌표
curX = 0; //블록생성 X좌표
curblock = null; //현재 블록의 정보
$nextblock.remove();
init();
fn_nextblock();
NewBlock();
}
init();
fn_nextblock()
NewBlock();
</script>
</body>
</html>
테트리스 |
||
TETRISScore : 0Level : 0Line : 0 |
'코딩 > 2023 JavaScript DOM' 카테고리의 다른 글
2023.10.19 / Step 7 [DOM_member] - 코딩 72 일차 (0) | 2023.10.19 |
---|---|
2023.10.18 / Step 6 [DOM_경마게임] - 코딩 71 일차 (0) | 2023.10.18 |
2023.10.16 / Step 6 [DOM_스네이크게임] - 코딩 69 일차 (0) | 2023.10.16 |
2023.10.13 / Step 6 [DOM_식권자판기3단계] - 코딩 68 일차 (0) | 2023.10.13 |
2023.10.12 / Step 6 [DOM_식권자판기2단계] - 코딩 67 일차 (0) | 2023.10.12 |