【Part7】 <JS>Symbolブロック崩しV2・V3

Uncategorized
この記事は約29分で読めます。

NEMTUSハッカソンに向けて

プログラム超初心者達が

Symbolを取り入れた簡単なゲームを開発するお話。

『~Challenge SymbolEnjoneer~』

一緒に見ていきましょう!Let’s Enjoy

part.7

こんにちは!サカショウです🐶

前回パートでは、スロットゲームとブロック崩しゲームを作成しSymbolを実装しました!
今回は、前回作ったブロック崩しゲームを改造して、別のステージを2つ完成させましょう✨

それでは、僕と一緒に進めていきましょう。

※本連載記事に記載の内容は、テストネットのみの利用にとどめてください。 そのままメインネットに使用する事は、できません。 秘密鍵が公開されてしまいますので、絶対にメインネットで使用しないと約束してください。

【今回パートに必要なもの】

  • PC(サカショウの環境は、Windows10)
  • インターネット環境
  • Symbol Desktop Wallet V1.0.9(テストネット)
  • テストネットアカウント×2
  • ブラウザ(Google chrome)(サカショウは、BraveのGoogleブラウザ)
  • VSCode

()内は、サカショウの環境です。異なる環境の場合、異なる挙動を取る可能性があります。

【使用するツールとライブラリ】

【 サカショウ Hack+Version】 ブロック崩しV2

こんな感じです。

※前回パートで作成したブロック崩しV1のファイルを複製して開いてください。
var要素とStyleタグの変数を少し変更します!

<head>
    <meta charset="utf-8" />
    <title>ブロック崩しv2</title>
    //backgroundを' #000 'に変更する。
    <style>
    	* { padding: 20; margin: 20; }
    	canvas { background: #eee; display: block; margin: 0 auto; 
    </style>
</head>

まずは、3行目~10行目辺りにあるStyleを変更して、ゲーム背景を黒色にします。

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 10;
var x = canvas.width/2;
var y = canvas.height-30;
var dx = 2;
var dy = -2;
var paddleHeight = 10;
//paddleWidthを' 70 'に変更して、少しパドル幅を狭めます。
var paddleWidth = 75;
var paddleX = (canvas.width-paddleWidth)/2;
var rightPressed = false;
var leftPressed = false;
//brickRowCountとbrickColumnCountを' 6 'と' 5 'に変更して、ブロックの行と列を変更します。
var brickRowCount = 6;
var brickColumnCount = 5;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var score = 0;
var lives = 1;

25行目~45行目辺りにある上記のvar要素を、
//以降に書いてある指示に従い、必要事項を変更する。

【答え合わせ】

  • 0000000….の羅列記載箇所を、送金するアカウントの秘密鍵に変更する。
  • aaaaaaa…..の羅列記載箇所を、XYMを受け取るアカウントのアドレスに変更する。

上記2か所を自分のアカウント情報に変更することで、ブロック崩しV2が遊べます🐶✨

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8" />
    <title>ブロック崩しv2</title>
    <style>
    	* { padding: 20; margin: 20; }
    	canvas { background: #000; display: block; margin: 0 auto; 
    </style>
</head>
<body>
 <canvas id="myCanvas" width="480" height="320"></canvas>

 <script src="https://xembook.github.io/nem2-browserify/symbol-sdk-1.0.1.js"></script>

 <script language="JavaScript">
    NODE = 'https://sym-test-07.opening-line.jp:3001';
    GENERATION_HASH = '7FCCD304802016BEBBCD342A332F91FF1F3BB5E902988B352697BE245F48E836';
    EPOCH_ADJUSTMENT = 1637848847;

    nem = require("/node_modules/symbol-sdk");

    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");
    var ballRadius = 10;
    var x = canvas.width / 2;
    var y = canvas.height - 30;
    var dx = 2;
    var dy = -2; 
    var paddleHeight = 10;
    var paddleWidth = 70;
    var paddleX = (canvas.width - paddleWidth) / 2;    
    var rightPressed = false;
    var leftPressed = false;        
    var brickRowCount = 5;
    var brickColumnCount = 3;
    var brickWidth = 75;
    var brickHeight = 20;
    var brickPadding = 10;
    var brickOffsetTop = 30;
    var brickOffsetLeft = 30;
    var score = 0;
    var lives = 1;
    
    var bricks = [];   
    for(var c = 0; c < brickColumnCount; c++) {
      bricks[c] = [];
      for(var r = 0; r < brickRowCount; r++) {
        bricks[c][r] = {x: 0, y: 0, status: 1};
      }
    }

    document.addEventListener("keydown", keyDownHandler, false);
    document.addEventListener("keyup", keyUpHandler, false);
    document.addEventListener("mousemove", mouseMoveHandler, false);
    
    function keyDownHandler(e) {
      if(e.key == "Right" || e.key == "ArrowRight") {
        rightPressed = true;
      }
      else if(e.key == "Left" || e.key == "ArrowLeft") {
        leftPressed = true;
      }
    }
    
    function keyUpHandler(e) {
      if(e.key == "Right" || e.key == "ArrowRight") {
        rightPressed = false;
      }
      else if(e.key == "Left" || e.key == "ArrowLeft") {
        leftPressed = false;
      }
    }
    
    function mouseMoveHandler(e) {
      var relativeX = e.clientX - canvas.offsetLeft;
      if(relativeX > 0 && relativeX < canvas.width) {
        paddleX = relativeX - paddleWidth / 2;
      }
    
    }  

    function collisionDetection() {
      for(var c = 0; c < brickColumnCount; c++) {
        for(var r = 0; r < brickRowCount; r++) {
          var b = bricks[c][r];
    
          if(b.status == 1) {
            if(x > b.x && x < b.x + brickWidth && y > b.y && y < b.y + brickHeight) {
              dy = -dy;
              b.status = 0;
              score++;
    
              if(score == brickRowCount * brickColumnCount) {
                 alert("YOU WIN, CONGRATULATIONS!");
                  alice = nem.Account.createFromPrivateKey('000000000000000000000000000000000000000000000000000000000000000', 
                  nem.NetworkType.TEST_NET);
                  console.log(alice);
  
                  tx = nem.TransferTransaction.create(
                     nem.Deadline.create(EPOCH_ADJUSTMENT),
                     nem.Address.createFromRawAddress("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
                     [new nem.Mosaic(new nem.MosaicId('3A8416DB2D53B6C8'), nem.UInt64.fromUint(1000000))],
                     nem.PlainMessage.create('NEMTUS Hackathon Hack+2022 ブロック崩しv2 Clear!'),
                     nem.NetworkType.TEST_NET,
                     nem.UInt64.fromUint(100000)
                     );
                     console.log(tx);

                 signedTx = alice.sign(tx, GENERATION_HASH);

                  console.log(signedTx);

                 new nem.TransactionHttp(NODE)
                 .announce(signedTx)
                 .subscribe((x) => console.log(x), (err) => console.error(err));
                 
                 alert("Reload");
                 document.location.reload();  

              }
            }
          }
        }
      }
    }

    function drawBall() {
      ctx.beginPath();
      ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
      ctx.fillStyle = "#0095DD";
      ctx.fill();
      ctx.closePath();
    }

    function drawPaddle() {
      ctx.beginPath();
      ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
      ctx.fillStyle = "#0095DD";
      ctx.fill();
      ctx.closePath();
    }

    function drawBricks() {
      for(var c = 0; c < brickColumnCount; c++) {
        for(var r = 0; r < brickRowCount; r++) {
    
          if(bricks[c][r].status == 1) {
            var brickX = (c * (brickWidth + brickPadding)) + brickOffsetLeft;
            var brickY = (r * (brickHeight + brickPadding)) + brickOffsetTop;
            bricks[c][r].x = brickX;
            bricks[c][r].y = brickY;
    
            ctx.beginPath();
            ctx.rect(brickX, brickY, brickWidth, brickHeight);
            ctx.fillStyle = "#0095DD";
            ctx.fill();
            ctx.closePath();
          }
        }
      }
    }

    function drawScore() {
      ctx.font = "16px Arial";
      ctx.fillStyle = "#0095DD";
      ctx.fillText("Score:" + score, 8, 20);
    }
    
    function drawLives() {
      ctx.font = "16px Arial";
      ctx.fillStyle = "#0095DD";
      ctx.fillText("Lives:" + lives, canvas.width - 65, 20);
    }        
    
    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      drawBall();
      drawBricks();
      drawPaddle();
      drawScore();
      drawLives();
      collisionDetection();
    
      if(x + dx > canvas.width - ballRadius | x + dx < ballRadius) {
        dx = -dx;
      }
    
      if(y + dy < ballRadius) {
        dy = -dy;
      } else if(y + dy > canvas.height - ballRadius) {
    
        if(x > paddleX && x < paddleX + paddleWidth) {
          dy = -dy;
        }
        else {
          lives--;
    
          if(!lives) {
            alert("GAME OVER");
            document.location.reload();
          }
          else {
            x = canvas.width / 2;
            y = canvas.height - 30;
            dx = 3;
            dy = -3;

            paddleX = (canvas.width - paddleWidth) / 2;
          }
        }
      }
    
      if(rightPressed && paddleX < canvas.width - paddleWidth) {
        paddleX += 7;
      }
      else if(leftPressed && paddleX > 0) {
        paddleX -= 7;
      }
    
      x += dx;
      y += dy;
    
      requestAnimationFrame(draw);
    }
       
    draw();   
 </script>

</body>
</html>

【 サカショウ Hack+Version】 ブロック崩しV3

こんな感じです。

ブロック崩しV2のどこを変えればブロック崩しV3になるのかな?
行った変更点は、ブロックのサイズと設置個数変更、余白調整とカラー変更、パドルに反発する度にボールを加速させる。これらを追加変更しています😋
コードを見比べて、読解力を鍛えてみよう!🐶✨

  • 0000000….の羅列記載箇所を、送金するアカウントの秘密鍵に変更する。
  • aaaaaaa…..の羅列記載箇所を、XYMを受け取るアカウントのアドレスに変更する。

上記2か所を自分のアカウント情報に変更することで、ブロック崩しV3が遊べます🐶✨

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8" />
    <title>ブロック崩しv3</title>
    <style>
    	* { padding: 20; margin: 20; }
    	canvas { background: #000; display: block; margin: 0 auto; 
    </style>
</head>
<body>

 <canvas id="myCanvas" width="480" height="320"></canvas>

 <script src="https://xembook.github.io/nem2-browserify/symbol-sdk-1.0.1.js"></script>

 <script language="JavaScript">
    NODE = 'https://sym-test-07.opening-line.jp:3001';
    GENERATION_HASH = '7FCCD304802016BEBBCD342A332F91FF1F3BB5E902988B352697BE245F48E836';
    EPOCH_ADJUSTMENT = 1637848847;

    nem = require("/node_modules/symbol-sdk");

    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");  
    var ballRadius = 12;  
    var x = canvas.width / 2;
    var y = canvas.height - 30;   
    var dx = 2;
    var dy = -2;   
    var paddleHeight = 10;
    var paddleWidth = 70;
    var paddleX = (canvas.width - paddleWidth) / 2;   
    var rightPressed = false;
    var leftPressed = false;  
    var brickRowCount = 5;
    var brickColumnCount = 10;
    var brickWidth = 38;
    var brickHeight = 30;
    var brickPadding = 7;
    var brickOffsetTop = 20;
    var brickOffsetLeft = 20;
    var bricks = [];
    var score = 0;
    var lives = 3;
    var bricks = [];

    for(var c = 0; c < brickColumnCount; c++) {
      bricks[c] = [];
      for(var r = 0; r < brickRowCount; r++) {
        bricks[c][r] = {x: 0, y: 0, status: 1};
      }
    }
    
    function collisionDetection() {
      for(var c = 0; c < brickColumnCount; c++) {
        for(var r = 0; r < brickRowCount; r++) {
          var b = bricks[c][r];
    
          if(b.status == 1) {
            if(x > b.x && x < b.x + brickWidth && y > b.y && y < b.y + brickHeight) {
              dy = -dy;
              b.status = 0;
              score++;
    
              if(score == brickRowCount * brickColumnCount) {
                 alert("YOU WIN, CONGRATULATIONS!");
                  alice = nem.Account.createFromPrivateKey('0000000000000000000000000000000000000000000000000000', 
                  nem.NetworkType.TEST_NET);
                  console.log(alice);
  
                  tx = nem.TransferTransaction.create(
                     nem.Deadline.create(EPOCH_ADJUSTMENT),
                     nem.Address.createFromRawAddress('aaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
                     [new nem.Mosaic(new nem.MosaicId('3A8416DB2D53B6C8'), nem.UInt64.fromUint(1000000))],
                     nem.PlainMessage.create('NEMTUS Hackathon Hack+2022 ブロック崩しv3 Clear!'),
                     nem.NetworkType.TEST_NET,
                     nem.UInt64.fromUint(100000)
                     );
                     console.log(tx);

                 signedTx = alice.sign(tx, GENERATION_HASH);

                  console.log(signedTx);

                 new nem.TransactionHttp(NODE)
                 .announce(signedTx)
                 .subscribe((x) => console.log(x), (err) => console.error(err));

                  alert("Reload");
                  document.location.reload();                                  

              }
            }
          }
        }
      }
    }
    
    function drawScore() {
      ctx.font = "16px Arial";
      ctx.fillStyle = "#ffa500";
      ctx.fillText("Score:" + score, 8, 20);
    }
    
    function drawLives() {
      ctx.font = "16px Arial";
      ctx.fillStyle = "#ffa500";
      ctx.fillText("Lives:" + lives, canvas.width - 65, 20);
    }
    
    function drawBall() {
      ctx.beginPath();
      ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
      ctx.fillStyle = "#0095DD";
      ctx.fill();
      ctx.closePath();
    }
    
    function drawPaddle() {
      ctx.beginPath();
      ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
      ctx.fillStyle = "#faebd7";
      ctx.fill();
      ctx.closePath();
    }
    
    function drawBricks() {
      for(var c = 0; c < brickColumnCount; c++) {
        for(var r = 0; r < brickRowCount; r++) {
    
          if(bricks[c][r].status == 1) {
            var brickX = (c * (brickWidth + brickPadding)) + brickOffsetLeft;
            var brickY = (r * (brickHeight + brickPadding)) + brickOffsetTop;
            bricks[c][r].x = brickX;
            bricks[c][r].y = brickY;
    
            ctx.beginPath();
            ctx.rect(brickX, brickY, brickWidth, brickHeight);
            ctx.fillStyle = "#ffd700";
            ctx.fill();
            ctx.closePath();
          }
        }
      }
    
    }
    
    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      drawBall();
      drawBricks();
      drawPaddle();
      drawScore();
      drawLives();
      collisionDetection();
    
      if(x + dx > canvas.width - ballRadius | x + dx < ballRadius) {
        dx = -dx;
      }
    
      if(y + dy < ballRadius) {
        dy = -dy;
      } else if(y + dy > canvas.height - ballRadius) {
    
        if(x > paddleX && x < paddleX + paddleWidth) {
          dy = -dy*1.1;
        }
        else {
          lives--;
    
          if(!lives) {
            alert("GAME OVER");
            document.location.reload();
          }
          else {
            x = canvas.width / 2;
            y = canvas.height - 30;
            dx = 2;
            dy = -2;
            // dx = 5;
            // dy = -5;
            paddleX = (canvas.width - paddleWidth) / 2;
          }
        }
      }
    
      if(rightPressed && paddleX < canvas.width - paddleWidth) {
        paddleX += 7;
      }
      else if(leftPressed && paddleX > 0) {
        paddleX -= 7;
      }
    
      x += dx;
      y += dy;
    
      requestAnimationFrame(draw);
    }
    
    document.addEventListener("keydown", keyDownHandler, false);
    document.addEventListener("keyup", keyUpHandler, false);
    document.addEventListener("mousemove", mouseMoveHandler, false);
    
    function keyDownHandler(e) {
      if(e.key == "Right" || e.key == "ArrowRight") {
        rightPressed = true;
      }
      else if(e.key == "Left" || e.key == "ArrowLeft") {
        leftPressed = true;
      }
    }
    
    function keyUpHandler(e) {
      if(e.key == "Right" || e.key == "ArrowRight") {
        rightPressed = false;
      }
      else if(e.key == "Left" || e.key == "ArrowLeft") {
        leftPressed = false;
      }
    }
    
    function mouseMoveHandler(e) {
      var relativeX = e.clientX - canvas.offsetLeft;
      if(relativeX > 0 && relativeX < canvas.width) {
        paddleX = relativeX - paddleWidth / 2;
      }
    
    }
    
    draw();
    

 </script>

</body>

</html>

いかがでしたか?
さあ、もうすぐハッカタスの締切だ!!僕ももう行かなくちゃッ!!
NEMTUS Hackathon Hack+2022でのプログラミング入門チャレンジは、ここまでです🐶✨
最後までチャレンジしてくださった皆様!!ありがとうございました!!!!

高のSymbol Lifeが皆様に訪れ続けますように。

入会のご案内
NPO法人 NEM技術普及推進会 NEMTUSでは、ともにNEM普及・発展のために活動する仲間を随時募集しています。また、皆様からの賛助や寄付によって、力強く活動を継続していくことができます。NEMTUSの活動にご賛同いただける皆様のご入会
タイトルとURLをコピーしました