打砖块-1

#打砖块-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>元素
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 () {
//update x y
if (leftPressed){
x -= speed
}
else if (rightPressed){
x += speed
}
//draw
ctx.clearRect(0,0,400,300)
ctx.drawImage(img,x,y)
},1000/30)
</script>
</body>
</html>

然后对以上代码进行优化抽象

  1. 定义一个入口_main(),将所有代码放入

  2. 将代码拆成几个函数,

    • paddle作为一个独立的个体,它的所有属性方法应该放到一起.

    • 创建 guagame, 控制所有注册点击事件和setInterval函数

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(){
//update
g.update()
//clear

//draw
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]) {
// 如果按键被按下, 调用注册的 action
g.actions[key]()
}
}

##myWay部分

完成了基本环节的搭建,对象只做了挡板

思考:1. 用if语句根据条件执行方法的,可以考虑改用actions[key]()映射

1
actions[action] && actions[action](event)

本篇中使用了actions: {}, keydowns: {},两个对象来完成功能,主要原因是在于回调方法是在setInterval中调用的,而回调方法是否调用的判断和按键有关,所以需要两个对象完成