일상

html5 canvas 테트리스 만들기 <3일차>

냘로하 2020. 8. 29. 12:09

테트리스 완성!

따라해서 만들기에 성공했으니, 이제 코드를 먹뜯즐해서 내걸로 소화시켜야 한다...(이게 젤 어려운것 같다)

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>tetris</title>
	<style>
			body{
			background: #202028;
			color: #fff;
			font-family: sans-serif;
			font-size: 2em;
			text-align: center;
			}
			canvas{
				border : solid .2em #fff;
				height: 90%
			}
	</style>
	<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.5.1.js"> </script>
</head>
<body>

	<div id="score" ></div>
	<canvas id="tatris" width="240" height="400"></canvas>
	<script src="tetris.js"></script>

	
</body>
</html>

짧은 html과

var canvas = document.getElementById("tatris");
 //랜더링 컨텍스트 지정.
var c = canvas.getContext('2d');
c.scale(20,20);
var arena = createMatrix(12,20);
	console.log(arena); console.table(arena);
var player ={
	position :  { x:0, y:0},
	matrix: null,
	score : 0 ,
}

var colors = [
	null,
	'red',
	'blue',
	'violet',
	'green',
	'purple',
	'orange',
	'pink',
];

function arenaSweep(){
	let rowcount = 1;
	outer : for (let y = arena.length - 1; y > 0; --y ){
		for (let x = 0 ; x < arena[y].length; ++x){
			if (arena[y][x]===0) {
				continue outer;
			}
		}
		var row = arena.splice(y,1)[0].fill(0);
		arena.unshift(row);
		++y;
		player.score += rowcount * 10;
		rowcount *=2;
	}
}
function collide(arena,player){
	//matrix = m , position = o
	var [m, o ] = [player.matrix , player.position];
	for (let y = 0 ; y < m.length; ++ y){
		for (let x = 0 ; x<m[y].length; ++ x){
			if(m[y][x]!==0 && 
				(arena[y+ o.y]&&
				arena[y + o.y][x + o.x])!==0){
				return true;
			}
		}
	}
	return false;
}
function createMatrix(w,h){
	var matrix = [];
	while (h--){
	matrix.push(new Array(w).fill(0));
	}
	return matrix;
}
function createPiece(type){
	if (type == 'T'){
		return [
		[0 ,0 ,0],
		[1 ,1 ,1],
		[0 ,1 ,0],
		];
	} else if (type ==='O'){
		return [
		[2,2],
		[2,2],
		];
	}else if (type === 'L'){
		return[
		[0,3,0],
		[0,3,0],
		[0,3,3],
		];
	}else if (type === 'J'){
		return[
		[0,4,0],
		[0,4,0],
		[4,4,0],
		];
	}else if (type ==='I'){
		return[
		[0,5,0,0],
		[0,5,0,0],
		[0,5,0,0],
		[0,5,0,0],
		];
	}else if (type === 'S'){
		return [
		[0,6,6],
		[6,6,0],
		[0,0,0],
		];
	}else if (type === 'Z'){
		return [
		[7,7,0],
		[0,7,7],
		[0,0,0],
		];
	}

}

function draw(){
	c.fillStyle='#000';
	c.fillRect(0,0,canvas.width, canvas.height);

	drawMatrix(arena,{x:0,y:0});
	drawMatrix(player.matrix,player.position );
}


function drawMatrix(matrix,offset){
	matrix.forEach((row,y)=>{
		row.forEach((value,x)=>{
			if(value!==0){
				c.fillStyle = colors[value];
				c.strokeStyle='white';
				c.lineWidth=0.05;
				c.strokeRect(x+offset.x ,
							 y+offset.y,1,1);
				c.fillRect(x+ offset.x ,
					       y+ offset.y ,1,1);
			}
		});
	});
}
function merge(arena,player){
	player.matrix.forEach((row,y)=>{
		row.forEach((value,x)=>{
			if(value!==0){
				arena[y+player.position.y][x+player.position.x]=value;
			}
		});
	});
}

function playerDrop(){
	player.position.y++;
	if(collide(arena, player)){
		player.position.y--;
		merge(arena,player);
		playerReset();
		arenaSweep();
		updatescore();
}
	dropCounter = 0;
}

function playerMove(dir){
	player.position.x += dir;
	console.log(dir);
		if(collide(arena,player)){
		player.position.x -= dir;
	}

}
function playerReset(){
	var pieces = 'ILJOTSZ';
	player.matrix = createPiece(pieces[pieces.length * Math.random()| 0 ]);
	console.log(player.matrix);
	player.position.y = 0;
	player.position.x =(arena[0].length/2|0) -
					   (player.matrix[0].length/2|0);
    if (collide(arena,player)){
    	arena.forEach(row => row.fill(0));
    	player.score = 0;
    	updatescore();
    };
};

function playerRotate (dir){
	const position = player.position.x;
	let offset = 1;
	rotate(player.matrix,dir);
	while(collide(arena,player)){
		player.position.x += offset;
		offset = -(offset+(offset> 0? 1 : -1 ));
		if(offset > player.matrix[0].length) {
			rotate(player.matrix,dir);
			player.position.x = position;
			return;
		}
	}
}
function rotate(matrix, dir){
	for (let y = 0; y<matrix.length; ++y){
		for (let x = 0 ; x < y; ++x ){
			[
				matrix[x][y],
				matrix[y][x],
			]=[ matrix[y][x],
				matrix[x][y],
			];
		}
	}
	if (dir>0) {
		matrix.forEach(row => row.reverse());
	}else{
		matrix.reverse();
	}
}

let dropCounter = 0;
let dropInterval = 1000;

let lastTime  = 0;
function update(time = 0 ){
	var deltaTime = time - lastTime
	lastTime = time;
	dropCounter += deltaTime;
	if(dropCounter > dropInterval){
		playerDrop();
	}
		draw();
		requestAnimationFrame(update);
}
function updatescore(){
	document.getElementById('score').innerText = player.score;

}


document.addEventListener('keydown',event => {

	if(event.keyCode === 37){
		playerMove(-1);
	}else if (event.keyCode ===39){
		playerMove(1);
	}else if (event.keyCode === 40){
		playerDrop();
	}else if (event.keyCode === 81){
		playerRotate(-1);
	}else if (event.keyCode === 87){
		playerRotate(1);
	}
});

playerReset();
updatescore();
update();

그에 비해서 많이 길다란 자바스크립트.... ㅠㅠ...

슬프게도 jQuery를 쓰는 일은 없었다고 합니다....  =>대신에  jquery로 펑션 쓸수 있으려나....내일 한번 해봐야겠습니다.

오늘은 끝! 소스파일도 올리겠습니다.

tetris.html
0.00MB
tetris.js
0.00MB