mustachio-game 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/package.json +2 -2
  2. package/.github/workflows/pr.yaml +0 -21
  3. package/.github/workflows/push.yaml +0 -26
  4. package/eslint.config.ts +0 -17
  5. package/index.html +0 -22
  6. package/src/assets/Mustachio.webp +0 -0
  7. package/src/assets/Mustachio_FacingLeft.webp +0 -0
  8. package/src/assets/Mustachio_FacingLeft_Fire.webp +0 -0
  9. package/src/assets/Mustachio_FacingRight.webp +0 -0
  10. package/src/assets/Mustachio_FacingRight_Fire.webp +0 -0
  11. package/src/assets/Mustachio_Fire.webp +0 -0
  12. package/src/assets/brick.webp +0 -0
  13. package/src/assets/cannonDown.webp +0 -0
  14. package/src/assets/cannonLeft.webp +0 -0
  15. package/src/assets/cannonRight.webp +0 -0
  16. package/src/assets/cannonUp.webp +0 -0
  17. package/src/assets/fallingFloor.webp +0 -0
  18. package/src/assets/homestead.webp +0 -0
  19. package/src/assets/homesteadClosed.webp +0 -0
  20. package/src/assets/itemBlock.webp +0 -0
  21. package/src/assets/obstacleBrick.webp +0 -0
  22. package/src/assets/punchedBlock.webp +0 -0
  23. package/src/assets/stacheSeed1.webp +0 -0
  24. package/src/assets/stacheSeed2.webp +0 -0
  25. package/src/assets/stacheSeedReversed1.webp +0 -0
  26. package/src/assets/stacheSeedReversed2.webp +0 -0
  27. package/src/assets/stacheShotDown.webp +0 -0
  28. package/src/assets/stacheShotLeft.webp +0 -0
  29. package/src/assets/stacheShotRight.webp +0 -0
  30. package/src/assets/stacheShotUp.webp +0 -0
  31. package/src/assets/stacheSlinger1.webp +0 -0
  32. package/src/assets/stacheSlinger2.webp +0 -0
  33. package/src/assets/stacheStalker.webp +0 -0
  34. package/src/assets/stacheStalkerReversed.webp +0 -0
  35. package/src/assets/stacheStreaker1.webp +0 -0
  36. package/src/assets/stacheStreaker2.webp +0 -0
  37. package/src/classes/game-objects/bg-objects/background.ts +0 -18
  38. package/src/classes/game-objects/bg-objects/cloud.ts +0 -37
  39. package/src/classes/game-objects/mustachio.ts +0 -482
  40. package/src/classes/game-objects/point-objects/enemies/enemy.ts +0 -64
  41. package/src/classes/game-objects/point-objects/enemies/stache-seed.ts +0 -124
  42. package/src/classes/game-objects/point-objects/enemies/stache-shot.ts +0 -68
  43. package/src/classes/game-objects/point-objects/enemies/stache-slinger.ts +0 -63
  44. package/src/classes/game-objects/point-objects/enemies/stache-stalker.ts +0 -41
  45. package/src/classes/game-objects/point-objects/enemies/stache-streaker.ts +0 -78
  46. package/src/classes/game-objects/point-objects/items/coin.ts +0 -72
  47. package/src/classes/game-objects/point-objects/items/fire-stache.ts +0 -48
  48. package/src/classes/game-objects/point-objects/items/item.ts +0 -27
  49. package/src/classes/game-objects/point-objects/items/stacheroom.ts +0 -48
  50. package/src/classes/game-objects/point-objects/point-item.ts +0 -10
  51. package/src/classes/game-objects/projectiles/brick-debris.ts +0 -44
  52. package/src/classes/game-objects/projectiles/enemy-projectiles/enemy-projectile.ts +0 -3
  53. package/src/classes/game-objects/projectiles/enemy-projectiles/fire-ball.ts +0 -87
  54. package/src/classes/game-objects/projectiles/enemy-projectiles/fire-bar.ts +0 -65
  55. package/src/classes/game-objects/projectiles/enemy-projectiles/fire-cross.ts +0 -67
  56. package/src/classes/game-objects/projectiles/enemy-projectiles/laser.ts +0 -41
  57. package/src/classes/game-objects/projectiles/projectile.ts +0 -3
  58. package/src/classes/game-objects/projectiles/stache-ball.ts +0 -57
  59. package/src/classes/game-objects/set-pieces/flag.ts +0 -34
  60. package/src/classes/game-objects/set-pieces/obstacles/blocks/block.ts +0 -17
  61. package/src/classes/game-objects/set-pieces/obstacles/blocks/cave-wall.ts +0 -21
  62. package/src/classes/game-objects/set-pieces/obstacles/blocks/falling-floor.ts +0 -65
  63. package/src/classes/game-objects/set-pieces/obstacles/blocks/fire-bar-block.ts +0 -31
  64. package/src/classes/game-objects/set-pieces/obstacles/blocks/fire-cross-block.ts +0 -28
  65. package/src/classes/game-objects/set-pieces/obstacles/blocks/punchable-blockS/brick.ts +0 -44
  66. package/src/classes/game-objects/set-pieces/obstacles/blocks/punchable-blockS/item-block.ts +0 -82
  67. package/src/classes/game-objects/set-pieces/obstacles/blocks/punchable-blockS/punchable-block.ts +0 -6
  68. package/src/classes/game-objects/set-pieces/obstacles/blocks/stache-cannon.ts +0 -54
  69. package/src/classes/game-objects/set-pieces/obstacles/blocks/wall.ts +0 -22
  70. package/src/classes/game-objects/set-pieces/obstacles/floor.ts +0 -27
  71. package/src/classes/game-objects/set-pieces/obstacles/obstacle-types.ts +0 -14
  72. package/src/classes/game-objects/set-pieces/obstacles/obstacle.ts +0 -3
  73. package/src/classes/game-objects/set-pieces/obstacles/pipe.ts +0 -35
  74. package/src/classes/game-objects/set-pieces/obstacles/warp-pipe.ts +0 -17
  75. package/src/classes/game-objects/set-pieces/set-piece.ts +0 -3
  76. package/src/classes/game-objects/ui-objects/score-display.ts +0 -10
  77. package/src/classes/game-objects/ui-objects/timer-display.ts +0 -15
  78. package/src/classes/game-objects/ui-objects/ui-object.ts +0 -16
  79. package/src/classes/game-objects/ui-objects/win-display.ts +0 -25
  80. package/src/dev.ts +0 -5
  81. package/src/index.ts +0 -3
  82. package/src/levels/caves/cave-one.ts +0 -90
  83. package/src/levels/level-helpers.ts +0 -101
  84. package/src/levels/level-one.ts +0 -379
  85. package/src/levels/test-levels/blocks-and-items.ts +0 -77
  86. package/src/levels/test-levels/cannon-and-cross.ts +0 -75
  87. package/src/levels/test-levels/caves-and-enemies.ts +0 -73
  88. package/src/levels/test-levels/win-game.ts +0 -24
  89. package/src/main.ts +0 -6
  90. package/src/mustachi-game-context.ts +0 -35
  91. package/src/shared/app-code.ts +0 -106
  92. package/src/shared/constants.ts +0 -1
  93. package/src/shared/game-context.ts +0 -547
  94. package/src/shared/game-objects/game-object.ts +0 -28
  95. package/src/shared/game-objects/moving-game-object.ts +0 -46
  96. package/src/shared/game-objects/rotating-game-object.ts +0 -58
  97. package/src/shared/game-objects/updating-game-object.ts +0 -7
  98. package/src/shared/player.ts +0 -73
  99. package/src/shared/types.ts +0 -21
  100. package/tsconfig.json +0 -26
  101. package/vite.config.ts +0 -13
@@ -1,68 +0,0 @@
1
- import { direction, type collision } from "../../../../shared/types";
2
- import type { GameContext } from "../../../../shared/game-context";
3
- import type { StacheCannon } from "../../set-pieces/obstacles/blocks/stache-cannon";
4
- import { BLOCK_SIZE } from "../../../../shared/constants";
5
- import { Enemy } from "./enemy";
6
- import { outOfBounds } from "../../../../shared/app-code";
7
- import stacheShotLeft from "../../../../assets/stacheShotLeft.webp";
8
- import stacheShotRight from "../../../../assets/stacheShotRight.webp";
9
- import stacheShotUp from "../../../../assets/stacheShotUp.webp";
10
- import stacheShotDown from "../../../../assets/stacheShotDown.webp";
11
-
12
- export class StacheShot extends Enemy {
13
- readonly pointValue: number = 250;
14
- private readonly shotSpeed = 3;
15
-
16
- constructor(gameContext: GameContext, parent: StacheCannon, dir: number) {
17
- const width = BLOCK_SIZE * 0.75;
18
- const height = BLOCK_SIZE * 0.75;
19
- const x = parent.rect.x + parent.rect.width / 2 - width / 2;
20
- const y = parent.rect.y + parent.rect.height / 2 - height / 2;
21
- super(
22
- gameContext,
23
- {
24
- x,
25
- y,
26
- width,
27
- height,
28
- },
29
- false,
30
- );
31
-
32
- if (dir === direction.LEFT) {
33
- this.image.src = stacheShotLeft;
34
- this.speedX = -this.shotSpeed;
35
- } else if (dir === direction.RIGHT) {
36
- this.image.src = stacheShotRight;
37
- this.speedX = this.shotSpeed;
38
- } else if (dir === direction.UP) {
39
- this.image.src = stacheShotUp;
40
- this.speedY = -this.shotSpeed;
41
- } else if (dir === direction.DOWN) {
42
- this.image.src = stacheShotDown;
43
- this.speedY = this.shotSpeed;
44
- } else {
45
- throw new Error("Invalid direction for StacheShot");
46
- }
47
- }
48
-
49
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
50
- update(_: collision[]) {
51
- this.rect.x += this.speedX;
52
- this.rect.y += this.speedY;
53
-
54
- if (outOfBounds(this, this.gameContext)) {
55
- this.gameContext.removeGameObject(this);
56
- }
57
- }
58
-
59
- draw(ctx: CanvasRenderingContext2D) {
60
- ctx.drawImage(
61
- this.image,
62
- this.rect.x + this.gameContext.xOffset,
63
- this.rect.y,
64
- this.rect.width,
65
- this.rect.height,
66
- );
67
- }
68
- }
@@ -1,63 +0,0 @@
1
- import type { collision } from "../../../../shared/types";
2
- import { Enemy } from "./enemy";
3
- import type { GameContext } from "../../../../shared/game-context";
4
- import { BLOCK_SIZE } from "../../../../shared/constants";
5
- import { FireBall } from "../../projectiles/enemy-projectiles/fire-ball";
6
- import stacheSlinger1 from "../../../../assets/stacheSlinger1.webp";
7
- import stacheSlinger2 from "../../../../assets/stacheSlinger2.webp";
8
-
9
- export class StacheSlinger extends Enemy {
10
- readonly pointValue: number = 1250;
11
- private readonly maxX: number;
12
- private readonly minX: number;
13
- private totalDistance: number = 0;
14
-
15
- constructor(gameContext: GameContext, x: number, y: number) {
16
- super(gameContext, {
17
- x,
18
- y,
19
- width: BLOCK_SIZE * 1.5,
20
- height: BLOCK_SIZE * 2,
21
- });
22
-
23
- this.maxX = x + BLOCK_SIZE * 4;
24
- this.minX = x - BLOCK_SIZE * 4;
25
-
26
- this.imageSources.push(stacheSlinger1, stacheSlinger2);
27
-
28
- this.image.src = this.imageSources[0];
29
- this.speedX = 1.5;
30
- gameContext.addGameObject(new FireBall(this.gameContext, this));
31
-
32
- this.shotTimer = setInterval(() => {
33
- gameContext.addGameObject(new FireBall(this.gameContext, this));
34
- }, 5000);
35
- }
36
-
37
- // This enemy doesn't collide with anything
38
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
39
- update(_: collision[]): void {
40
- if (!this.isDead) {
41
- this.rect.x += this.speedX;
42
- this.totalDistance += this.speedX;
43
-
44
- if (this.totalDistance >= this.maxX) {
45
- this.speedX = -Math.abs(this.speedX);
46
- this.image.src = this.imageSources[1];
47
- } else if (this.totalDistance <= this.minX) {
48
- this.speedX = Math.abs(this.speedX);
49
- this.image.src = this.imageSources[0];
50
- }
51
- }
52
- }
53
-
54
- draw(ctx: CanvasRenderingContext2D): void {
55
- ctx.drawImage(
56
- this.image,
57
- this.rect.x + this.gameContext.xOffset,
58
- this.rect.y,
59
- this.rect.width,
60
- this.rect.height,
61
- );
62
- }
63
- }
@@ -1,41 +0,0 @@
1
- import type { collision, rectangle } from "../../../../shared/types";
2
- import { Enemy } from "./enemy";
3
- import type { GameContext } from "../../../../shared/game-context";
4
- import { BLOCK_SIZE } from "../../../../shared/constants";
5
- import stacheStalker from "../../../../assets/stacheStalker.webp";
6
- import stacheStalkerReversed from "../../../../assets/stacheStalkerReversed.webp";
7
-
8
- export class StacheStalker extends Enemy {
9
- readonly pointValue: number = 100;
10
-
11
- constructor(gameContext: GameContext, x: number, y: number) {
12
- const rect: rectangle = {
13
- x,
14
- y,
15
- width: BLOCK_SIZE * 0.75,
16
- height: BLOCK_SIZE * 0.75,
17
- };
18
- super(gameContext, rect);
19
-
20
- this.imageSources.push(stacheStalker, stacheStalkerReversed);
21
-
22
- this.image.src = this.imageSources[0];
23
- this.speedX = 1;
24
- }
25
-
26
- draw(ctx: CanvasRenderingContext2D) {
27
- ctx.drawImage(
28
- this.image,
29
- this.rect.x + this.gameContext.xOffset,
30
- this.rect.y,
31
- this.rect.width,
32
- this.rect.height,
33
- );
34
- }
35
-
36
- update(collisions: collision[]): void {
37
- if (!this.isDead) {
38
- this.leftRightMovement(collisions);
39
- }
40
- }
41
- }
@@ -1,78 +0,0 @@
1
- import type { collision } from "../../../../shared/types";
2
- import { Enemy } from "./enemy";
3
- import type { GameContext } from "../../../../shared/game-context";
4
- import { BLOCK_SIZE } from "../../../../shared/constants";
5
- import { Laser } from "../../projectiles/enemy-projectiles/laser";
6
- import stacheStreaker1 from "../../../../assets/stacheStreaker1.webp";
7
- import stacheStreaker2 from "../../../../assets/stacheStreaker2.webp";
8
-
9
- export class StacheStreaker extends Enemy {
10
- readonly pointValue: number = 1250;
11
- private canMove: boolean = true;
12
- private totalDistance: number = 0;
13
- private readonly timeBetweenShots: number = 3500;
14
- private readonly shotTime: number = 5000;
15
-
16
- constructor(gameContext: GameContext, x: number, y: number) {
17
- super(
18
- gameContext,
19
- {
20
- x,
21
- y,
22
- width: BLOCK_SIZE * 2,
23
- height: BLOCK_SIZE * 1.5,
24
- },
25
- false,
26
- );
27
-
28
- this.imageSources.push(stacheStreaker1, stacheStreaker2);
29
-
30
- this.image.src = this.imageSources[0];
31
- this.speedX = 1;
32
- this.shotTimer = setTimeout(() => {
33
- this.fireLaser();
34
- }, this.timeBetweenShots);
35
- }
36
-
37
- // This enemy doesn't collide with anything
38
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
39
- update(_: collision[]): void {
40
- if (!this.isDead && this.canMove) {
41
- this.rect.x += this.speedX;
42
- this.totalDistance += Math.abs(this.speedX);
43
-
44
- if (this.totalDistance >= BLOCK_SIZE * 5) {
45
- this.speedX *= -1;
46
- this.totalDistance = 0;
47
- //this.setNextImage()
48
- }
49
- }
50
- }
51
-
52
- draw(ctx: CanvasRenderingContext2D): void {
53
- ctx.drawImage(
54
- this.image,
55
- this.rect.x + this.gameContext.xOffset,
56
- this.rect.y,
57
- this.rect.width,
58
- this.rect.height,
59
- );
60
- }
61
-
62
- private fireLaser(): void {
63
- this.gameContext.addGameObject(
64
- new Laser(this.gameContext, this, this.shotTime),
65
- );
66
- this.canMove = false;
67
- this.setNextImage();
68
-
69
- this.shotTimer = setTimeout(() => {
70
- this.canMove = true;
71
- this.setNextImage();
72
-
73
- this.shotTimer = setTimeout(() => {
74
- this.fireLaser();
75
- }, this.timeBetweenShots);
76
- }, this.shotTime);
77
- }
78
- }
@@ -1,72 +0,0 @@
1
- import type { GameContext } from "../../../../shared/game-context";
2
- import type { collision, rectangle } from "../../../../shared/types";
3
- import { Item } from "./item";
4
- import { BLOCK_SIZE } from "../../../../shared/constants";
5
-
6
- export class Coin extends Item {
7
- readonly pointValue: number = 100;
8
-
9
- constructor(
10
- gameContext: GameContext,
11
-
12
- x: number,
13
- y: number,
14
- fromItemBlock: boolean = false,
15
- ) {
16
- const rect: rectangle = {
17
- x,
18
- y,
19
- width: 15,
20
- height: 15,
21
- };
22
-
23
- if (!fromItemBlock) {
24
- rect.x += BLOCK_SIZE / 2 - rect.width / 2;
25
- rect.y += BLOCK_SIZE / 2 - rect.height / 2;
26
- }
27
-
28
- super(gameContext, rect, fromItemBlock);
29
-
30
- if (fromItemBlock) {
31
- this.speedY = -2.5;
32
- }
33
- }
34
-
35
- // The coin doesn't care about collisions
36
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
37
- update(_collisions: collision[]): void {
38
- // The animation only happens if the coin
39
- // is triggered from an item block
40
- if (!this.fromItemBlock) {
41
- return;
42
- }
43
-
44
- if (this.speedY < 0) {
45
- this.rect.y += this.speedY;
46
- this.speedY += 0.1;
47
- return;
48
- }
49
-
50
- // Once the animation is done, we remove the coin
51
- this.collect();
52
- }
53
-
54
- draw(ctx: CanvasRenderingContext2D) {
55
- ctx.fillStyle = "gold";
56
-
57
- ctx.beginPath();
58
- ctx.arc(
59
- this.rect.x + this.rect.width / 2 + this.gameContext.xOffset,
60
- this.rect.y + this.rect.height / 2,
61
- this.rect.width,
62
- 0,
63
- Math.PI * 2,
64
- );
65
-
66
- ctx.fill();
67
- ctx.closePath();
68
- ctx.strokeStyle = "black";
69
- ctx.lineWidth = 1;
70
- ctx.stroke();
71
- }
72
- }
@@ -1,48 +0,0 @@
1
- import type { GameContext } from "../../../../shared/game-context";
2
- import type { collision, rectangle } from "../../../../shared/types";
3
- import { Item } from "./item";
4
-
5
- export class FireStache extends Item {
6
- readonly pointValue: number = 1000;
7
- totalRaise: number = 20;
8
- speedX = 2;
9
-
10
- constructor(
11
- gameContext: GameContext,
12
-
13
- x: number,
14
- y: number,
15
- fromItemBlock: boolean = false,
16
- ) {
17
- const rect: rectangle = {
18
- x,
19
- y,
20
- width: 20,
21
- height: 20,
22
- };
23
-
24
- super(gameContext, rect, fromItemBlock);
25
- }
26
-
27
- draw(ctx: CanvasRenderingContext2D) {
28
- ctx.fillStyle = "red";
29
- ctx.fillRect(
30
- this.rect.x + this.gameContext.xOffset,
31
- this.rect.y,
32
- this.rect.width,
33
- this.rect.height,
34
- );
35
- }
36
-
37
- update(collisions: collision[]): void {
38
- // The animation only happens if the coin
39
- // is triggered from an item block
40
- if (this.fromItemBlock && this.totalRaise > 0) {
41
- this.rect.y += this.speedY;
42
- this.totalRaise += this.speedY;
43
- return;
44
- }
45
-
46
- this.leftRightMovement(collisions);
47
- }
48
- }
@@ -1,27 +0,0 @@
1
- import type { GameContext } from "../../../../shared/game-context";
2
- import type { rectangle } from "../../../../shared/types";
3
- import { PointObject } from "../point-item";
4
- import { BLOCK_SIZE } from "../../../../shared/constants";
5
-
6
- export abstract class Item extends PointObject {
7
- protected readonly fromItemBlock: boolean;
8
-
9
- constructor(
10
- gameContext: GameContext,
11
-
12
- rect: rectangle,
13
- fromItemBlock: boolean = false,
14
- ) {
15
- if (fromItemBlock) {
16
- rect.x -= rect.width / 2;
17
- rect.y += BLOCK_SIZE;
18
- }
19
-
20
- super(gameContext, rect);
21
-
22
- this.fromItemBlock = fromItemBlock;
23
- if (fromItemBlock) {
24
- this.speedY = -0.5;
25
- }
26
- }
27
- }
@@ -1,48 +0,0 @@
1
- import type { GameContext } from "../../../../shared/game-context";
2
- import type { collision, rectangle } from "../../../../shared/types";
3
- import { Item } from "./item";
4
-
5
- export class Stacheroom extends Item {
6
- readonly pointValue: number = 1000;
7
- totalRaise: number = 20;
8
- speedX = 2;
9
-
10
- constructor(
11
- gameContext: GameContext,
12
-
13
- x: number,
14
- y: number,
15
- fromItemBlock: boolean = false,
16
- ) {
17
- const rect: rectangle = {
18
- x,
19
- y,
20
- width: 20,
21
- height: 20,
22
- };
23
-
24
- super(gameContext, rect, fromItemBlock);
25
- }
26
-
27
- draw(ctx: CanvasRenderingContext2D) {
28
- ctx.fillStyle = "blue";
29
- ctx.fillRect(
30
- this.rect.x + this.gameContext.xOffset,
31
- this.rect.y,
32
- this.rect.width,
33
- this.rect.height,
34
- );
35
- }
36
-
37
- update(collisions: collision[]): void {
38
- // The animation only happens if the coin
39
- // is triggered from an item block
40
- if (this.fromItemBlock && this.totalRaise > 0) {
41
- this.rect.y += this.speedY;
42
- this.totalRaise += this.speedY;
43
- return;
44
- }
45
-
46
- this.leftRightMovement(collisions);
47
- }
48
- }
@@ -1,10 +0,0 @@
1
- import { MovingGameObject } from "../../../shared/game-objects/moving-game-object";
2
-
3
- export abstract class PointObject extends MovingGameObject {
4
- abstract pointValue: number;
5
-
6
- collect() {
7
- this.gameContext.addScore(this.pointValue);
8
- this.gameContext.removeGameObject(this);
9
- }
10
- }
@@ -1,44 +0,0 @@
1
- import type { collision } from "../../../shared/types";
2
- import type { Brick } from "../set-pieces/obstacles/blocks/punchable-blockS/brick";
3
- import type { GameContext } from "../../../shared/game-context";
4
- import { Projectile } from "./projectile";
5
-
6
- export class BrickDebris extends Projectile {
7
- readonly acceptsCollision = false;
8
-
9
- constructor(gameContext: GameContext, parent: Brick) {
10
- super(gameContext, {
11
- x: parent.rect.x + parent.rect.width / 2,
12
- y: parent.rect.y + parent.rect.height / 2,
13
- width: 8,
14
- height: 8,
15
- });
16
- }
17
-
18
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
19
- update(_: collision[]): void {
20
- this.rect.x += this.speedX;
21
- this.rect.y += this.speedY;
22
- this.speedY += this.gameContext.gravity;
23
-
24
- if (this.rect.y > this.gameContext.gameArea.height) {
25
- this.gameContext.removeGameObject(this);
26
- }
27
- }
28
-
29
- draw(ctx: CanvasRenderingContext2D): void {
30
- ctx.fillStyle = "brown";
31
-
32
- ctx.beginPath();
33
- ctx.arc(
34
- this.rect.x + this.rect.width / 2 + this.gameContext.xOffset,
35
- this.rect.y + this.rect.height / 2,
36
- this.rect.width,
37
- 0,
38
- Math.PI * 2,
39
- );
40
-
41
- ctx.fill();
42
- ctx.closePath();
43
- }
44
- }
@@ -1,3 +0,0 @@
1
- import { Projectile } from "../projectile";
2
-
3
- export abstract class EnemyProjectile extends Projectile {}
@@ -1,87 +0,0 @@
1
- import type { collision } from "../../../../shared/types";
2
- import { EnemyProjectile } from "./enemy-projectile";
3
- import type { GameContext } from "../../../../shared/game-context";
4
- import type { Enemy } from "../../point-objects/enemies/enemy";
5
- import { Player } from "../../../../shared/player";
6
-
7
- export class FireBall extends EnemyProjectile {
8
- private readonly target: Player;
9
- private readonly tracking: boolean = Math.random() < 0.25;
10
-
11
- constructor(gameContext: GameContext, parent: Enemy) {
12
- super(gameContext, {
13
- x: parent.rect.x + parent.rect.width / 2,
14
- y: parent.rect.y + parent.rect.height + 10,
15
- width: 8,
16
- height: 8,
17
- });
18
-
19
- setTimeout(() => {
20
- this.gameContext.removeGameObject(this);
21
- }, 5000);
22
-
23
- const player = gameContext.getPlayer();
24
- if (player) {
25
- this.target = player;
26
- this.setSpeed();
27
- } else {
28
- throw new Error("Player not found");
29
- }
30
- }
31
-
32
- update(collisions: collision[]): void {
33
- for (const collision of collisions) {
34
- if (collision.gameObject instanceof Player) {
35
- collision.gameObject.playerHit();
36
- return;
37
- }
38
-
39
- this.gameContext.removeGameObject(this);
40
- }
41
-
42
- if (this.rect.x < 0 || this.rect.x > this.gameContext.gameArea.width) {
43
- this.gameContext.removeGameObject(this);
44
- return;
45
- }
46
-
47
- if (this.rect.y < 0 || this.rect.y > this.gameContext.gameArea.height) {
48
- this.gameContext.removeGameObject(this);
49
- return;
50
- }
51
-
52
- if (this.tracking) {
53
- this.setSpeed();
54
- }
55
-
56
- this.rect.x += this.speedX;
57
- this.rect.y += this.speedY;
58
- }
59
-
60
- draw(ctx: CanvasRenderingContext2D): void {
61
- ctx.beginPath();
62
- ctx.lineWidth = 5;
63
- ctx.fillStyle = "red";
64
- ctx.arc(
65
- this.rect.x + this.gameContext.xOffset,
66
- this.rect.y,
67
- this.rect.height,
68
- 0,
69
- 2 * Math.PI,
70
- );
71
- ctx.fill();
72
- }
73
-
74
- private setSpeed() {
75
- const dx = this.target.rect.x - this.rect.x;
76
- const dy = this.target.rect.y - this.rect.y;
77
- const angle = Math.atan2(dy, dx);
78
-
79
- if (this.tracking) {
80
- this.speedX = Math.cos(angle) * 1.25;
81
- this.speedY = Math.sin(angle) * 1.25;
82
- } else {
83
- this.speedX = Math.cos(angle) * 2;
84
- this.speedY = Math.sin(angle) * 2;
85
- }
86
- }
87
- }
@@ -1,65 +0,0 @@
1
- import type { GameContext } from "../../../../shared/game-context";
2
- import type { collision, rectangle } from "../../../../shared/types";
3
- import type { FireBarBlock } from "../../set-pieces/obstacles/blocks/fire-bar-block";
4
- import { RotatingGameObject } from "../../../../shared/game-objects/rotating-game-object";
5
-
6
- export class FireBar extends RotatingGameObject {
7
- private readonly anchorBlock: FireBarBlock;
8
-
9
- constructor(
10
- gameContext: GameContext,
11
-
12
- x: number,
13
- y: number,
14
- anchorBlock: FireBarBlock,
15
- ) {
16
- const rect: rectangle = {
17
- x,
18
- y,
19
- width: 10,
20
- height: 250,
21
- };
22
-
23
- super(gameContext, rect);
24
- this.anchorBlock = anchorBlock;
25
- }
26
-
27
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
28
- update(_: collision[]): void {
29
- this.rotation += this.rotationSpeed;
30
- this.rotation %= Math.PI * 2;
31
-
32
- const anchorCenterX =
33
- this.anchorBlock.rect.x + this.anchorBlock.rect.width / 2;
34
- const anchorCenterY =
35
- this.anchorBlock.rect.y + this.anchorBlock.rect.height / 2;
36
-
37
- // Position the firebar so its BOTTOM CENTER is at the anchor center
38
- this.rect.x = anchorCenterX - this.rect.width / 2;
39
- this.rect.y = anchorCenterY - this.rect.height;
40
- }
41
-
42
- draw(ctx: CanvasRenderingContext2D): void {
43
- ctx.save();
44
-
45
- // Move the origin to the bottom-center of the firebar
46
- ctx.translate(
47
- this.rect.x + this.rect.width / 2 + this.gameContext.xOffset,
48
- this.rect.y + this.rect.height,
49
- );
50
-
51
- // Rotate around the bottom edge
52
- ctx.rotate(this.rotation);
53
-
54
- // Draw the bar with its bottom edge at the origin
55
- ctx.fillStyle = "red";
56
- ctx.fillRect(
57
- -this.rect.width / 2, // center horizontally
58
- -this.rect.height, // draw upward from pivot
59
- this.rect.width,
60
- this.rect.height,
61
- );
62
-
63
- ctx.restore();
64
- }
65
- }