---
# System prepended metadata

title: '**ゼミナールB**'

---

# **ゼミナールB**
### **今回の目標**
 ブロック崩しゲームの難易度を上げる

### ブロック崩し
・ブロックの数を増やす
・ボールの速度が速くなる
・パドルの幅が小さくなる
以上の3つに取り組むことで、難易度を上げる

### 方法
・ブロックの数は、ブロックのサイズを小さくし、行列の数を増やす
　ブロックのサイズに合わせて、ボールのサイズも小さくする

・ボールの速度は、スコアに応じて少しずつ早くなるようにする
　ミスをしたら元の速度に戻す
 
・パドルの幅は、スコア20点ごとに小さくする
　サイズに応じて青→緑→黄色と色を変更する

### プログラム
```
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>brock</title>
</head>
<body>
  <canvas id = "myCanvas" width="500" height="320"></canvas>
  <p>
    <button onclick="connect()">接続する</button>
    <button id="startButton" onclick="gameStart();">Start</button>
    <button onclick="disconnect()">切断する</button>
  </p>
<script>


const UUID_BUTTON_SERVICE = 'e95d9882-251d-470a-a062-fa1922dfa9a8'
const UUID_BUTTON_SERVICE_CHARACTERISTIC_A   = 'e95dda90-251d-470a-a062-fa1922dfa9a8'
const UUID_BUTTON_SERVICE_CHARACTERISTIC_B = 'e95dda91-251d-470a-a062-fa1922dfa9a8'
let server = null;
let device = null;
let service_button = null;
let char_buttonA = null;
let char_buttonB = null;
let buttonA, buttonB; 
let animeID;

let canvas = document.getElementById("myCanvas");
let ctx = canvas.getContext("2d");
let ballRadius = 5;
let x = canvas.width/2;
let y = canvas.height-30;
let dx = 3;
let dy = -3;
let paddleHeight = 10;
let paddleWidth = 75;
let paddleX = (canvas.width-paddleWidth)/2;
let brickRowCount = 10;
let brickColumnCount = 6;
let brickWidth = 35;
let brickHeight = 10;
let brickPadding = 10;
let brickOffsetTop = 30;
let brickOffsetLeft = 30;
let score = 0;
let lives = 3;

let bricks = [];
for(let c=0; c<brickColumnCount; c++) {
  bricks[c] = [];
  for(let r=0; r<brickRowCount; r++) {
    bricks[c][r] = { x: 0, y: 0, status: 1 };
  }
}

async function connect() {
  device = await navigator.bluetooth.requestDevice({
    filters: [
      {services: [UUID_BUTTON_SERVICE]},
      { namePrefix: "BBC micro:bit" }
    ]}
  );
  server = await device.gatt.connect();
  service_button = await server.getPrimaryService(UUID_BUTTON_SERVICE);
  char_buttonA = await service_button.getCharacteristic(UUID_BUTTON_SERVICE_CHARACTERISTIC_A);
  char_buttonB = await service_button.getCharacteristic(UUID_BUTTON_SERVICE_CHARACTERISTIC_B);
  await char_buttonA.startNotifications();
  await char_buttonB.startNotifications();
  alert("接続が完了しました");
  startButton.disabled = false;
}

function disconnect() {
  cancelAnimationFrame(animeID);
  startButton.disabled = true;
  if (!device || !device.gatt.connected){
    return;
  }
  device.gatt.disconnect();
  alert("切断しました");
}

function collisionDetection() {
  for(let c=0; c<brickColumnCount; c++) {
    for(let r=0; r<brickRowCount; r++) {
      let 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, CONGRATS!");
            document.location.reload();
          }
          if(score % 5 == 0) {
            if(dx > 0){
              dx = dx + 0.5;
            }else{
              dx = dx - 0.5;
            }
            if(dx > 0){
              dy = dy + 0.5;
            }else{
              dy = dy - 0.5;
            }
          }
          if(score % 20 == 0) {
            paddleWidth -= 10;
          }
        }
      }
    }
  }
}

function drawBack(canvas, context) {
  context.beginPath();
  context.rect(0,0,canvas.width, canvas.height);
  context.fillStyle = "black";
  context.fill();
}

function drawBall() {
  ctx.beginPath();
  ctx.arc(x, y, ballRadius, 0, Math.PI*2);
  ctx.fillStyle = "white";
  ctx.fill();
  ctx.closePath();
}
function drawPaddle() {
  ctx.beginPath();
  ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight);
  ctx.fillStyle = "blue";
  if(score >= 20) {
    ctx.fillStyle = "green";
  }
  if(score >= 40) {
    ctx.fillStyle = "yellow";
  }
  ctx.fill();
  ctx.closePath();
}
function drawBricks() {
  for(let c=0; c<brickColumnCount; c++) {
    for(let r=0; r<brickRowCount; r++) {
      if(bricks[c][r].status == 1) {
        let brickX = (r*(brickWidth+brickPadding))+brickOffsetLeft;
        let brickY = (c*(brickHeight+brickPadding))+brickOffsetTop;
        bricks[c][r].x = brickX;
        bricks[c][r].y = brickY;
        ctx.beginPath();
        ctx.rect(brickX, brickY, brickWidth, brickHeight);
        ctx.fillStyle = "red";
        ctx.fill();
        ctx.closePath();
      }
    }
  }
}
function drawScore() {
  ctx.font = "16px Arial";
  ctx.fillStyle = "white";
  ctx.fillText("Score: "+score, 8, 20);
}
function drawLives() {
  ctx.font = "16px Arial";
  ctx.fillStyle = "white";
  ctx.fillText("Lives: "+lives, canvas.width-65, 20);
}


function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);  
  drawBack(canvas, ctx);
  drawBricks();
  drawBall();
  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();
        char_buttonA.removeEventListener('characteristicvaluechanged', ButtonAState);
        char_buttonB.removeEventListener('characteristicvaluechanged', ButtonBState);
        cancelAnimationFrame(animeID);
      }else {
        x = canvas.width/2;
        y = canvas.height-30;
        dx = 3;
        dy = -3;
        paddleX = (canvas.width-paddleWidth)/2;
      }
    }
  }

  if(buttonB == 1 && paddleX < canvas.width-paddleWidth) {
    paddleX += 9;
  }
  else if(buttonA == 1 && paddleX > 0) {
    paddleX -= 9;
  }

  x += dx;
  y += dy;
  animeID = requestAnimationFrame(draw);
}

async function gameStart() {
  x = canvas.width/2;
  y = canvas.height-30;
  dx = 3;
  dy = -3;
  buttonA = 0;
  buttonB = 0;

  char_buttonA.addEventListener('characteristicvaluechanged', ButtonAState);
  char_buttonB.addEventListener('characteristicvaluechanged', ButtonBState);


  start = undefined;
  if (animeID != undefined) {
    cancelAnimationFrame(animeID);
  }

  animeID = requestAnimationFrame(draw);
}


function ButtonAState(event) {
  buttonA = event.target.value.getUint8(0);
}
function ButtonBState(event) {
  buttonB = event.target.value.getUint8(0);
}

</script>
</body>
</html>
```
### 結果
目標の３つを達成することで、難易度が上がったことが実感できた。
ボールの増加などの複雑な処理にも挑戦してみたい。