1. 미로찾기 프로젝트
복습할때 한번더 코드 쳐보기(10/9)
(1) 플레이어가 미로를 탐험하고 목표지점에 도달하는 프로그램
<간단 설명>
1. map 배열
0: 빈공간, 1: 벽, 2:목표지점, 3: 플레이어 위치
2. madeTable(y, x)
테이블 생성함수
3. drawArray(arr)
map 배열을 기반으로 테이블 색상을 칠하는 함수
4. isMove(y, x)
주어진 위치(y, x)가 이동가능한지 확인하는 함수
1이면 이동불가능 false, 0이면 이동가능 true
5. unitY와 unitX
플레이어 현재위치를 나타내는 변수
6. endY, endX
목표 지점 위치를 나타내는 변수
7. window.onload 핸들러
HTML 문서가 완전히 로드될때 실행
게임 초기화 관련 작업
8. document.body.innerHTML
HTML 문서의 내용을 현재 생성된 미로테이블 대체
drawArray(map) 호출하여 map 배열에 따라 테이블 칠함.
9. document.body.onkeypress 핸들러
사용자가 키보드 키를 눌렀을때 발생
키 코드에 따라 다양한 동작처리
10. event.keyCode를 사용하여 사용자가 어떤 키를 눌렀는지 동작 수행
11. 키 이벤트 처리 스위치문 사용
56 (키패드의 8 키) - 위로 이동
54 (키패드의 6 키) - 오른쪽으로 이동
52 (키패드의 4 키) - 왼쪽으로 이동
50 (키패드의 2 키) - 아래로 이동
12. isMove 함수로 플레이어가 이동 가능한 위치인지 확인
13. 게임종료조건
현재위치가 목표지점의 위치가 일치할때
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script>
var map = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2],
[1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1],
[1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1],
[1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1],
[1, 3, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
function madeTable(y, x) {
var str = "";
str += "<table border=1>";
for (var i = 0; i < y; i++) {
str += "<tr>";
for (var j = 0; j < x; j++) {
str += `<td id=y${i}x${j} width=25 height=25>`;
str += "</td>";
}
str += "</tr>";
}
str += "</table>";
return str;
}
function drawArray(arr) {
var y = arr.length;
var x = arr[0].length;
for (var i = 0; i < y; i++) {
for (var j = 0; j < x; j++) {
switch (arr[i][j]) {
case 1:
document
.getElementById("y" + i + "x" + j)
.setAttribute("bgcolor", "red");
break;
case 2:
document
.getElementById("y" + i + "x" + j)
.setAttribute("bgcolor", "yellow");
break;
case 3:
document.getElementById("y" + i + "x" + j).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
break;
}
}
}
}
function isMove(y, x) {
if (map[y][x] == 1) {
return false;
} else {
return true;
}
}
var unitY = 13;
var unitX = 1;
var endY = 1;
var endX = 14;
window.onload = function () {
document.body.innerHTML = madeTable(map.length, map[0].length);
drawArray(map);
document.body.onkeypress = function () {
switch (event.keyCode) {
case 56:
if (isMove(unitY - 1, unitX)) {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitY = unitY - 1;
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
}
break;
case 54:
if (isMove(unitY, unitX + 1)) {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitX = unitX + 1;
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
}
break;
case 52:
if (isMove(unitY, unitX - 1)) {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitX = unitX - 1;
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
}
break;
case 50:
if (isMove(unitY + 1, unitX)) {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitY = unitY + 1;
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
}
break;
}
if (unitX == endX && unitY == endY) {
alert("게임을 종료합니다.");
}
};
};
</script>
</head>
<body></body>
</html>
(2) 리플레이가 추가된 프로그램
<간단 설명>
리플레이 배열(replayX, replayY)
리플레이 배열은 플레이어의 움직임 저장
리플레이 기능을 통해 각 움직임 단계 좌표 기록
게임 종료시 배열을 사용하여 움직임 재생
replayFunction() 함수
리플레이 기능 수행
플레이어 위치 초기화하고 리플레이 배열에서 위치를 하나 가져오고
플레이어 이미지를 그림
리플레이 배열이 빈 경우 리플레이 타이머를 중지하고 게임 종료
replayTimer
replayTimer 변수는 setInterval 함수를 사용하여 리플레이 함수를 일정시간 간격으로 반복
1) 리플레이 시작 지점 기록
게임 시작시 replayX와 replayY 배열에 초기 플레이어 위치인
(1,13) 좌표 추가하여 리플레이 시작지점 기록
2) 게임 종료시 리플레이 시작
게임이 종료되면 리플레이 시작. 움직임으로 자동재생
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script>
var map = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2],
[1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1],
[1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1],
[1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1],
[1, 3, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
function madeTable(y, x) {
var str = "";
str += "<table border=1>";
for (var i = 0; i < y; i++) {
str += "<tr>";
for (var j = 0; j < x; j++) {
str += `<td id=y${i}x${j} width=25 height=25>`;
str += "</td>";
}
str += "</tr>";
}
str += "</table>";
return str;
}
function drawArray(arr) {
var y = arr.length;
var x = arr[0].length;
for (var i = 0; i < y; i++) {
for (var j = 0; j < x; j++) {
switch (arr[i][j]) {
case 1:
document
.getElementById("y" + i + "x" + j)
.setAttribute("bgcolor", "red");
break;
case 2:
document
.getElementById("y" + i + "x" + j)
.setAttribute("bgcolor", "yellow");
break;
case 3:
document.getElementById("y" + i + "x" + j).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
break;
}
}
}
}
function isMove(y, x) {
if (map[y][x] == 1) {
return false;
} else {
return true;
}
}
function replayFunction() {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitX = replayX.shift();
unitY = replayY.shift();
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
if (replayX.length == 0) {
clearInterval(replayTimer);
alert("리플레이를 종료합니다");
}
}
var replayTimer;
var unitY = 13;
var unitX = 1;
var endY = 1;
var endX = 14;
var replayX = [];
var replayY = [];
window.onload = function () {
replayX.push(unitX);
replayY.push(unitY);
document.body.innerHTML = madeTable(map.length, map[0].length);
drawArray(map);
document.body.onkeypress = function () {
switch (event.keyCode) {
case 56:
if (isMove(unitY - 1, unitX)) {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitY = unitY - 1;
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
}
break;
case 54:
if (isMove(unitY, unitX + 1)) {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitX = unitX + 1;
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
}
break;
case 52:
if (isMove(unitY, unitX - 1)) {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitX = unitX - 1;
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
}
break;
case 50:
if (isMove(unitY + 1, unitX)) {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitY = unitY + 1;
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
}
break;
}
replayX.push(unitX);
replayY.push(unitY);
if (unitX == endX && unitY == endY) {
alert("게임을 종료합니다.");
console.log(replayX);
replayTimer = setInterval(replayFunction, 500);
}
};
};
</script>
</head>
<body></body>
</html>
(3) 최단거리를 추가
+ 간단 설명 +
shortFunction함수
최단경로 재생하는 함수
현재 플레이어위치 초기화, shortX, shortY 배열에서 다음 위치를 가져와 해당 위치의 플레이어 이미지 그림
shortX, shortY
최단경로 재생
tempX, tempY
replayX, replayY 배열의 복사본 사용
복사본 배열 사용하여 최단경로 계산
계산 중에 복사본 배열을 값 제거
중복되는 좌표가 없을때만 shortX, shortY 값 추가
shortTimer(최단 경로 타이머)
setInterval 함수를 사용하여 shortFunction 함수 일정시간 간격 호출
최단 경로 및 재생
게임 종료되면 최단경로 계산.
해당 경로를 replayX, replayY 배열에서 중복되지 않도록 shortX, shortY 배열 저장
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script>
var map = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2],
[1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1],
[1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1],
[1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1],
[1, 3, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
function madeTable(y, x) {
var str = "";
str += "<table border=1>";
for (var i = 0; i < y; i++) {
str += "<tr>";
for (var j = 0; j < x; j++) {
str += `<td id=y${i}x${j} width=25 height=25>`;
str += "</td>";
}
str += "</tr>";
}
str += "</table>";
return str;
}
function drawArray(arr) {
var y = arr.length;
var x = arr[0].length;
for (var i = 0; i < y; i++) {
for (var j = 0; j < x; j++) {
switch (arr[i][j]) {
case 1:
document
.getElementById("y" + i + "x" + j)
.setAttribute("bgcolor", "red");
break;
case 2:
document
.getElementById("y" + i + "x" + j)
.setAttribute("bgcolor", "yellow");
break;
case 3:
document.getElementById("y" + i + "x" + j).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
break;
}
}
}
}
function isMove(y, x) {
if (map[y][x] == 1) {
return false;
} else {
return true;
}
}
function shortFunction() {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitX = shortX.shift();
unitY = shortY.shift();
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
if (shortX.length == 0) {
clearInterval(shortTimer);
alert("최단경로 완료하였습니다.");
}
}
function isUnitXY(x, y) {
var returnValue = false;
for (var i = 0; i < tempX.length; i++) {
if (tempX[i] == x && tempY[i] == y) {
returnValue = true;
break;
}
}
return returnValue;
}
function replayFunction() {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitX = replayX.shift();
unitY = replayY.shift();
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
if (replayX.length == 0) {
clearInterval(replayTimer);
alert("리플레이를 종료합니다");
while (tempX.length != 0) {
var x = tempX.shift();
var y = tempY.shift();
if (!isUnitXY(x, y)) {
shortX.push(x);
shortY.push(y);
} else {
while (!(x == tempX[0] && y == tempY[0])) {
tempX.shift();
tempY.shift();
}
}
console.log(shortX);
console.log(shortY);
}
shortTimer = setInterval(shortFunction, 250);
}
}
var shortTimer;
var replayTimer;
var unitY = 13;
var unitX = 1;
var endY = 1;
var endX = 14;
var replayX = [];
var replayY = [];
var tempX = [];
var tempY = [];
var shortX = [];
var shortY = [];
window.onload = function () {
replayX.push(unitX);
replayY.push(unitY);
document.body.innerHTML = madeTable(map.length, map[0].length);
drawArray(map);
document.body.onkeypress = function () {
switch (event.keyCode) {
case 56:
if (isMove(unitY - 1, unitX)) {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitY = unitY - 1;
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
}
break;
case 54:
if (isMove(unitY, unitX + 1)) {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitX = unitX + 1;
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
}
break;
case 52:
if (isMove(unitY, unitX - 1)) {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitX = unitX - 1;
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
}
break;
case 50:
if (isMove(unitY + 1, unitX)) {
document.getElementById(`y${unitY}x${unitX}`).innerHTML = "";
unitY = unitY + 1;
document.getElementById(`y${unitY}x${unitX}`).innerHTML =
"<img src='../images/말.jpg' width=20 height=20>";
}
break;
}
replayX.push(unitX);
replayY.push(unitY);
if (unitX == endX && unitY == endY) {
alert("게임을 종료합니다.");
tempX = replayX.slice();
tempY = replayY.slice();
console.log(replayX);
replayTimer = setInterval(replayFunction, 250);
}
};
};
</script>
</head>
<body></body>
</html>
+ 추가 설명 +
tempX = [1,2,3,4,2,3,4]
tempY = [1,2,3,4,2,3,4]
- tempX와 tempY의 1을 변수 x,y 넣는다.
- 그럼 tempX와 tempY의 1이 없어지고 1값이 배열에 존재하는지 물어본다. 존재하지 않아 shortX, shortY 배열에 각각 1값이 저장된다.
- tempX와 tempY의 2를 변수 x,y를 넣고 tempX,Y 배열에 있는 2값이 사라지면서 다음 변수가 2가 존재하는지 확인한다. 다음 변수가 2가 아니라면 shortX,Y 저장되지 않고 삭제된다.
- tempX,Y 3값도 변수 x,y에 넣고 2인지 확인하는데 2가 아니라면 3값도 삭제된다. 4까지 반복
- 4 다음 변수가 2일때 shortX, shortY에 저장된다.
- 3을 넣고 다음 배열에 존재하지 않으면 shortX,shortY 저장.
- 마지막 배열자리 4도 넣고 존재하지 않으면 저장
2. DOM 조작
- HTML과 자바스크립트 코드는 DOM을 조작하는 예제
window.onload 이벤트핸들러
웹페이자가 로드되면 실행되는 이벤트 핸들러
document.body.children
body 요소의 자식 요소 목록을 반환하고 콘솔에 출력
document.getElementByTagName('ul')[0]
문서 내에서 ul태그 요소를 선택 후 출력
myUl.children
선택된 ul요소의 자식 요소 목록 반환하고 콘솔에 출력
반복문을 사용하여 li요소 내용 출력
myUl.firstChild
ul요소의 첫번째 자식노드요소 접근
다양한속성(텍스트, 데이터, HTML 내용 등) 콘솔출력
getElementByTagName("li")[1]
두번째 요소인 li 요소 오렌지 선택 내용을 출력
또한 previousSibling 및 nextSibling 사용하여
해당 요소의 이전과 다음 형제노드 접근하고 내용 출력
새로운 li요소 생성하고 텍스트 내용 설정한 다음
appendChild 및 insertBefore메소드를 사용하여 DOM추가
removeChild()
특정노드 삭제
innerHTML 속성을 사용하여 HTML을 포함한 새로운 li 요소 생성하고 DOM 추가
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script>
window.onload = function () {
var body = document.body.children;
console.log(body);
var myUl = document.getElementsByTagName("ul")[0];
console.log(myUl);
var myLi = myUl.children;
console.log(myLi);
for (var i = 0; i < myLi.length; i++) {
console.log(myLi[i].innerHTML);
}
console.log(myUl.firstChild.innerText);
console.log(myUl.firstChild.innerHTML);
console.log(myUl.firstChild.parentNode);
var orange = document.getElementsByTagName("li")[1];
console.log(orange.innerHTML);
console.log(orange.previousSibling.innerHTML);
console.log(orange.nextSibling.innerHTML);
var newNode = document.createElement("li");
var newText = document.createTextNode("수박");
newNode.appendChild(newText);
console.log(newNode);
myUl.appendChild(newNode);
myUl.insertBefore(newNode, orange);
myUl.removeChild(newNode);
var newNode = document.createElement("li");
newNode.innerHTML = "<b>수박</b>";
myUl.appendChild(newNode);
};
</script>
</head>
<body>
<div>
<p>과일리스트</p>
<ul>
<li>사과</li>
<li>오렌지</li>
<li>바나나</li>
</ul>
</div>
</body>
</html>