JavaScript setInterval() 함수를 이용하여 토끼를 클릭했을때 풍선이 사방으로 퍼지는 효과를 만들어보자.
1. 먼저 풍선 이미지를 저장할 배열과 풍선이미지를 불러오고 풍선 효과를 줄때 필요한 배열을 생성한다.
사용한 풍선이미지는 다음과 같다.
2. mousedoun 이벤트의 함수 안에 토끼를 클릭했을때 이벤트가 발생해야 하므로 if (isRabbitDie) 안에 추가로 for문을 작성한다.
3. setInterval 함수 안에 풍선을 그리는 for문과 움직이는 for 문을 작성한다.
4. 토끼이미지를 클릭한 지점부터 색이 다른 풍선들이 랜덤한 속도로 퍼져 나가는걸 볼 수 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Step09_example5.html</title>
<style>
canvas{
border: 1px solid red;
}
</style>
</head>
<body>
<h1>canvas 요소 활용해 보기</h1>
<!-- canvas 요소는 width 와 height 를 속성으로 직접 지정할수 있다. -->
<canvas id="myCanvas" width="800" height="500"></canvas>
<script>
//canvas 요소의 참조값
const canvas=document.querySelector("#myCanvas");
//canvas 에 그림을 그릴 도구(context) 객체 얻어내기
const context=canvas.getContext("2d");
//canvas 에 그릴 이미지 로딩하기
const snipeImg=new Image();
snipeImg.src="images/snipe.png";
const holeImg=new Image();
holeImg.src="images/hole.png";
const backImg=new Image();
backImg.src="images/background.jpg";
//토끼 이미지 로딩
const rabbitImg1=new Image();
rabbitImg1.src="images/rabbit_1.png";
const rabbitImg2=new Image();
rabbitImg2.src="images/rabbit2.png";
//로딩된 이미지를 배열에 담아 놓는다 (나중에 애니매이션 효과를 주기 위해)
const rabbitImgs=[rabbitImg1, rabbitImg2];
//snipe 의 좌표
let snipeX=0, snipeY=0;
//총알 구멍 객체(object) 를 저장할 배열
const holes=[];
//토끼의 좌표
let rabbitX=400, rabbitY=250;
//토끼 이미지 인덱스
let rabbitIndex=0;
//카운트를 셀 변수
let count=0;
//효과음 로딩하기
const fireSound = new Audio("sounds/fire.wav");
const dieSound = new Audio("sounds/birddie.mp3");
// 풍선 이미지 저장할 배열
const bubbleImgsp=[];
//풍선 이미지 로딩
for (let i=0; i<6; i++) {
// 풍선 이미지를 로딩해서
let tmp=new Image()
tmp.src="images/b"+i+".png";
// 배열에 누적시키기
bubbleImgsp.push(tmp);
}
// 풍선의 정보를 저장할 배열
const bubbles=[];
setInterval(()=>{
//함수가 호출될때 마다 count 를 1 씩 증가 시킨다
count++;
//여기 함수 내부는 1/100 초 마다 한번씩 실행된다.
//context.clearRect(0, 0, 800, 500);
//배경이미지를 canvas 의 크기에 맞게 그린다.
context.drawImage(backImg, 0, 0, 800, 500);
//총알 구멍 이미지를 반복문 돌면서 모두 그린다.
for(let i=0; i<holes.length; i++){
//i번째 총알 구멍 이미지 정보를 담고 있는 객체를 불러와서
let tmp=holes[i];
//거기에 담긴 x, y 좌표를 이용해서 총알 구멍을 그린다.
context.drawImage(holeImg, tmp.x-10, tmp.y-10, 20, 20);
}
// 토끼 그리기
context.drawImage(rabbitImgs[rabbitIndex], rabbitX-50, rabbitY-50, 100, 100)
// 풍선 그리기
for(let i=0; i<bubbles.length; i++) {
// i번째 풍선 정보를 가지고 있는 object 를 참조해서
let tmp = bubbles[i];
// object 안에 있는 정보를 바탕으로 풍선을 그린다.
context.drawImage(bubbleImgsp[tmp.index], tmp.x-25, tmp.y-25, 50, 50);
}
// 풍선 움직이기
for(let i=0; i<bubbles.length; i++) {
let tmp = bubbles[i];
// 각각 풍선의 speedX, speedY 값 만큼 x,y 좌표를 변화시킨다.
tmp.x+= tmp.speedX;
tmp.y+= tmp.speedY;
}
//스나이프 그리기
context.drawImage(snipeImg, snipeX-50, snipeY-50, 100, 100);
if(count%20 == 0){
//토끼 이미지 인덱스 1 증가 시키기
rabbitIndex++;
//만일 존재하지 않는 인덱스라면 0 으로 초기화 하기
if(rabbitIndex==2){
rabbitIndex=0;
}
}
// 0~99 사이의 랜덤한 정수를 얻어내서
let ranNum= parseInt(Math.random()*100);
// 우연히 50이 나올때만 (확률상 1초에 대략 1번꼴)
if (ranNum==50) {
//토끼를 랜덤한 위치로 움직이게 하기
rabbitX = Math.random()*700 + 50;
rabbitY = Math.random()*400 + 50;
}
}, 10);
//canvas 요소의 mousemove 이벤트 처리
canvas.addEventListener("mousemove", (e)=>{
//이벤트가 발생한곳의 canvas 내에서의 좌표를 snipeX, snipeY 에 반영
snipeX=e.offsetX;
snipeY=e.offsetY;
});
canvas.addEventListener("mousedown", (e)=>{
// mousedown 이벤트가 발생한 곳의 좌표를 변수에 담아놓고 아래에서 2번 사용
let x = e.offsetX
let y = e.offsetY
//이벤트가 발생한 곳의 좌표를 object 에 담는다.
// const hole={x:x, y:y} 의 줄임표현
const hole={x, y};
//holes 배열에 저장(누적) 시킨다.
holes.push(hole);
// 재생 위치를 처음으로 리셋 후
fireSound.currentTime=0;
// 총소리 재생
fireSound.play();
// 토끼가 총에 맞았는지 판별해서 맞았으면 소리재생
let isRabbitDie = x > rabbitX-50 &&
x < rabbitX+50 &&
y > rabbitY-50 &&
y < rabbitY+50
if (isRabbitDie) {
dieSound.currentTime=0;
dieSound.play();
console.log("죽는소리")
//풍선6개 만들기
for (let i=0; i<6; i++) {
//새로운 object를 하나 만들어서
let tmp ={};
//풍선 하나의 정보를 담고
tmp.x = rabbitX;
tmp.y = rabbitY;
tmp.index = i;
tmp.speedX = Math.random()*20-10
tmp.speedY = Math.random()*20-10
bubbles.push(tmp);
}
}
});
</script>
</body>
</html>