본문 바로가기
자바스크립트와 캔버스

철창속 고양이 스크립트 공개!

기능을 좀 더 넣은 최종판입니다 :) 
약속대로 스크립트를 공개합니다! 좀 스크롤 압박이 있을 수 있습니다 ㅎㅎ
코로나로 힘들어하는 분들이 모두 자유로워져 힘내시라는 의미도 있어요~

동영상, 배경음악 모두 저작권은 무료이고 영상은 픽사베이의 저작권 표시의무가 없지만
배경음악은 Music: www.bensound.com  이라는 문구를 포함해야 하는 의무가 있습니다.

아래 내용 안 보이시면 여쪽으로 오세요 ~ 🥾🥾 http://dreamplan7.cafe24.com/canvas7/canvas3.htm

 

공 통통

 

dreamplan7.cafe24.com

 

 

티스토리 게시글용

<script src="http://dreamplan7.cafe24.com/canvas7/craylib.js"></script>

<!-- 시작 -->
<!-- 영상 태그 : 볼륨이 0 이어야 자동 재생이 됨 -->
<video id="video" src="http://dreamplan7.cafe24.com/canvas7/Cat-35693.mp4" 
  preload="auto" autoplay controls="false" hidden 
  onloadstart="this.volume=0.0"></video>

<!-- 캔버스 -->
<canvas id="MyCanvas" width=640 height=360></canvas>

<!-- 스크립트 -->
<script>  
  let GameManager = new Object();
  GameManager.clicked=false;

  $(document).click(function( event ){
    GameManager.clicked=true;
  });

  $(document).ready(function(){
    Init(GameManager);
  });
  
  
  const video = document.querySelector('video');
  
  // 초기화
  async function Init(gm)
  {
    try{
      gm.Canvas=document.getElementById("MyCanvas");
      gm.Canvas.onmousemove = function(evt) {
        let rect = gm.Canvas.getBoundingClientRect();
        gm.mousex = evt.clientX - rect.left;
        gm.mousey = evt.clientY - rect.top;
      }
      gm.ctx=gm.Canvas.getContext("2d");
      
      // 스피커
      gm.speakerImage = 
        await loadImage("http://dreamplan7.cafe24.com/canvas7/speaker.png");
      
      // 스피커 off
      gm.speakerOffImage = 
        await loadImage("http://dreamplan7.cafe24.com/canvas7/speaker_off.png");
            
      // 배경음악
      gm.bgSound = 
        new Audio("http://dreamplan7.cafe24.com/canvas7/bensound-littleidea.mp3");
      gm.bgSound.loop = true;
      
      // 프리 로딩
      new Audio("http://dreamplan7.cafe24.com/canvas7/bensound-hey.mp3");
      
      // 배경음악 온/오프
      gm.bgOn=true;
      
      // 블록 효과음
      gm.collisionSound=
        new Audio("http://dreamplan7.cafe24.com/canvas7/keyboard_1.mp3");
      gm.collisionSound.volume=0.8;
      
      // 공 초기 위치 방향 랜덤
      gm.ball = {
        x:320, 
        y:320,
        speedx:rand(-3, 3)*2,
        speedy:rand(-3, 3)*2,
        radius:10
      }
      if(gm.ball.speedx==0)gm.ball.speedx=1;
      if(gm.ball.speedy==0)gm.ball.speedy=1;
      
      // 블록 여러개 생성
      // 블록의 기본 크기
      gm.blockwidth=80;
      gm.blockheight=20;
      // 블록 배열 채우기
      gm.block = new Array();
      for(let x=0; x<640; x+=gm.blockwidth)
        for(let y=20; y<300; y+=gm.blockheight)
        {
          gm.block.push({
            x:x,
            y:y,
            w:gm.blockwidth-1,
            h:gm.blockheight-1,
            alive:true,
            alpha:0.8
          });
        }
        
      gm.allclear=false;
      gm.allclearSpeed=10;
      
      // 애니메이션 시작
      requestAnimationFrame(Repeat);
    }catch(e){
      console.log(e)
    }
  }
  
  // HTML5 의 60fps 용 애니메이션 재생
  function Repeat()
  {
    Play(GameManager);
    requestAnimationFrame(Repeat);
  }
  
  // 60fps 속도로 호출되는 플레이 함수
  function Play(gm)
  {
    
    try{
      let ctx = gm.ctx;
      
      // 영상 복사해 배경에 그리기
      gm.Canvas.getContext('2d', { alpha: false })
        .drawImage(video, 0, 0, 640, 360);      
      
      // 클릭에 따라 스피커 온/오프
      if(gm.clicked==true)
      {
        gm.clicked=false;
        if(gm.mousex > 590 && gm.mousex < 590 + 30 &&
          gm.mousey > 320 && gm.mousey < 320 + 30)
        {
          gm.bgOn = !gm.bgOn;
          if(gm.bgOn==true) gm.bgSound.play();
          else gm.bgSound.pause();
        }
      }
      
      // 배경음악 ON 상태이고 배경음악 재생권한만 있으면 바로 재생
      if(gm.bgOn==true)
      {
        if(gm.bgSound.paused) 
          gm.bgSound.play();
      }
      
      if(gm.allclear==true)
      {
        if(gm.allclearSpeed<50)
          if(rand(0, 100) < 2 ) gm.allclearSpeed++;
      }
      
      if(video.paused) 
          video.play();
          
      // 공
      // 속도에 따라 이동
      gm.ball.x += gm.ball.speedx;
      gm.ball.y += gm.ball.speedy;
      
      // 벽 부딪힘 처리
      if(gm.ball.x<gm.ball.radius)
      {
        gm.ball.x=gm.ball.radius;
        if(!gm.allclear)
          gm.ball.speedx=rand(3,6);
        else
          gm.ball.speedx=rand(gm.allclearSpeed, gm.allclearSpeed);
      }
      if(gm.ball.x>640-gm.ball.radius)
      {
        gm.ball.x=640-gm.ball.radius;
        if(!gm.allclear)
          gm.ball.speedx=-rand(3,6);
        else
          gm.ball.speedx=-rand(gm.allclearSpeed, gm.allclearSpeed);
      }
      if(gm.ball.y<gm.ball.radius)
      {
        gm.ball.y=gm.ball.radius;
        if(!gm.allclear)
          gm.ball.speedy=rand(3,6);
        else
          gm.ball.speedy=rand(gm.allclearSpeed, gm.allclearSpeed);
      }
      if(gm.ball.y>360-gm.ball.radius)
      {      
        gm.ball.y=360-gm.ball.radius;
        if(!gm.allclear)
          gm.ball.speedy=-rand(3,6);
        else
          gm.ball.speedy=-rand(gm.allclearSpeed, gm.allclearSpeed);
      }
      
      ctx.beginPath();
      ctx.strokeStyle='black';
      ctx.arc(
        gm.ball.x, gm.ball.y, gm.ball.radius, 
        0, (Math.PI/180)*360, false);
      ctx.fillStyle='white';
      ctx.fill();
      ctx.closePath();
      
      // 블록 충돌
      let broken=false;
      for(let i=0;i<gm.block.length; ++i){
        let thisblock = gm.block[i];
        if(thisblock.alive==false)continue;
        
        // 블록상단 충돌
        if(check_box_collision(
          thisblock.x, thisblock.y, 
          thisblock.w, 0, 
          gm.ball.x-gm.ball.radius, gm.ball.y-gm.ball.radius, 
          gm.ball.radius*2, gm.ball.radius*2))
        {
          gm.ball.speedy=-rand(3,6);
          thisblock.alive=false;
          broken=true;
          break;
        }
        
        // 블록하단 충돌
        if(check_box_collision(
          thisblock.x, thisblock.y + thisblock.h, 
          thisblock.w, 0,
          gm.ball.x-gm.ball.radius, gm.ball.y-gm.ball.radius, 
          gm.ball.radius*2, gm.ball.radius*2))
        {
          gm.ball.speedy=rand(3,6);
          thisblock.alive=false;
          broken=true;
          break;
        }
        
        // 블록좌측 충돌
        if(check_box_collision(
          thisblock.x, thisblock.y, 
          0, thisblock.h,
          gm.ball.x-gm.ball.radius, gm.ball.y-gm.ball.radius, 
          gm.ball.radius*2, gm.ball.radius*2))
        {
          gm.ball.speedx=-rand(3,6);
          thisblock.alive=false;
          broken=true;
          break;
        }
        
        // 블록우측 충돌
        if(check_box_collision(
          thisblock.x+thisblock.w, thisblock.y, 
          0, thisblock.h,
          gm.ball.x-gm.ball.radius, gm.ball.y-gm.ball.radius, 
          gm.ball.radius*2, gm.ball.radius*2))
        {
          gm.ball.speedx=rand(3,6);
          thisblock.alive=false;
          broken=true;
          break;
        }
      }
      
      // 블록이 제거된 경우만 모든 블록이 클리어되었나 검사
      if(broken==true)
      {
        if(gm.bgOn==true)
          gm.collisionSound.play();
        let allclear=true;
        for(let i=0;i<gm.block.length; ++i)
          if(gm.block[i].alive==true){
            allclear=false;
            break;
          }
        // 영상, 배경음악 체인지
        if(allclear==true)
        {
          video.src="http://dreamplan7.cafe24.com/canvas7/Cat-32218.mp4";
          gm.bgSound.src = "http://dreamplan7.cafe24.com/canvas7/bensound-hey.mp3";
          gm.bgSound.play();
          gm.allclear=true;
        }
      }
      
      // 블록      
      ctx.beginPath();        
      for(let i=0;i<gm.block.length; ++i){
        if(gm.block[i].alpha<=0)continue;
        if(gm.block[i].alive==false)
          gm.block[i].alpha-=0.05;
        ctx.fillStyle='rgba(0, 0, 255, ' + gm.block[i].alpha + ')';        
        ctx.fillRect(
          gm.block[i].x, gm.block[i].y, 
          gm.block[i].w, gm.block[i].h
        );
      }
      ctx.closePath();
      
      // 스피커 이미지
      if(gm.bgOn==true)
        ctx.drawImage(
          gm.speakerImage, 
          590, 320
        );
      else
        ctx.drawImage(
          gm.speakerOffImage, 
          590, 320
        );
      
      // 배경 음악 사용 사용 조건 텍스트 표시 규정 준수
      ctx.font = 'italic 12pt Calibri';
      ctx.fillStyle = 'white';
      ctx.fillText('Music: www.bensound.com', 10, 350);
    }catch(e){
      console.log(e)
    }
  }

</script>

홈페이지용

<!DOCTYPE html>
<html lang="ko">
<head>
	<meta charset="UTF-8">
	<title>공 통통</title>
</head>
<body style='background-color:black'>
<a href='http://itadventure.tistory.com/category/자바스크립트와%20캔버스' 
  target='_blank'>
  https://itadventure.tistory.com
</a>
/ 크레이의 IT탐구<br/>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="http://dreamplan7.cafe24.com/canvas7/craylib.js"></script>

<!-- 시작 -->
<!-- 영상 태그 : 볼륨이 0 이어야 자동 재생이 됨 -->
<video id="video" src="http://dreamplan7.cafe24.com/canvas7/Cat-35693.mp4" 
  preload="auto" autoplay controls="false" hidden 
  onloadstart="this.volume=0.0"></video>

<!-- 캔버스 -->
<canvas id="MyCanvas" width=640 height=360></canvas>

<!-- 스크립트 -->
<script>  
  let GameManager = new Object();
  GameManager.clicked=false;

  $(document).click(function( event ){
    GameManager.clicked=true;
  });

  $(document).ready(function(){
    Init(GameManager);
  });
  
  
  const video = document.querySelector('video');
  
  // 초기화
  async function Init(gm)
  {
    try{
      gm.Canvas=document.getElementById("MyCanvas");
      gm.Canvas.onmousemove = function(evt) {
        let rect = gm.Canvas.getBoundingClientRect();
        gm.mousex = evt.clientX - rect.left;
        gm.mousey = evt.clientY - rect.top;
      }
      gm.ctx=gm.Canvas.getContext("2d");
      
      // 스피커
      gm.speakerImage = 
        await loadImage("http://dreamplan7.cafe24.com/canvas7/speaker.png");
      
      // 스피커 off
      gm.speakerOffImage = 
        await loadImage("http://dreamplan7.cafe24.com/canvas7/speaker_off.png");
            
      // 배경음악
      gm.bgSound = 
        new Audio("http://dreamplan7.cafe24.com/canvas7/bensound-littleidea.mp3");
      gm.bgSound.loop = true;
      
      // 프리 로딩
      new Audio("http://dreamplan7.cafe24.com/canvas7/bensound-hey.mp3");
      
      // 배경음악 온/오프
      gm.bgOn=true;
      
      // 블록 효과음
      gm.collisionSound=
        new Audio("http://dreamplan7.cafe24.com/canvas7/keyboard_1.mp3");
      gm.collisionSound.volume=0.8;
      
      // 공 초기 위치 방향 랜덤
      gm.ball = {
        x:320, 
        y:320,
        speedx:rand(-3, 3)*2,
        speedy:rand(-3, 3)*2,
        radius:10
      }
      if(gm.ball.speedx==0)gm.ball.speedx=1;
      if(gm.ball.speedy==0)gm.ball.speedy=1;
      
      // 블록 여러개 생성
      // 블록의 기본 크기
      gm.blockwidth=80;
      gm.blockheight=20;
      // 블록 배열 채우기
      gm.block = new Array();
      for(let x=0; x<640; x+=gm.blockwidth)
        for(let y=20; y<300; y+=gm.blockheight)
        {
          gm.block.push({
            x:x,
            y:y,
            w:gm.blockwidth-1,
            h:gm.blockheight-1,
            alive:true,
            alpha:0.8
          });
        }
        
      gm.allclear=false;
      gm.allclearSpeed=10;
      
      // 애니메이션 시작
      requestAnimationFrame(Repeat);
    }catch(e){
      console.log(e)
    }
  }
  
  // HTML5 의 60fps 용 애니메이션 재생
  function Repeat()
  {
    Play(GameManager);
    requestAnimationFrame(Repeat);
  }
  
  // 60fps 속도로 호출되는 플레이 함수
  function Play(gm)
  {
    
    try{
      let ctx = gm.ctx;
      
      // 영상 복사해 배경에 그리기
      gm.Canvas.getContext('2d', { alpha: false })
        .drawImage(video, 0, 0, 640, 360);      
      
      // 클릭에 따라 스피커 온/오프
      if(gm.clicked==true)
      {
        gm.clicked=false;
        if(gm.mousex > 590 && gm.mousex < 590 + 30 &&
          gm.mousey > 320 && gm.mousey < 320 + 30)
        {
          gm.bgOn = !gm.bgOn;
          if(gm.bgOn==true) gm.bgSound.play();
          else gm.bgSound.pause();
        }
      }
      
      // 배경음악 ON 상태이고 배경음악 재생권한만 있으면 바로 재생
      if(gm.bgOn==true)
      {
        if(gm.bgSound.paused) 
          gm.bgSound.play();
      }
      
      if(gm.allclear==true)
      {
        if(gm.allclearSpeed<50)
          if(rand(0, 100) < 2 ) gm.allclearSpeed++;
      }
      
      if(video.paused) 
          video.play();
          
      // 공
      // 속도에 따라 이동
      gm.ball.x += gm.ball.speedx;
      gm.ball.y += gm.ball.speedy;
      
      // 벽 부딪힘 처리
      if(gm.ball.x<gm.ball.radius)
      {
        gm.ball.x=gm.ball.radius;
        if(!gm.allclear)
          gm.ball.speedx=rand(3,6);
        else
          gm.ball.speedx=rand(gm.allclearSpeed, gm.allclearSpeed);
      }
      if(gm.ball.x>640-gm.ball.radius)
      {
        gm.ball.x=640-gm.ball.radius;
        if(!gm.allclear)
          gm.ball.speedx=-rand(3,6);
        else
          gm.ball.speedx=-rand(gm.allclearSpeed, gm.allclearSpeed);
      }
      if(gm.ball.y<gm.ball.radius)
      {
        gm.ball.y=gm.ball.radius;
        if(!gm.allclear)
          gm.ball.speedy=rand(3,6);
        else
          gm.ball.speedy=rand(gm.allclearSpeed, gm.allclearSpeed);
      }
      if(gm.ball.y>360-gm.ball.radius)
      {      
        gm.ball.y=360-gm.ball.radius;
        if(!gm.allclear)
          gm.ball.speedy=-rand(3,6);
        else
          gm.ball.speedy=-rand(gm.allclearSpeed, gm.allclearSpeed);
      }
      
      ctx.beginPath();
      ctx.strokeStyle='black';
      ctx.arc(
        gm.ball.x, gm.ball.y, gm.ball.radius, 
        0, (Math.PI/180)*360, false);
      ctx.fillStyle='white';
      ctx.fill();
      ctx.closePath();
      
      // 블록 충돌
      let broken=false;
      for(let i=0;i<gm.block.length; ++i){
        let thisblock = gm.block[i];
        if(thisblock.alive==false)continue;
        
        // 블록상단 충돌
        if(check_box_collision(
          thisblock.x, thisblock.y, 
          thisblock.w, 0, 
          gm.ball.x-gm.ball.radius, gm.ball.y-gm.ball.radius, 
          gm.ball.radius*2, gm.ball.radius*2))
        {
          gm.ball.speedy=-rand(3,6);
          thisblock.alive=false;
          broken=true;
          break;
        }
        
        // 블록하단 충돌
        if(check_box_collision(
          thisblock.x, thisblock.y + thisblock.h, 
          thisblock.w, 0,
          gm.ball.x-gm.ball.radius, gm.ball.y-gm.ball.radius, 
          gm.ball.radius*2, gm.ball.radius*2))
        {
          gm.ball.speedy=rand(3,6);
          thisblock.alive=false;
          broken=true;
          break;
        }
        
        // 블록좌측 충돌
        if(check_box_collision(
          thisblock.x, thisblock.y, 
          0, thisblock.h,
          gm.ball.x-gm.ball.radius, gm.ball.y-gm.ball.radius, 
          gm.ball.radius*2, gm.ball.radius*2))
        {
          gm.ball.speedx=-rand(3,6);
          thisblock.alive=false;
          broken=true;
          break;
        }
        
        // 블록우측 충돌
        if(check_box_collision(
          thisblock.x+thisblock.w, thisblock.y, 
          0, thisblock.h,
          gm.ball.x-gm.ball.radius, gm.ball.y-gm.ball.radius, 
          gm.ball.radius*2, gm.ball.radius*2))
        {
          gm.ball.speedx=rand(3,6);
          thisblock.alive=false;
          broken=true;
          break;
        }
      }
      
      // 블록이 제거된 경우만 모든 블록이 클리어되었나 검사
      if(broken==true)
      {
        if(gm.bgOn==true)
          gm.collisionSound.play();
        let allclear=true;
        for(let i=0;i<gm.block.length; ++i)
          if(gm.block[i].alive==true){
            allclear=false;
            break;
          }
        // 영상, 배경음악 체인지
        if(allclear==true)
        {
          video.src="http://dreamplan7.cafe24.com/canvas7/Cat-32218.mp4";
          gm.bgSound.src = "http://dreamplan7.cafe24.com/canvas7/bensound-hey.mp3";
          gm.bgSound.play();
          gm.allclear=true;
        }
      }
      
      // 블록      
      ctx.beginPath();        
      for(let i=0;i<gm.block.length; ++i){
        if(gm.block[i].alpha<=0)continue;
        if(gm.block[i].alive==false)
          gm.block[i].alpha-=0.05;
        ctx.fillStyle='rgba(0, 0, 255, ' + gm.block[i].alpha + ')';        
        ctx.fillRect(
          gm.block[i].x, gm.block[i].y, 
          gm.block[i].w, gm.block[i].h
        );
      }
      ctx.closePath();
      
      // 스피커 이미지
      if(gm.bgOn==true)
        ctx.drawImage(
          gm.speakerImage, 
          590, 320
        );
      else
        ctx.drawImage(
          gm.speakerOffImage, 
          590, 320
        );
      
      // 배경 음악 사용 사용 조건 텍스트 표시 규정 준수
      ctx.font = 'italic 12pt Calibri';
      ctx.fillStyle = 'white';
      ctx.fillText('Music: www.bensound.com', 10, 350);
    }catch(e){
      console.log(e)
    }
  }

</script>
</body>
</html>

 

티스토리 게시글 쓰는 법

 

티스토리에 게시글을 작성하실 때 편리한 방법이 있더라구요.
삼점이 아이콘 클릭 후  HTML 블럭 메뉴를 선택하시고 스크립트를 넣으면 오케이!

 

 

배경음악을 바꾸고 싶으신가요?

 

배경음악을 어딘가 업로드하셔서 아래와 같은 소스에서 따옴표 안의 배경음악 주소를 수정해 주세요.

// 배경음악
gm.bgSound = 
   new Audio("http://dreamplan7.cafe24.com/canvas7/bensound-littleidea.mp3");

 

아울러 클리어했을 때 배경음악은 아래 부분과

// 프리 로딩
new Audio("http://dreamplan7.cafe24.com/canvas7/bensound-hey.mp3");

아래 부분에서 bensound-hey 라고 된 부분의 따옴표 문장을 바꾸시면 되요

// 영상, 배경음악 체인지
if(allclear==true)
{
  video.src="http://dreamplan7.cafe24.com/canvas7/Cat-32218.mp4";
  gm.bgSound.src = "http://dreamplan7.cafe24.com/canvas7/bensound-hey.mp3";
  gm.bgSound.play();
  gm.allclear=true;
}

 

영상을 바꾸고 싶어요

 

영상을 어딘가에 업로드하신 다음 아래 태그에서 src 우측 따옴표 내의 문장을 변경하시고

<video id="video" src="http://dreamplan7.cafe24.com/canvas7/Cat-35693.mp4" 
  preload="auto" autoplay controls="false" hidden 
  onloadstart="this.volume=0.0"></video>

 

클리어했을때 영상은 아래 소스를 바꿔주시면 됩니다 :)

video.src="http://dreamplan7.cafe24.com/canvas7/Cat-32218.mp4";

 


방문해주시는 모든 분들께 늘 감사드립니다.

재미있으셨다면 공감 한방, 댓글은 굿잡!
감사합니다~