看专业码农直播写游戏

观看回放地址萧井陌的个人空间

Day One

播主代码:

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>game 1</title>
<style media="screen">
canvas {
border: 1px black solid;
}
</style>
</head>
<body>
<canvas id="id-canvas" width="400" height="300"></canvas>
<script>
var log = console.log.bind(console)
var imageFromPath = function(path) {
var img = new Image()
img.src = path
return img
}
var Paddle = function() {
var image = imageFromPath('paddle.png')
var o = {
image: image,
x: 100,
y: 250,
speed: 15,
}
var paddle = o
o.moveLeft = function() {
paddle.x -= paddle.speed
}
o.moveRight = function() {
paddle.x += paddle.speed
}
o.collide = function(ball) {
if (ball.y + ball.image.height > o.y) {
if (ball.x > o.x && ball.x < o.x + o.image.width) {
log('相撞')
return true
}
}
return false
}
return o
}
var Ball = function() {
var image = imageFromPath('ball.png')
var o = {
image: image,
x: 100,
y: 200,
speedX: 10,
speedY: 10,
fired: false,
}
o.fire = function() {
o.fired = true
}
o.move = function() {
if (o.fired) {
// log('move')
if (o.x < 0 || o.x > 400) {
o.speedX = -o.speedX
}
if (o.y < 0 || o.y > 300) {
o.speedY = -o.speedY
}
// move
o.x += o.speedX
o.y += o.speedY
}
}
return o
}
// 瓜
var GuaGame = function() {
var g = {
actions: {},
keydowns: {},
}
var canvas = document.querySelector('#id-canvas')
var context = canvas.getContext('2d')
g.canvas = canvas
g.context = context
// draw
g.drawImage = function(guaImage) {
g.context.drawImage(guaImage.image, guaImage.x, guaImage.y)
}
// events
window.addEventListener('keydown', function(event){
g.keydowns[event.key] = true
})
window.addEventListener('keyup', function(event){
g.keydowns[event.key] = false
})
//
g.registerAction = function(key, callback) {
g.actions[key] = callback
}
// timer
setInterval(function(){
// events
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]()
}
}
// update
g.update()
// clear
context.clearRect(0, 0, canvas.width, canvas.height)
// draw
g.draw()
}, 1000/30)
return g
}
var __main = function() {
var game = GuaGame()
var paddle = Paddle()
var ball = Ball()
game.registerAction('a', function(){
paddle.moveLeft()
})
game.registerAction('d', function(){
paddle.moveRight()
})
game.registerAction('f', function(){
ball.fire()
})
game.update = function() {
ball.move()
// 判断相撞
if (paddle.collide(ball)) {
// 这里应该调用一个 ball.反弹() 来实现
ball.speedY *= -1
}
}
game.draw = function() {
// draw
game.drawImage(paddle)
game.drawImage(ball)
}
}
__main()
</script>
</body>
</html>

临摹代码:

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>game 1</title>
<style type="text/css">
canvas{
border: 1px solid #eee;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
<script type="text/javascript">
// tool
var log = console.log.bind()
var imageFromPath = function (path) {
var img = new Image()
img.src = path
return img
}
var Paddle = function () {
var image = imageFromPath('https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2323943722,3696495464&fm=26&gp=0.jpg')
var o = {
img: image,
x: 200,
y: 150,
w: 120,
h: 60,
speed: 15,
}
o.moveLeft = function () {
o.x -= o.speed
}
o.moveRight = function () {
o.x += o.speed
}
o.collide = function (image) {
if (image.y + image.img.height > o.y && image.y < o.y + o.img.height) { // 纵轴 球偏移和自高 大于 栏偏移
// 横轴 球偏移 大于 栏偏移 并且 球偏移 小于 栏偏移和自宽
if (image.x > o.x && image.x < o.x + o.img.width) {
return true
}
}
return false
}
return o
}
var Ball = function () {
var image = imageFromPath('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504301500648&di=df06cc9f705e9355769e468413924d32&imgtype=jpg&src=http%3A%2F%2Fimg0.imgtn.bdimg.com%2Fit%2Fu%3D2346240780%2C32583404%26fm%3D214%26gp%3D0.jpg')
var o = {
img: image,
x: 200,
y: 150,
w: 60,
h: 30,
speedX: 10,
speedY: 10,
fired: false,
}
o.fire = function () {
o.fired = true
}
o.move = function () {
if (o.fired) {
if (o.x < 0 || o.x + o.w > 400) {
o.speedX *= -1
}
if (o.y < 0 || o.y + o.h > 300) {
o.speedY *= -1
}
o.x += o.speedX
o.y += o.speedY
}
}
return o
}
var Game = function () {
var g = {
actions: {},
keydowns: {},
}
// 画布生成
var canvas = document.querySelector("#canvas")
var ctx = canvas.getContext("2d")
g.canvas = canvas
g.ctx = ctx
// events
window.addEventListener("keydown",function (e) {
g.keydowns[e.key] = true
})
window.addEventListener("keyup",function (e) {
g.keydowns[e.key] = false
})
g.registerAction = function (key,cb) {
// 执行对应按键的对应方法
g.actions[key] = cb
}
// clean canvas
g.clean = function () {
g.ctx.clearRect(0,0,g.canvas.width,g.canvas.height)
}
// draw image
g.drawImage = function (image) {
g.ctx.drawImage(image.img,image.x,image.y,image.w,image.h)
}
// 图片变化,一秒钟变化30次
setInterval(function () {
// Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 (两者的主要区别是 一个 for-in 循环还会枚举其原型链上的属性)。
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]()
}
}
// update
g.update()
// clean
g.clean()
// draw
g.draw()
},1000/30)
return g
}
// 主入口
var __main = function () {
var paddle = Paddle()
var game = Game()
var ball = Ball()
game.update = function () {
ball.move()
// 碰撞
if (paddle.collide(ball)) {
ball.speedY *= -1
}
}
game.draw = function () {
game.drawImage(paddle)
game.drawImage(ball)
}
game.registerAction('a',function () {
paddle.moveLeft()
})
game.registerAction('d',function () {
paddle.moveRight()
})
game.registerAction('f',function () {
ball.fire()
})
}
__main()
</script>
</body>
</html>