SOURCE

console 命令行工具 X clear

                    
>
console
// 画布
var canvas = document.getElementById("canvas")
var context = canvas.getContext("2d")

//分数
var userScore = 0
var systemScore = 0
var gameIsOver = false

// 圆的变量
let radius = 5 // 让球小一点,5个像素的半径
var ballPos = {x:canvas.width/2, y:canvas.height/2}
var speedX = 2 //值越小,动画越平滑
var speedY = 1

// 右侧挡板变量
var panelYOffset = 20 // 上右移动的范围
var panelYSpeed = -1 //挡板移动速度
var panelHeight = 50
// 左侧挡板y坐标
var leftPanelY = (canvas.height-panelHeight)/2

// 创建放射线渐变对象
var direction = "no-repeat"
// 有可能会出现木质没有显示的问题,可能是图片未加载完成
var img=document.getElementById("mood")
var pat=context.createPattern(img,direction)

// 音乐按钮状态
var musicButtonStateIsOn = false 

// 渲染
function render(){
  // 清屏
  context.clearRect(0,0,canvas.width,canvas.height)
  
  // 绘制不透明背景
  context.fillStyle="black";
  context.fillRect(0,0,canvas.width,canvas.height)

  // 添加阴影
  context.shadowBlur=1
  context.shadowOffsetY=2
  context.shadowOffsetX=-2
  context.shadowColor="gray"
  
  // 绘制右挡板
  drawPanel(canvas.width-10,(canvas.height-panelHeight)/2-panelYOffset)
  // 绘制左挡板
  drawPanel(0,leftPanelY)
  
  // 绘制圆
  context.fillStyle="white"
  context.beginPath()
  context.arc(ballPos.x, ballPos.y, radius, 0, 2*Math.PI)
  context.fill()
  
  // 绘制分数
  drawText(20,30, "用户 "+userScore)
  var txt = "系统 " + systemScore
  drawText(canvas.width-20-context.measureText(txt).width,30, txt)
  
  // 绘制按钮
  drawMusicButton()
}

// 绘制挡板函数
function drawPanel(x, y){
  context.fillStyle=pat
  context.fillRect(x,y,10,panelHeight)
}

// 监听鼠标移动事件
canvas.addEventListener("mousemove", function (e) {
  var y = e.clientY -canvas.getBoundingClientRect().top-panelHeight/2
  if (y > 0 && y < (canvas.height-panelHeight)) {
    leftPanelY = y
  }
})

// 四周碰撞检查
function hitTest(){
  if (ballPos.x > canvas.width-radius){// 触达右边界
    speedX = -speedX
  }else if (ballPos.x < radius){// 触达左边界
    speedX = -speedX
  }
  if (ballPos.y > canvas.height-radius){// 触达右边界
    speedY = -speedY
  }else if (ballPos.y < radius){// 触达左边界
    speedY = -speedY
  }
}

// 挡板碰撞检测
function hitPanelTest(){
  if (ballPos.x > canvas.width-radius-10){// 碰撞右挡板
    var rightPanelY = (canvas.height-panelHeight)/2-panelYOffset
    if (ballPos.y > rightPanelY && ballPos.y < (rightPanelY+panelHeight)){
      speedX = -speedX
      systemScore++
      playHitAudio()// 播放音效
      checkScore()
    }
  }else if (ballPos.x < radius+10){// 触达左边界
    if (ballPos.y > leftPanelY && ballPos.y < (leftPanelY+panelHeight)){
      speedX = -speedX
      userScore++
      playHitAudio()// 播放音效
      checkScore()
    }
  }
}

// 检查分数与游戏状态是否结束
function checkScore(){
  if (systemScore >=3 || userScore >= 3){
    gameIsOver = true // 游戏结束
  }
}

// 绘制文本
function drawText(x,y,text){
  context.fillText(text,x,y)
}

// 游戏结束时监听单击事件的函数句柄
function onGameOver(e){
  // 移除监听
  canvas.removeEventListener("click", onGameOver)
  playHitAudio()// 播放音效
  userScore = 0
  systemScore = 0
  gameIsOver = false 
  run()
  playBackgroundSound()
}

// 播放音效
function playHitAudio(){
  var audio = document.getElementById("hit-sound")
  audio.play()
}

// 播放背景音乐
function playBackgroundSound(){
  var audio = document.getElementById("bg-sound")
  audio.play()
}

// 停止背景音乐
function stopBackgroundSound(){
  var audio = document.getElementById("bg-sound")
  audio.pause()
}

// 绘制音乐按钮
function drawMusicButton(){
  var img= new Image()
  if (musicButtonStateIsOn){
    img.src = "http://xiuxing-1252822131.cossh.myqcloud.com/book/sound-on.jpg"
  }else{
    img.src = "http://xiuxing-1252822131.cossh.myqcloud.com/book/sound-off.jpg"
  }
  context.drawImage(img,canvas.width-20,0);
}

// 让挡板起来
function run(){
  // 挡板
  panelYOffset += panelYSpeed
  if (panelYOffset < -20 || panelYOffset > 20){
    panelYSpeed = -panelYSpeed
  }
  // 球的运行
  ballPos.x += speedX
  ballPos.y += speedY
  
  hitPanelTest()//挡板检测,放在前面
  hitTest() // 与边界碰撞检测
  
  render()
  
  // 循环执行
  if (!gameIsOver){
    requestAnimationFrame(run)
  }else{
    var txt = "游戏结束"
  	drawText(canvas.width/2-context.measureText(txt).width/2,canvas.height/2, txt)
    txt = "单击屏幕重新开始"
    drawText(canvas.width/2-context.measureText(txt).width/2,canvas.height/2+20, txt)
    // 监听单击事件
    canvas.addEventListener("click", onGameOver)
    stopBackgroundSound()//停止音乐
  }
}
run()// 开始
playBackgroundSound()
<br/><br/>
<canvas id="canvas" style="width:100%">
	您的浏览器不支持Html5 Canvas标签。
</canvas>
<img id="mood" style="width:100px;" src="http://pic35.photophoto.cn/20150525/0046043399250753_b.jpg"/>
<!--单击音效-->
<audio id="hit-sound"> 
 <source src='https://opengameart.org/sites/default/files/audio_preview/click.wav.ogg' tpe='audio/ogg'>
  <source src='https://opengameart.org/sites/default/files/audio_preview/click.wav.mp3' tpe='audio/mp3'>
</audio>
<!--背景音乐-->
<audio id="bg-sound"> 
 <source src='https://opengameart.org/sites/default/files/01%20track%201.ogg' tpe='audio/ogg'>
  <source src='https://opengameart.org/sites/default/files/audio_preview/01%20track%201.ogg.mp3' tpe='audio/mp3'>
</audio>
<img src="http://xiuxing-1252822131.cossh.myqcloud.com/book/sound-on.jpg"/>
<img src="http://xiuxing-1252822131.cossh.myqcloud.com/book/sound-off.jpg"/>