#打砖块-1
##Tutorial部分
首先完成功能”一个通过’a’和’d’控制左右移动的图片”
代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style media="screen"> canvas{ border : 1px black solid; } </style> </head> <body> <canvas id="id-canvas" width="400" height="300"> </canvas> <script> var x= 100 var y =200 var speed = 5 var log = console.log.bind(console) var canvas = document.querySelector("#id-canvas") var ctx = canvas.getContext('2d') var leftPressed = false var rightPressed = false var img = new Image(); img.src = 'res/paddle.png'; img.onload = function(){ ctx.drawImage(img,x,y) } window.addEventListener("keydown",function (event) { log(event.key) switch (event.key){ case 'a': leftPressed = true break case 'd': rightPressed = true break default: break } }) window.addEventListener("keyup",function (event) { log(event.key) switch (event.key){ case 'a': leftPressed = false break case 'd': rightPressed = false break default: break } }) setInterval(function () { if (leftPressed){ x -= speed } else if (rightPressed){ x += speed } ctx.clearRect(0,0,400,300) ctx.drawImage(img,x,y) },1000/30) </script> </body> </html>
|
然后对以上代码进行优化抽象
定义一个入口_main(),将所有代码放入
将代码拆成几个函数,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| var getImageFromStr = function(path) { var img = new Image() img.src = path return img }
Paddle = function () { var o = { x: 100, y: 200, speed: 5, } o.image = getImageFromStr('res/paddle.png') o.moveLeft = function () { o.x -= o.speed } o.moveRight = function () { o.x += o.speed } return o; }
|
paddle 自己的逻辑应该让自己控制,所以
1 2 3 4 5 6
| if (leftPressed){ x -= speed } else if (rightPressed){ x += speed }
|
应该用对象自己的方法moveLeft和moveRight替换
将事件注册, setInterval 、update和 draw 整体封装成一个GuaGame,作为控制对象
控制对象里面需要有
1 2
| var canvas = document.querySelector("#id-canvas") var ctx = canvas.getContext('2d')
|
把setInterval放在GuaGame中
1 2 3 4 5 6 7 8
| setInterval(function(){
g.update()
g.draw },1000/30)
|
而update中的一些事件是通过注册来的,此时可以使用以下的巧妙方法完成
首先
1 2 3 4 5 6 7
| var g = { actions: {}, keydowns: {}, } g.registerAction = function(key, callback) { g.actions[key] = callback }
|
然后在setInterval中遍历并处理事件
1 2 3 4 5 6 7 8
| var actions = Object.keys(g.actions) for (var i = 0; i < actions.length; i++) { var key = actions[i] if(g.keydowns[key]) { g.actions[key]() } }
|
##myWay部分
完成了基本环节的搭建,对象只做了挡板
思考:1. 用if语句根据条件执行方法的,可以考虑改用actions[key]()
映射
1
| actions[action] && actions[action](event)
|
本篇中使用了actions: {}, keydowns: {},
两个对象来完成功能,主要原因是在于回调方法是在setInterval中调用的,而回调方法是否调用的判断和按键有关,所以需要两个对象完成