summaryrefslogtreecommitdiff
path: root/centipede/js/game/objects/centipede.js
blob: 7e4c8f68336794ba189ec8000ffc0edfdec79105 (plain)
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
game.CentipedePiece = (spec) => {
  const object = game.Object(spec);
  object.poisonedTimer = 1000;
  const parentUpdate = object.update;
  object.turningState = {
    turning: false,
    turnDirectionY: 1,
    objectStateBeforeTurn: null,
  };
  object.turn = () => {
    object.turningState.objectStateBeforeTurn = {dx: object.dx, dy: object.dy, x: object.x, y: object.y};
    object.turningState.turning = true;
    if (object.y >= game.height - object.height) {
      object.turningState.turnDirectionY = -1;
    }
    if (object.y <= 0) {
      object.turningState.turnDirectionY = 1;
    }
  };
  object.update = (elapsedTime) => {
    if (object.poisoned) {
      object.turningState.turning = false;
    }
    else if ((object.x+object.width > game.width || object.x < 0) && !object.turningState.turning) {
      object.x = Math.min(Math.max(object.x, 0), game.width - object.width);
      object.turn();
    }
    if (object.turningState.turning) {
      object.dx = 0;
      object.dy = Math.abs(object.turningState.objectStateBeforeTurn.dx) * object.turningState.turnDirectionY;
      object.rot = object.dy > 0 ? -90 : 90;
      if (Math.abs(object.turningState.objectStateBeforeTurn.y - object.y) >= object.height) {
        object.y = object.turningState.objectStateBeforeTurn.y + object.height * object.turningState.turnDirectionY;
        object.dx = -object.turningState.objectStateBeforeTurn.dx;
        object.rot = object.dx > 0 ? 180 : 0;
        object.dy = 0;
        object.turningState.turning = false;
      }
    }
    parentUpdate(elapsedTime);
    object.y = Math.min(Math.max(object.y, 0), game.height - object.height);
  };
  object.onMushroomCollision = (mushroom) => {
    if (mushroom.poisoned && object.dy === 0) {
      object.poison();
      return;
    }
    if (!object.turningState.turning) {
      if (mushroom.x < object.x && object.dx > 0) {
        return;
      }
      object.turn();
    }
  }
  return object;
}

game.Centipede = (spec) => {
  const segments = [
    ...Array(spec.segments).fill(0).map((_, i) => game.CentipedePiece({...spec, x: spec.startX - spec.width*(i+1), y: spec.startY, sprite: game.sprites.centipedeBody})),
    game.CentipedePiece({...spec, x: spec.startX, y: spec.startY, sprite: game.sprites.centipedeHead}),
  ];

  const update = (elapsedTime) => {
    segments.map((segment) => segment.update(elapsedTime));
  }

  const draw = (elapsedTime) => {
    segments.map((segment) => segment.draw(elapsedTime));
  }
  
  const intersects = (object) => {
    return segments.filter((segment) => segment.intersects(object)).length;
  }

  const onBulletCollision = (bullet) => {
    if (bullet.alive) {
      const segment = segments.find((segment) => segment.intersects(bullet));
      const segmentIndex = segments.indexOf(segment);

      const {mushX, mushY} = game.Mushroom.toMushCoords(segment);
      game.explosions.push(game.Explosion({...game.Mushroom.toGameCoords({mushX, mushY}), width: segment.width, height: segment.height, sprite: game.sprites.explosionSmall}));
      if (!game.mushrooms.find((mushroom) => mushroom.mushX === mushX && mushroom.mushY === mushY)) {
        game.mushrooms.push(game.Mushroom({mushX, mushY, ...game.mushroomDims}));
      }
      game.score += segment.sprite === game.sprites.centipedeHead ? 20 : 5;
      game.sounds.enemy_hit.load();
      game.sounds.enemy_hit.play();
      segments.splice(segmentIndex, 1);
    }
    bullet.alive = false;
  }

  const onMushroomCollision = (mushroom) => {
    segments.find((segment) => segment.intersects(mushroom)).onMushroomCollision(mushroom);
  }

  const onPlayerCollision = (player) => {
    player.kill();
  }

  const alive = () => segments.length ? true : false; 

  return {update, draw, segments, intersects, onBulletCollision, onMushroomCollision, onPlayerCollision, alive};
}