오늘은 어떤 실험을 할까 고민하다가 주제를 결정하지 못했는데 문득 고전 스네이크 게임이 생각나서 한번 캐릭을 조정하는 걸 표현을 해볼까 하는 생각에 정석은 아닌데 생각나는 느낌대로 코딩해서 실험을 해보았네요. 오늘 실험 내용은 Circle(원)을 스네이크라고 생각하고 켄버스 영역 내에서 키보드로 조정해보는 실험입니다.
//배경
var svg = d3.select("body").append("svg")
.attr("width",500)
.attr("height",500)
.style("background-color","yellow");
캔버스 영역을 500x500으로 잡았고 배경색은 Yellow Color로 지정했습니다. 계속 캔버스 영역에 대해 다루었기 때문에 이제 이 표현은 자연스럽게 다가 올꺼에요. 이 영역이 게임 배경이 됩니다.
var circle = svg.append("circle")
.attr("cx",circle_cx)
.attr("cy",circle_cy)
.attr("r",20)
.attr("fill","red")
이 부분은 Circl(원)을 지겹게 사용한 거라 circle_cx, circle,cy 좌표에 반지름 20인 Red 원을 그리는 코딩입니다.
이 부분이 실제 실험을 할 내용입니다. 어떻게 이동을 시켜야 circle(원)이 움직일까요.
이전에 배운 내용 중에 on() 이벤트 함수가 있습니다. 키보드나 마우스의 이벤트 함수로 키보드나 마우스의 어떤 동작이 발생하면 이벤트를 발생시킬 수 있는데 실험은 키보드 이벤트를 통해 circle(원)을 움직이게 하겠습니다.
위 키눌림과 키값을 통해서 circle을 움직이는 방향과 거리를 계산하고 setInterval()함수로 일정시간간격으로 rendering 을 하도록 하여 circle이 움직이게 만들도록 구상해 보았습니다.
순간 떠오로는 느낌이라 맘에 드는 코딩은 아닙니다. 그냥 느낌만 전달한 코딩으로 대충 아래와 같이 코딩했네요.
[조건]
[구상]
if(왼쪽키면) x은 -5만큼(y=0)
else if(오른쪽키면) x은 +5만큼(y=0)
if(위쪽키면) y은 -5만큼(x=0)
else if(아래쪽키면) y은 5만큼(x=0)
방향을 if문으로 이렇게 구상하고 x,y의 이동 거리는 5만큼 잡았습니다. x,y은 move_cx, move_cy로 변수로 별도 지정하여 최종 circle(원) 좌표에 더하는 식으로 만들 예정입니다.
d3.select("body")
.on("keydown", function() {
if(d3.event.keyCode==37){
move_cx=-5;
move_cy=0;
}
else if(d3.event.keyCode==39){
move_cx=5;
move_cy=0;
}
if(d3.event.keyCode==38){
move_cx=0;
move_cy=-5;
}
else if(d3.event.keyCode==40){
move_cx=0;
move_cy=5;
}
});
위 코딩을 보면 body 태그안에서 on() 함수가 실행 됩니다. 이렇게 하면 웹페이지 body 영역에서 키보드를 누르면 이벤트가 발생하는데 이때 누른 d3.event.keyCode 값에 따라 move_cx, move_cy 값이 결정됩니다.
이제 방향과 거리를 구했으니깐 circle(원)을 그려서 움직임을 만들어 봅시다.
[구상]
최종 원의 x좌표 : circle_cx = circle_cx+move_cx;
최종 원의 y좌표 : circle_cy = circle_cy+move_cy;
function render(){
svg.select("circle").remove(); //이전원 제거;
svg.append("circle") //원 그리기
.attr("cx",circle_cx)
.attr("cy",circle_cy)
.attr("r",20)
.attr("fill","red")
}
setInterval(render, 50);
원을 그릴 때 이전 원은 제거해야 하고 키로 눌렀을 때 move_cx, move_cy 방향과 거리 값을 원을 그리는 좌표 circle_cx, circle_cy 변수에 더해줌으로써 키가 누르는 방향과 거리로 circle(원) 그려집니다. 그리고 랜더링 시간은 0.05초로 빠르게 움직이게 했습니다. 시간값은 컴사양에 따라서 조정하시면 됩니다. 제 노트북은 똥컴이라서 0.05초도 느리게 움직이네요.
좀 다듬어서 코딩을 하면,
function render(){
svg.select("circle").remove(); //이전값 제거;
//최종 그려 질 원의 x,y좌표
circle_cx+=move_cx;
circle_cy+=move_cy;
// 캔버스 영역을 벗어나지 못하게 락을 검
if(circle_cx>=480) circle_cx=480;
else if(circle_cx<=20) circle_cx=20;
if(circle_cy>=480) circle_cy=480;
else if(circle_cy<=20) circle_cy=20;
svg.append("circle") //키값 출력
.attr("cx",circle_cx)
.attr("cy",circle_cy)
.attr("r",20)
.attr("fill","red")
}
setInterval(render, 50);
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var circle_cx=250;
var circle_cy=250
var move_cx=0;
var move_cy=0;
//배경
var svg = d3.select("body").append("svg")
.attr("width",500)
.attr("height",500)
.style("background-color","yellow");
var circle = svg.append("circle")
.attr("cx",circle_cx)
.attr("cy",circle_cy)
.attr("r",20)
.attr("fill","red")
d3.select("body")
.on("keydown", function() {
if(d3.event.keyCode==37){
move_cx=-5;
move_cy=0;
}
else if(d3.event.keyCode==39){
move_cx=5;
move_cy=0;
}
if(d3.event.keyCode==38){
move_cx=0;
move_cy=-5;
}
else if(d3.event.keyCode==40){
move_cx=0;
move_cy=5;
}
});
function render(){
svg.select("circle").remove(); //이전값 제거;
circle_cx+=move_cx;
circle_cy+=move_cy;
if(circle_cx>=480) circle_cx=480;
else if(circle_cx<=20) circle_cx=20;
if(circle_cy>=480) circle_cy=480;
else if(circle_cy<=20) circle_cy=20;
svg.append("circle") //키값 출력
.attr("cx",circle_cx)
.attr("cy",circle_cy)
.attr("r",20)
.attr("fill","red")
}
setInterval(render, 50);
</script>
</body>
키보드를 눌렀을 때 움직임만 실험한거라 게임오버 상태는 없네요.
오늘은 circle(원)을 스네이크 캐릭이라고 가정하고 조정을 해보았습니다. 조정 코딩이 깔끔하지 않고 부족한 부분이 많네요. 사실 잠결에 post 주제를 결정 못해서 생각나는데로 뭘 했는지 기억이 잘 안나네요. (^^)
완성하고 나니 게임을 만들고 싶긴 하는데 어떻게 할지 결정을 못했네요.
물건. 일본발 미니멀리즘이 살짝 유행이 지나는가 싶더니 소수를 중심으로 다시 조금씩 유행하고 ...