BrainStorm Programming Class JavaScript Lecture #4, part-2 Jeong Tae Hong 2013-01-25
Contents Input Event in Game : Basic Theory Collision : Basic Theory Finite State Machine : Basic Theory Jeong Tae Hong 2013-01-25
Input Event in Game : Basic Theory 게임에서 사용하는 입력장치 위치 지정 도구 : 마우스, 터치패드, 조이스틱 등 자판 도구 : 키보드, 조이패드(버튼 부분), 가상키보드 등 위치 지정 도구 좌표 입력 (x,y) 상대입력 : 마우스, 조이스틱 방금 전 위치보다 얼마만큼 더 움직였는가? 절대입력 : 터치패드 입력된 위치가 어디인가? 자판 도구 문자열 입력 어떤 버튼(키)가 입력되었는가? Virtual Key code 특정 기계버튼을 특정 코드에 일대일 대응 어떤 버튼은 어떤 코드를 가진다 어떤 코드를 입력하면 어떤 행동을 수행한다 E.g. 소문자 ‘a’ ASCII 코드로 10진수 97 97이 입력되면 왼쪽으로 이동한다(FPS 게임) Jeong Tae Hong 2013-01-25
Input Event in Game : Basic Theory Measure : 측정값 입력된 수치 입력된 키 코드, 마우스의 현재 좌표 등 Trigger : 전달 신호 Measure를 가져가라는 신호 (이벤트 모드) 키 입력 이벤트, 마우스 클릭 이벤트 등 입력 모드 리퀘스트 모드 샘플 모드 이벤트 모드 이것만 알면 된다! Jeong Tae Hong 2013-01-25
Input Event in Game : Basic Theory 이벤트 모드 여러 개의 입력장치에서 트리거 발생 각각의 트리거에는 각각의 메져가 있다. 이벤트 큐에 트리거가 축적된다. 리스너가 있는 이벤트 트리거가 지정하는 메져를 핸들러로 보낸다. 마우스클릭리스너 마우스클릭트리거 마우스좌표 마우스클릭핸들러 Jeong Tae Hong 2013-01-25
Input Event in Game : Basic Theory 키보드 입력 in JavaScript “키보드 이벤트”의 “리스너”를 추가하고, “핸들링”하는 작업 키보드 이벤트 onKeyDown ‘keydown’ : 키를 누른 순간 onKeyPress ‘keypress’ : 키를 누르고 있는 동안 모든 키에 다 적용되지는 않는다. (사용x) onKeyUp ‘keyup’ : 누른 키에서 손을 뗐을때! 리스너가 추가되는 대상 : window Window? 현재 보고 있는 브라우저 창(탭) window.addEventListener("keydown", eventKeyPressed, true); 키보드 이벤트의 경우 마지막에 true (Bubbling) Jeong Tae Hong 2013-01-25
Input Event in Game : Basic Theory 키보드 방향키 좌 : 37, 상 : 38, 우 : 39, 하 : 40 좌 왼쪽으로 이동 X좌표 감소 상 위쪽으로 이동 Y좌표 감소 캔버스 좌표계 우 오른쪽으로 이동 X좌표 증가 하 아래쪽으로 이동 Y좌표 증가 (0,0) X++ Y++ Jeong Tae Hong 2013-01-25
Input Event in Game : Basic Theory console.log() 콘솔에 내용 출력 e.keyIdentifier 키보드 이벤트에서 어떤 키가 눌러졌는지 ‘e’를 그대로 출력하면? 모든 속성을 볼 수 있다. Jeong Tae Hong 2013-01-25
Input Event in Game : Basic Theory 소스코드 <!DOCTYPE html> <style> <head> <html> } border: 1px solid black canvas { </style> <body> </head> <canvas id="aCanvas" width="300" height="500"> </canvas> HTML5 Canvas return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || window.requestAnimFrame = (function() { <script> function(/* function */callback, /* DOMElement */element) { }; return window.setTimeout(callback, 1000 / 60); )(); var context = canvas.getContext("2d"); var canvas = document.getElementById("aCanvas"); img.addEventListener('load', eventLoaded, false); var img = new Image(); img.src = "http://vcl.ajou.ac.kr/~jake4u/wordpress/wp-content/uploads/rs2-noback.png"; requestAnimFrame(draw); function eventLoaded() { var totalFrame = 11; var frame = 0; var yPos = 0; var xPos = 0; context.drawImage(img, frame * 29, 0, 29, 125, xPos, yPos, 58, 250); context.clearRect(0, 0, canvas.width, canvas.height); function draw() { frame = 0; if (frame == totalFrame) { frame++; </script> window.addEventListener("keydown", eventKeyPressed, false); function eventKeyPressed(e) { console.log(e.keyCode, e.keyIdentifier); xPos -= 3; case 37: switch(e.keyCode) { break; yPos -= 3; case 38: xPos += 3; case 39: yPos += 3; case 40: </html> </body> Jeong Tae Hong 2013-01-25
Input Event in Game : Basic Theory 실습 Jeong Tae Hong 2013-01-25
Collision 충돌 : 두 물체가 부딪히는 것 게임에서의 충돌 : 오브젝트와 오브젝트가 맞닿았는가? E.g. 총알과 적이 맞닿으면? 적은 죽는다, 총알은 사라진다. E.g. 게임 화면의 가장자리에 플레이어가 맞닿으면? 그 방향으로 더 이상 갈 수 없다. Jeong Tae Hong 2013-01-25
Collision How to? Bounding Primitive Boundary Check 오브젝트를 둘러싸는 간단한 도형 사각형, 원 등을 사용할 수 있다. Boundary Check 두 물체가 서로의 B.P의 경계를 침범했는가? True 충돌 Jeong Tae Hong 2013-01-25
Collision Box to Box x11,y11 x12,y11 x21,y21 x22,y21 Box1 Box2 x11,y12 Jeong Tae Hong 2013-01-25
Collision Box1 Box2 Box to Box Box2 Box1 Box1 Box2 Box1 Box2 Box1 Box2 x11,y11 x12,y11 x21,y21 x22,y21 Box1 Box2 Box to Box If : x12>x21 빨간 점보다 파란 점이 왼쪽인 경우 x11,y12 x12,y12 x21,y22 x22,y22 Box2 Box1 Box1 Box2 Box1 Box2 Box1 Box2 Y좌표가 많이 어긋난 경우 지나쳐간 경우 제대로 충돌한 경우 Jeong Tae Hong 2013-01-25
Collision Box to Box Box1 Box2 Box1 Box2 제대로 충돌한 경우 제대로 충돌한 경우 분석 x12>x21 && x11<x21 : 가로 상으로 안에 있다. y11<y21 && y12>y22 : 세로 상으로 안에 있다. 어느 한 점이 다른 박스 내에 있다면 충돌! 가로와 세로를 모두 따져야한다. x11,y11 x12,y11 x21,y21 x22,y21 Box1 Box2 Box1 Box2 제대로 충돌한 경우 x11,y12 x12,y12 x21,y22 x22,y22 Jeong Tae Hong 2013-01-25
Collision Box to Box Box1 Box2 Box1 Box2 제대로 충돌한 경우 제대로 충돌한 경우 분석 x12>x21 && x11<x21 : 가로 상으로 안에 있다. y11<y21 && y12>y22 : 세로 상으로 안에 있다. 어느 한 점이 다른 박스 내에 있다면 충돌! 가로와 세로를 모두 따져야 한다. x11,y11 x12,y11 x21,y21 x22,y21 Box1 Box2 Box1 Box2 제대로 충돌한 경우 x11,y12 x12,y12 x21,y22 x22,y22 Jeong Tae Hong 2013-01-25
Collision 매우 기초적인 수준의 충돌검사 실제로 사용하려면 어느 방향 충돌인지도 체크해야 한다. Jeong Tae Hong 2013-01-25
Collision 매우 기초적인 수준의 충돌검사 닿으면 밀려난다! Jeong Tae Hong 2013-01-25
Collision 소스코드 Jeong Tae Hong 2013-01-25 <!DOCTYPE html> <style> <head> <html> border: 1px solid black canvas { </style> } <body> </head> </canvas> HTML5 Canvas <canvas id="aCanvas" width="300" height="500"> window.requestAnimFrame = (function() { <script> return window.setTimeout(callback, 1000 / 60); function(/* function */callback, /* DOMElement */element) { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || }; var canvas = document.getElementById("aCanvas"); )(); var context = canvas.getContext("2d"); img.addEventListener('load', eventLoaded, false); img.src = "http://vcl.ajou.ac.kr/~jake4u/wordpress/wp-content/uploads/rs2-noback.png"; var img = new Image(); requestAnimFrame(draw); function eventLoaded() { var totalFrame = 11; var frame = 0; var yPos = 0; var xPos = 0; var rectX = 100; var rectH = 60; var rectW = 60; var rectY = 100; rectX +=1; if(true == collision(xPos, yPos, 29, 125, rectX, rectY, rectW, rectH)) { function draw() { context.clearRect(0, 0, canvas.width, canvas.height); frame++; context.fillRect(rectX,rectY,rectW,rectH); context.fillStyle = "#FF0000"; context.drawImage(img, frame * 29, 0, 29, 125, xPos, yPos, 29, 125); frame = 0; if (frame == totalFrame) { window.addEventListener("keydown", eventKeyPressed, false); </script> function eventKeyPressed(e) { console.log(e.keyCode, e.keyIdentifier); xPos -= 1; case 37: switch(e.keyCode) { yPos -= 1; case 38: break; xPos += 1; case 39: case 40: yPos += 1; if (x11 + Width1 < x21 || x11 > x21 + Width2) function collision(x11, y11, Width1, Height1, x21, y21, Width2, Height2) { return false; // 왼쪽으로 멀리 있거나, 오른쪽으로 멀리 있다면 // 더 위에 있거나, 더 아래에 있다면 if (y11 + Height1 < y21 || y11 > y21 + Height2) return true; </html> </body> Jeong Tae Hong 2013-01-25
Finite State Machine 유한상태기계 가지고 있는 상태의 개수가 유한한 기계 E.g. 태홍이네 선풍기 : 10개의 상태를 가진다. 회전 상태 2개 : 회전, 고정 세기 상태 4개 : 자연바람, 약, 중, 강 작동 상태 2개 : On, Off 타이머 2개 : 연속, 시간설정 태홍이네 선풍기가 연속으로 작동 중이며, 회전하고 있고 자연바람 모드이다. 방향 : 회전 전원 : On 타이머 : 연속 세기 : 자연바람 Jeong Tae Hong 2013-01-25
Finite State Machine FSM의 필수 요소 상태 : 유한개의 상태가 필요하다. 전이조건 : 어떤 상태가 다른 상태로 바뀌기 위한 조건 전이 : 어떤 상태에서 다른 상태로 바뀜 태홍이네 선풍기 10개의 상태 존재 전이 조건 세기 : 풍량 버튼을 누른다 방향 : 방향 다이얼을 돌린다 동작 : 전원 버튼을 누른다 타이머 : 타이머 다이얼을 돌린다. 전이 각각의 전이조건을 만족하면 상태가 바뀐다! 너무나 당연함 Jeong Tae Hong 2013-01-25
Finite State Machine FSM in Game : 게임 진행에도 여러 상태가 존재. Intro Menu Play 각 상태를 넘어가기 위한 뚜렷한 조건이 존재 Menu Play : 플레이버튼 누르기 Play GameOver : 플레이어 사망 or 시간제한 종료 조건의 발생은 반드시 다른 상태로의 전이를 일으킨다. Intro Menu Play Pause GameOver Retry Jeong Tae Hong 2013-01-25
Finite State Machine FSM in Game Character : 마리오! 그림출처 http://hucce.tistory.com/entry/%EC%9C%A0%ED%95%9C%EC%83%81% ED%83%9C%EA%B8%B0%EA%B3%84%EB%A5%BC- %EC%9D%B4%EC%9A%A9%ED%95%9C-%EA%B2%8C%EC%9E%84- %EA%B0%9C%EB%B0%9C Jeong Tae Hong 2013-01-25
Homework 지난 시간의 애니메이션 예제에 키보드 입력을 더하기 박스를 하나 생성하고, 충돌검사를 통해 박스를 움직이기 이번 시간에 제시된 예시처럼 구현하면 된다. 박스를 하나 생성하고, 충돌검사를 통해 박스를 움직이기 마찬가지로 예시와 동일 게임의 유한상태 기계를 생각해보고 종이에 그려본다. 전체적인 흐름, 각 세부 상태에서는 어떤 일이 일어나는지 상태가 바뀌기 위한 조건은 무엇인지. Advanced 4방향 충돌검사를 통해 박스를 네 방향으로 밀어서 이동시키기 아래에서 충돌 위로 밀려나기 Jeong Tae Hong 2013-01-25
Thanks 8시간에 걸쳐 배운 내용 JavaScript의 문법 HTML5 Canvas 기본적인 Syntax Object Based Programming : 객체란 무엇인가? Event Driven Programming : 이벤트와 핸들링 HTML5 Canvas Drawing Basic Simple Animation Adv. Animation Sprite Basic IDE를 활용한 개발과 Debugging Game Programming Basic Input Handling Basic Collision Basic Finite State Machine Basic Jeong Tae Hong 2013-01-25
Thanks 여러 가지 이유로 다루지 못한 내용 JavaScript Sprite Adv. Debugging Adv. 예외 처리와 JS의 고급 응용 DOM과 jQuery Sprite Adv. Debugging Adv. Game Programming 각 개념의 디테일과 심화 내용 Jeong Tae Hong 2013-01-25
Thanks 앞으로 진행할 일 Unity3D 기초 : 장세중 선배님께서 수업 진행 Unity3D와 JavaScript : 위 수업과 병행하여 스터디 진행 Web에서의 JS, 게임을 만들기 위한 JS, 유니티에서 쓰이는 JS 모두 다른 방식으로 응용된다. Unity3D의 JavaScript 라이브러리를 활용하는 방법에 대해 공부 Jeong Tae Hong 2013-01-25
Thanks 그럼 우리가 지금까지 힘들게 배운 것들은요? 필수 상식으로 버리기엔 너무 아깝다면… JavaScript 문법적 규칙 자체는 유니티에서도 유효하다. 애니메이션과 스프라이트 게임을 만들기 위한 필수 상식 입력 이벤트, 충돌 마찬가지로 필수 상식 필수 상식으로 버리기엔 너무 아깝다면… JavaScript 기반의 Web Game을 제작하는 모임은 어떨까? 제안 1 : 프로토타입 제작을 위한 도구로 활용 Unity3D의 수업이 진행되는 동안 프로토타입 제작 가능 제안 2 : Unity3D와 별도로 하나의 정식 개발 프로세스로 확립 의견을 수렴해보고 다시 논의 Jeong Tae Hong 2013-01-25