Skip to content

Commit

Permalink
feat: #197 basic terrain obeying
Browse files Browse the repository at this point in the history
  • Loading branch information
marcinbator committed Dec 16, 2024
1 parent 4eb42d7 commit c99bcbd
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 16 deletions.
92 changes: 77 additions & 15 deletions src/app/game/games/climbhill/climbhill.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,66 @@ export class ClimbHillComponent
}
this.game.state.distance += this.game.state.carXSpeed;

this.generateTerrain();
this.updateCarPosition();

this.updateScore();

this.render();
}

//
private updateCarPosition(): void {
const terrain = this.game.state.visibleTerrain;
const contextWidth = this._canvas.width;
const segmentWidth = contextWidth / (terrain.length - 1);

const carXInTerrain = this._carX % contextWidth;
const segmentIndex = Math.floor(carXInTerrain / segmentWidth);
const segmentOffset = (carXInTerrain % segmentWidth) / segmentWidth;

const terrainY1 = terrain[segmentIndex] || 0;
const terrainY2 = terrain[segmentIndex + 1] || 0;
const targetCarY =
this._canvas.height / 2 -
(terrainY1 * (1 - segmentOffset) + terrainY2 * segmentOffset);

const targetCarAngle = Math.atan2(terrainY2 - terrainY1, segmentWidth);

const smoothingFactor = 0.2;
this.game.state.carY = this.lerp(
this.game.state.carY,
targetCarY,
smoothingFactor
);
this.game.state.carAngle = this.lerp(
this.game.state.carAngle,
targetCarAngle,
smoothingFactor
);
}

private generateTerrain(): void {
const terrainShiftAmount = this.game.state.carXSpeed * 0.03;
this.game.state.terrainShiftBuffer += terrainShiftAmount;

if (this.game.state.terrainShiftBuffer >= 1) {
this.game.state.visibleTerrain.shift();
const lastValue =
this.game.state.visibleTerrain[
this.game.state.visibleTerrain.length - 1
];
let newTerrainValue = lastValue + this.random(-15, 15);
if (newTerrainValue < -70) {
newTerrainValue = -70;
}
if (newTerrainValue > 120) {
newTerrainValue = 120;
}
this.game.state.visibleTerrain.push(newTerrainValue);

this.game.state.terrainShiftBuffer -= 1;
}
}

private resetValues(): void {
this.game.state.score = 0;
Expand All @@ -82,14 +137,19 @@ export class ClimbHillComponent
this.game.state.score = this.round(this.game.state.distance / 100);
}

private lerp(start: number, end: number, alpha: number): number {
return start * (1 - alpha) + end * alpha;
}

private render(): void {
const context = this._canvas.getContext('2d');
if (!context) return;

context.clearRect(0, 0, this._canvas.width, this._canvas.height);

context.save();
context.translate(this._carX, this.game.state.carY - this._carHeight / 2);
context.rotate(this.game.state.carAngle);
context.rotate(-this.game.state.carAngle);
context.fillStyle = 'blue';
context.fillRect(
-this._carWidth / 2,
Expand All @@ -103,23 +163,25 @@ export class ClimbHillComponent
}

private drawTerrain(context: CanvasRenderingContext2D): void {
const terrain = this.game.state.visibleTerrain;
const contextWidth = this._canvas.width;
const vertexesNumber = this.game.state.visibleTerrain.length;
const vertexStep = contextWidth / vertexesNumber;
const contextHeight = this._canvas.height;

const segmentWidth = contextWidth / (terrain.length - 1);
const pixelOffset = this.game.state.terrainShiftBuffer * segmentWidth;

context.beginPath();
context.lineWidth = 5;
context.moveTo(
0,
this._canvas.height - 200 - this.game.state.visibleTerrain[0]
);
for (let i = 1; i < vertexesNumber; i++) {
const vertexHeight = this.game.state.visibleTerrain[i];
context.lineTo(i * vertexStep, this._canvas.height - 200 - vertexHeight);
context.moveTo(-pixelOffset, contextHeight / 2 - terrain[0]);
for (let i = 1; i < terrain.length; i++) {
const x = i * segmentWidth - pixelOffset;
const y = contextHeight / 2 - terrain[i];
context.lineTo(x, y);
}
context.lineTo(contextWidth, this._canvas.height - 200);
context.strokeStyle = 'green';
context.stroke();
context.lineTo(contextWidth, contextHeight);
context.lineTo(0, contextHeight);
context.closePath();
context.fillStyle = 'green';
context.fill();
}

private random(min: number, max: number): number {
Expand Down
6 changes: 5 additions & 1 deletion src/app/game/games/climbhill/models/climbhill.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ export class ClimbHillState implements TGameState {
public carY = 0;
public carXSpeed = 0;
public carAngle = 0;
public visibleTerrain = [0, 0, 0, 10, 0, 0, 0, 0, 0, 0];
public terrainShiftBuffer = 0;
public visibleTerrain = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
];
}

export class ClimbHill extends Game {
Expand Down

0 comments on commit c99bcbd

Please sign in to comment.