Skip to content

Commit

Permalink
add particle background in the game scene (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
MounirAia authored Aug 24, 2024
1 parent b48e70c commit 6cd0794
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 5 deletions.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
<script type="module" src="src/main.ts" defer></script>
</head>
<body>
<h1 class="header">Web Shoot em UP</h1>
<h1 class="header">Web Shoot'em UP</h1>
<div class="game">
<div class="game-container">
<canvas id="canvas" width="1280" height="720" style="background-color: #cccccc"></canvas>
Expand Down
139 changes: 137 additions & 2 deletions src/Scenes/GameScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { IGameStatManager, UpdateGameStatManager } from '../GameStatManager';
import { IServiceImageLoader } from '../ImageLoader';
import { IServiceKeyboardManager } from '../Keyboard';
import { IScene, IServiceSceneManager } from '../SceneManager';
import { CANVA_SCALEX, CANVA_SCALEY, canvas } from '../ScreenConstant';
import { CANVA_SCALEX, CANVA_SCALEY, canvas, FRAME_RATE } from '../ScreenConstant';
import { ServiceLocator } from '../ServiceLocator';
import { DrawGeneratedSpritesManager, UpdateGeneratedSpritesManager } from '../Sprites/GeneratedSpriteManager';
import { DrawPlayer, IServicePlayer, UpdatePlayer } from '../Sprites/Player';
Expand Down Expand Up @@ -346,8 +346,140 @@ class InGameTimer {
}
}

class Particle {
private x: number;
private y: number;
private width: number;
private height: number;
private speed: number;

constructor(parameters: { x: number; y: number; width: number; height: number; speed: number }) {
const { x, y, width, height, speed } = parameters;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speed = speed;
}

public Update(dt: number): void {
this.x -= this.speed;
}

public Draw(ctx: CanvasRenderingContext2D): void {
ctx.rect(this.x, this.y, this.width, this.height);
}

public GetX(): number {
return this.x;
}

public GetY(): number {
return this.y;
}

public GetIfParticleIsOutsideViewScreen(): boolean {
// TODO: Need to cover the case if the particle is outside from the right side of the screen because it was ejected from the screen by the shockwave

if (this.x + this.width < 0 || this.y < 0 || this.y + this.height > canvas.height) {
return true;
}

return false;
}
}

class ParticleManager {
private particles: Particle[];
private particlesIndexToRemove: number[];
private particleWidth: number;
private particleHeight: number;
private particleSpeed: number;
private particleColor: string;

private timeRemainingBeforeNewParticles: number;
private baseTimeBeforeNewParticles: number;

constructor() {
this.particles = [];
this.particlesIndexToRemove = [];
this.particleWidth = 1 * CANVA_SCALEX;
this.particleHeight = 1 * CANVA_SCALEY;
this.particleSpeed = ServiceLocator.GetService<IServiceUtilManager>(
'UtilManager',
).GetSpeedItTakesToCoverHalfTheScreenWidth({
framesItTakes: 500,
});
this.particleColor = '#959595';

const dt = 1 / FRAME_RATE;
this.baseTimeBeforeNewParticles = (this.particleWidth * dt) / this.particleSpeed;
this.timeRemainingBeforeNewParticles = this.baseTimeBeforeNewParticles;

console.log(this.baseTimeBeforeNewParticles, this.particleSpeed, this.particleWidth);

const lines = Math.floor((320 * CANVA_SCALEX) / this.particleWidth);

for (let i = 0; i < lines; i++) {
this.generateParticlesOnALine({ x: i * this.particleWidth });
}
}

public Update(dt: number): void {
/* Update the particles and Clean the non visible particles*/
this.particles.forEach((particle) => {
particle.Update(dt);
if (particle.GetIfParticleIsOutsideViewScreen()) {
this.particlesIndexToRemove.push(this.particles.indexOf(particle));
}
});

this.particlesIndexToRemove.forEach((index) => {
this.particles.splice(index, 1);
});

this.particlesIndexToRemove = [];

/* Generate new particles */
this.timeRemainingBeforeNewParticles -= dt;
if (this.timeRemainingBeforeNewParticles <= 0) {
this.generateParticlesOnALine({ x: canvas.width });
this.timeRemainingBeforeNewParticles = this.baseTimeBeforeNewParticles;
}

console.log(this.particles.length);
}

public Draw(ctx: CanvasRenderingContext2D): void {
ctx.beginPath();
this.particles.forEach((particle) => {
particle.Draw(ctx);
});
ctx.fillStyle = this.particleColor;
ctx.fill();
}

private generateParticlesOnALine(parameters: { x: number }) {
const { x } = parameters;
const maxParticlesPerLine = 1;
for (let i = 0; i < maxParticlesPerLine; i++) {
const particleYOffset = Math.random() * 136 * CANVA_SCALEY;
this.particles.push(
new Particle({
x,
y: 17 * CANVA_SCALEY + particleYOffset,
width: this.particleWidth,
height: this.particleHeight,
speed: this.particleSpeed,
}),
);
}
}
}

export class GameScene implements IScene {
private cityBackgroundManager: CityBackgroundManager;
private particleEffectOnMap: ParticleManager;
private userStateUI: UserStateUI;
private timerIsToggled: boolean;
private inGameTimer: InGameTimer;
Expand Down Expand Up @@ -379,9 +511,9 @@ export class GameScene implements IScene {

Draw(ctx: CanvasRenderingContext2D) {
this.drawUI(ctx);
DrawGeneratedSpritesManager(ctx);
DrawPlayer(ctx);
DrawWaveManager(ctx);
DrawGeneratedSpritesManager(ctx);
if (this.timerIsToggled) {
this.inGameTimer.Draw(ctx);
}
Expand All @@ -391,6 +523,7 @@ export class GameScene implements IScene {

private loadUI() {
this.cityBackgroundManager = new CityBackgroundManager();
this.particleEffectOnMap = new ParticleManager();
this.userStateUI = new UserStateUI();
this.inGameTimer = new InGameTimer();
}
Expand All @@ -399,10 +532,12 @@ export class GameScene implements IScene {
this.cityBackgroundManager.Update(dt);
this.userStateUI.Update(dt);
this.inGameTimer.Update(dt);
this.particleEffectOnMap.Update(dt);
}

private drawUI(ctx: CanvasRenderingContext2D) {
this.cityBackgroundManager.Draw(ctx);
this.particleEffectOnMap.Draw(ctx);
this.userStateUI.Draw(ctx);
}
}
2 changes: 1 addition & 1 deletion src/Scenes/MainMenuScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class MainMenuScene implements IScene {
y: yTitle,
width: widthTitle,
height: heightTitle,
text: "WEB SHOOT'EM UP",
text: "Web Shoot'em UP",
fontSize: UIManager.Typography.title.fontSize,
fontFamily: UIManager.Typography.title.fontFamily,
});
Expand Down
2 changes: 1 addition & 1 deletion src/UtilManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class UtilManager implements IServiceUtilManager {
return undefined;
}

// Used to compute speed of any projectile and make it adapatable to the screen dimension
// Used to compute speed of any projectile and make it adapatable to the screen dimension, in pixel/frame -> also 1 frame = 1 dt
GetSpeedItTakesToCoverHalfTheScreenWidth(parameters: { framesItTakes: number }) {
const { framesItTakes } = parameters;
if (framesItTakes > 0) {
Expand Down

0 comments on commit 6cd0794

Please sign in to comment.