@@ -11,8 +11,8 @@ quote}}
1111{{index "Banks, Ian", "project chapter", simulation}}
1212
1313Much of my initial fascination with computers, like that of many nerdy
14- kids, had a lot to do with computer ((game))s. I was drawn into the
15- tiny simulated ((world))s that I could manipulate and in which stories
14+ kids, had to do with computer ((game))s. I was drawn into the tiny
15+ simulated ((world))s that I could manipulate and in which stories
1616(sort of) unfolded—more, I suppose, because of the way I could project
1717my ((imagination)) into them than because of the possibilities they
1818actually offered.
@@ -154,7 +154,7 @@ restored to its starting position, and the player may try again.
154154
155155## Reading a level
156156
157- {{index "Level type "}}
157+ {{index "Level class "}}
158158
159159The following ((class)) stores a ((level)) object. Its argument should
160160be the string that defines the level.
@@ -231,6 +231,10 @@ class State {
231231 static start(level) {
232232 return new State(level, level.startActors, "playing");
233233 }
234+
235+ get player() {
236+ return this.actors.find(a => a.type == "player");
237+ }
234238}
235239```
236240
@@ -297,20 +301,21 @@ behavior is very different. Let's define these classes—without
297301
298302{{index simulation, "Player class"}}
299303
300- The player class has a property ` ySpeed ` that stores its current
301- vertical speed, which will help simulate momentum and gravity.
304+ The player class has a property ` speed ` that stores its current speed,
305+ to simulate momentum and gravity.
302306
303307``` {includeCode: true}
304308class Player {
305- constructor(pos, ySpeed ) {
309+ constructor(pos, speed ) {
306310 this.pos = pos;
307- this.ySpeed = ySpeed ;
311+ this.speed = speed ;
308312 }
309313
310314 get type() { return "player"; }
311315
312316 static create(pos) {
313- return new Player(pos.plus(new Vec(0, -0.5)), 0);
317+ return new Player(pos.plus(new Vec(0, -0.5)),
318+ new Vec(0, 0));
314319 }
315320}
316321
@@ -329,7 +334,7 @@ would create and return a new `Vec` object every time the property is
329334read, which would be wasteful. (Strings, being ((immutable)), don't
330335have to be recreated every time they are evaluated.)
331336
332- {{index "Lava type ", bouncing}}
337+ {{index "Lava class ", bouncing}}
333338
334339When constructing a ` Lava ` actor, we need to initialize the object
335340differently depending on the character it is based on. Dynamic lava
@@ -365,7 +370,7 @@ class Lava {
365370Lava.prototype.size = new Vec(1, 1);
366371```
367372
368- {{index "Coin type ", animation}}
373+ {{index "Coin class ", animation}}
369374
370375` Coin ` actors are relatively simple. They mostly just sit in their
371376place. But to liven up the game a little, they are given a "wobble", a
@@ -531,7 +536,7 @@ Actors are redrawn every time the display is updated with a given
531536state. The ` actorLayer ` property will be used to track the element
532537that holds the actors so that they can be easily removed and replaced.
533538
534- {{index scaling, "DOMDisplay type "}}
539+ {{index scaling, "DOMDisplay class "}}
535540
536541Our ((coordinates)) and sizes are tracked in units relative to the
537542((grid)) size, where a size or distance of 1 means 1 grid unit. When
@@ -713,7 +718,7 @@ DOMDisplay.prototype.scrollPlayerIntoView = function(state) {
713718 let left = this.dom.scrollLeft, right = left + width;
714719 let top = this.dom.scrollTop, bottom = top + height;
715720
716- let player = state.actors.find(a => a.type == " player") ;
721+ let player = state.player;
717722 let center = player.pos.plus(player.size.times(0.5))
718723 .times(scale);
719724
@@ -827,6 +832,8 @@ steps.
827832
828833{{index obstacle, "touches method", "collision detection"}}
829834
835+ {{id touches}}
836+
830837This method tells us whether a ((rectangle)) (specified by a position
831838and a size) touches a grid element of the given type.
832839
@@ -876,7 +883,7 @@ State.prototype.update = function(time, keys) {
876883
877884 if (newState.status != "playing") return newState;
878885
879- let player = actors.find(a => a.type == " player") ;
886+ let player = newState. player;
880887 if (this.level.touches(player.pos, player.size, "lava")) {
881888 return new State(this.level, actors, "lost");
882889 }
@@ -938,7 +945,7 @@ Coin.prototype.collide = function(state) {
938945
939946## Actor updates
940947
941- {{index actor, "Lava type ", lava}}
948+ {{index actor, "Lava class ", lava}}
942949
943950Actor objects' ` update ` methods take as arguments the time step, the
944951state object, and a ` keys ` object. The one for the ` Lava ` actor type
@@ -957,7 +964,7 @@ Lava.prototype.update = function(time, state) {
957964};
958965```
959966
960- {{index bouncing, multiplication, "Vector type ", "collision detection"}}
967+ {{index bouncing, multiplication, "Vect class ", "collision detection"}}
961968
962969It computes a new position by adding the product of the ((time)) step
963970and the current speed to its old position. If no obstacle blocks that
@@ -967,7 +974,7 @@ position, to which it jumps back when it hits something. Bouncing lava
967974inverts its speed by multiplying it by -1, so that it starts moving in
968975the opposite direction.
969976
970- {{index "Coin type ", coin, wave}}
977+ {{index "Coin class ", coin, wave}}
971978
972979Coins use their ` act ` method to wobble. They ignore collisions since
973980they are simply wobbling around inside of their own square.
@@ -990,7 +997,7 @@ argument to `Math.sin` to find the new position on the ((wave)). The
990997coin's current position is then computed from its base position and an
991998offset based on this wave.
992999
993- {{index "collision detection", "Player type "}}
1000+ {{index "collision detection", "Player class "}}
9941001
9951002That leaves the ((player)) itself. Player motion is handled separately
9961003per ((axis)) because hitting the floor should not prevent horizontal
@@ -1012,7 +1019,7 @@ Player.prototype.update = function(time, state, keys) {
10121019 pos = movedX;
10131020 }
10141021
1015- let ySpeed = this.ySpeed + time * gravity;
1022+ let ySpeed = this.speed.y + time * gravity;
10161023 let movedY = pos.plus(new Vec(0, ySpeed * time));
10171024 if (!state.level.touches(movedY, this.size, "wall")) {
10181025 pos = movedY;
@@ -1021,7 +1028,7 @@ Player.prototype.update = function(time, state, keys) {
10211028 } else {
10221029 ySpeed = 0;
10231030 }
1024- return new Player(pos, ySpeed);
1031+ return new Player(pos, new Vec(xSpeed, ySpeed) );
10251032};
10261033```
10271034
0 commit comments