const canvas = document.getElementById('myCanvas');
const context = canvas.getContext('2d');
document.addEventListener('keydown', keyPush);
const fieldWidth = 40;
const fieldHeight = 40;
const fieldColumn = 10;
const fieldRow = 10;
const fields = [];
const charRadius = 20;
let charPosX = charRadius;
let charPosY = canvas.height - charRadius;
let charMoveDirX = -1;
let charMoveDirY = -1;
let charMoveSpd = 2;
let fieldColor = ["lightpink", "lightsalmon", "gold", "lightgreen", "lightblue", "powderblue", "violet"];
class Field {
constructor(left, top, right, bottom, column, row, color, charstat) {
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
this.column = column;
this.row = row;
this.color = color;
this.charstat = charstat
}
draw() {
context.beginPath();
context.rect(this.left, this.top, fieldWidth, fieldHeight);
context.fillStyle = fieldColor[this.color%7];
context.fill();
context.closePath();
}
}
class Exit extends Field{
}
let exit = new Exit(
380 - (fieldWidth) / 2 , // left 380 - 20 360
20 - (fieldHeight) / 2, // top 20 - 20 0
380 + (fieldWidth) / 2, // right 380 + 20 400
20 + (fieldHeight) / 2, // bottom 20 + 20 40
1,
1,
)
class Char extends Field{
constructor(left, top, right, bottom, hp, money) {
super(left, top, right, bottom)
this.hp = hp;
this.money = money;
}
drawChar()
{
context.beginPath();
context.arc(charPosX, charPosY, charRadius, 0, 2 * Math.PI);
context.fillStyle = 'aqua';
context.fill();
context.closePath();
}
}
let char = new Char(
charPosX-20, // left: ; 20 -20
charPosY-20, // top: ; 400 - 20 - 20
charPosX+20, // right 20 + 20
charPosY+20, // bottom 400 - 20 + 20
10, // hp
0, // money
)
function keyPush(evt){
switch(evt.keyCode) {
case 37: // 왼쪽
if(charPosX - 20 > 0) {
charPosX += -40;
charPosY += 0;
char.left = charPosX - charRadius;
char.right = charPosX + charRadius ;
}
break;
case 38: // 윗키
if(charPosY - 20 > 0) {
charPosX += 0;
charPosY += -40;
char.top = charPosY - charRadius;
char.bottom = charPosY + charRadius;
}
break;
case 39: // 오른쪽
if(charPosX + 20 < canvas.width){
charPosX += 40;
charPosY += 0;
char.left = charPosX - charRadius;
char.right = charPosX + charRadius;
}
break;
case 40: // 아래
if(charPosY + 20 < canvas.height){
charPosX += 0;
charPosY += 40;
char.top = charPosY - charRadius;
char.bottom = charPosY + charRadius;
}
break;
default:
break;
}
}
function draw()
{
// 화면 클리어
context.clearRect(0, 0, canvas.width-40, canvas.height);
context.clearRect(360, 40, 40, canvas.height-40);
// drawCanavs();
// 그리기
drawFields();
char.drawChar();
}
function drawExit(){
var img_exit = new Image();
img_exit.src = "exit.png";
img_exit.onload = function()
{
context.drawImage(img_exit, exit.left, exit.top, fieldWidth, fieldHeight)
}
}
function drawFields()
{
let gaming = false;
for(let i = 0; i < fieldRow; i++)
{
for(let j = 0; j < fieldColumn; j++)
{
if(i != 9 || j != 0 )
fields[i][j].draw();
if(fields[i][j].charstat > 0) gaming = true;
}
}
if(!gaming){
/* clear(); */
}
}
function update()
{
// 충돌확인 어떤경우에도 안부딪히는 상황
if(isCollisionExitToChar(char, exit)) // right left top bottom
{
console.log("충돌!")
setTimeout(() => {
window.location.reload();
alert("clear")
}, 300);
}
}
function isCollisionExitToChar(charA, exitB)
{
// a의 완쪽과 b의 오른쪽
// a의 오른쪽과 b의 왼쪽
// a의 아래쪽과 b의 위쪽
// a의 위쪽과 b의 아래쪽
if (charA.left >= exitB.right || // a의 왼쪽이 더 클때
charA.right <= exitB.left || // b의 왼쪽이 더 클때
charA.top >= exitB.bottom || // a의 탑이 더 클때
charA.bottom <= exitB.top ) // b의 탑이 더 클때
{
return false;
}
return true;
}
function setFields()
{
for(let i = 0; i < fieldRow; i++)
{
fields[i] = [];
for(let j = 0; j < fieldColumn; j++)
{
fields[i][j] = new Field(
0 + i * 40,
0 + j * 40,
0 + (1+i) * 40,
0 + (1+j) * 40,
i,
j,
Math.floor((Math.random()*7)+1)
)
}
}
}
function setExit()
{
for(let i = 0; i < fieldRow; i++)
{
exit[i] = [];
for(let j = 0; j < fieldColumn; j++)
{
exit[i][j] = new Exit(
0 + i * 30,
0 + j * 30,
0 + (1+i) * 30,
0 + (1+j) * 30,
i,
j,
)
}
}
}
// function drawCanavs(){
// context.beginPath();
// context.rect(0, 0, canvas.width, canvas.height);
// context.fillStyle = "rgba(10, 10, 10, 0.1)";
// context.fill();
// context.closePath();
// } // 어쩌다보니 암전효과 ㅋㅋ
setExit();
setFields();
drawExit();
setInterval(draw, 1000 / 15);
setInterval(update, 1000 / 15);
1. 맵 제작 - 이차원 배열 10 X 10
2. 맵타일 - 오브젝트 or 클래스
3. 플레이어, 탈출구 - 오브젝트 - 클래스
4. 키 입력 처리 - 상하좌우 1칸씩 이동 가능
5. 플레이어가 탈출구에 도착하면 게임 클리어