// FPS игры // Эта игра была написана на TypeScript fps(60); var song = new Audio(); song.src = 'https://storage.geekclass.ru/images/d13ad405-4f14-4239-af5d-582cf55320e1.ogg'; song.loop = true; song.play(); var completed = false; interface Drawable { draw(ctx: CanvasRenderingContext2D) : void; } class Scene implements Drawable { public objects: Array; public constructor() { this.objects = new Array(); } public draw(ctx: CanvasRenderingContext2D) : void { this.objects.forEach(function(i) { i.draw(ctx); }); } } class Mesh { public mesh: any; public constructor(maker: () => any) { this.mesh = maker(); } }; var MeshRefs = { playerImage: new Mesh(() => { var img = new Image(40, 40); img.src = "https://storage.geekclass.ru/images/be68a4c3-479a-4f21-b9da-08f27fb3b833.jpeg"; return img; }), wallImage: new Mesh(() => { var img = new Image(40, 40); img.src = "https://storage.geekclass.ru/images/b6dc49bf-c53b-48a4-a196-49c2bc0ea192.jpeg"; return img; }), flagImage: new Mesh(() => { var img = new Image(40, 40); img.src = "https://storage.geekclass.ru/images/3375898c-19ae-45d9-a5be-5bd791069de7.png"; return img; }) }; class Wall implements Drawable { public x: number; public y: number; mesh: Mesh; public constructor() { this.mesh = MeshRefs.wallImage; this.x = 0; this.y = 0; } public draw(ctx: CanvasRenderingContext2D) : void { ctx.drawImage( this.mesh.mesh, this.x, this.y, this.mesh.mesh.width, this.mesh.mesh.height ); } } class Flag implements Drawable { public x: number; public y: number; mesh: Mesh; public constructor() { this.mesh = MeshRefs.flagImage; this.x = 0; this.y = 0; } public draw(ctx: CanvasRenderingContext2D) : void { ctx.drawImage( this.mesh.mesh, this.x, this.y, this.mesh.mesh.width, this.mesh.mesh.height ); } } class GameMap implements Drawable { x: number; y: number; wall: Wall; flag: Flag; map: Array>; public fromArray(arr: Array>) : void { this.map = new Array>(); arr[0].forEach((i, ii) => { this.map.push(Array()); }); arr.forEach((i, ii) => { i.forEach((j, ij) => { this.map[ij].push(j); }); }); } public constructor() { this.flag = new Flag(); this.wall = new Wall(); this.x = 0; this.y = 0; } public draw(ctx: CanvasRenderingContext2D) : void { this.map.forEach((i, ii) => { i.forEach((j, ij) => { if (this.map[ii][ij] == 1) { this.wall.x = this.x + (ii * 40); this.wall.y = this.y + (ij * 40); this.wall.draw(ctx); } if (this.map[ii][ij] == 2) { this.flag.x = this.x + (ii * 40); this.flag.y = this.y + (ij * 40); this.flag.draw(ctx); } }); }); } } class Player implements Drawable { x: number; y: number; vy: number; vx: number; mesh: Mesh; public constructor() { this.mesh = MeshRefs.playerImage; this.x = 0; this.y = 0; this.vx = 0; this.vy = 0; } private singleCollision(i, j) { i = i*40; j = j*40; return i < this.x + 37 && i + 40 > this.x + 3 && j < this.y + 37 && j + 40 > this.y + 3; } public update(dt: number, level: GameMap) { var scalar = Math.sqrt(this.vx*this.vx+this.vy*this.vy); if (scalar == 0) return; this.x += this.vx/scalar*dt; if (this.x < 0) { this.x = 0; this.vy = 0; } this.collision(level, 'x'); this.y += this.vy/scalar*dt; if (this.y < 0) { this.vy = 0; this.y = 0; } this.collision(level, 'y'); } public collision(map: GameMap, dir: string) { var end = false; map.map.forEach((i, ii) => { if (end) return; i.forEach((j, ij) => { if (j == 1) { if (this.singleCollision(ii, ij)) { if (this.vx < 0 && dir == 'x') { this.vx = 0; this.x = ii * 40 + 37; } else if (this.vx > 0 && dir == 'x') { this.vx = 0; this.x = ii * 40 - 37; } if (this.vy < 0 && dir == 'y') { this.vy = 0; this.y = ij * 40 + 37; } else if (this.vy > 0 && dir == 'y') { this.vy = 0; this.y = ij * 40 - 37; } end = true; return; } } else if (j == 2 && this.singleCollision(ii, ij)) { completed = true; } }); }); if (dir == 'x') this.vx = 0; if (dir == 'y') this.vy = 0; } public draw(ctx: CanvasRenderingContext2D) : void { //Нарисовать меш игрока ctx.drawImage( this.mesh.mesh, this.x, this.y, this.mesh.mesh.width, this.mesh.mesh.height ); } } var scene: Scene = new Scene(); var level: GameMap = new GameMap(); var player: Player = new Player(); var lastTime = Date.now(); var currentLevel = 0; var deltaTime = 0; var levels = [ [ [0, 1, 1, 2, 1], [0, 0, 0, 0, 1], [0, 1, 1, 1, 1], [1, 1, 0, 0, 0], ], [ [1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 0, 0, 1], [1, 0, 0, 0, 1, 0, 1, 0, 1], [1, 0, 1, 1, 1, 0, 1, 0, 1], [1, 0, 0, 0, 0, 0, 1, 2, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1] ], [ [1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 1, 0, 0, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 1], [1, 2, 1, 0, 0, 0, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1] ], [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1], [1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1], [1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1], [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1], [1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1], [1, 2, 1, 0, 0, 0, 1, 0, 1, 0, 1], [1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ], [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1], [1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1], [1, 0, 1, 0, 0, 2, 1, 0, 1, 0, 1], [1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ], [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1], [1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1], [1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1], [1, 0, 1, 0, 0, 0, 1, 2, 1, 1, 1], [1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1], [1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1], [1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1], [1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ], [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ] ] level.fromArray(levels[currentLevel]); scene.objects.push(player); scene.objects.push(level); context.clearColor = '#7ddbe0'; function update() { var now = Date.now(); deltaTime = (now-lastTime)/10; lastTime = now; if (engine.keys['a'] || engine.keys['ф'] || engine.keys['A'] || engine.keys['Ф']) { player.vx = -30; } if (engine.keys['d'] || engine.keys['в'] || engine.keys['D'] || engine.keys['В']) { player.vx = 30; } if (engine.keys['w'] || engine.keys['ц'] || engine.keys['W'] || engine.keys['Ц']) { player.vy = -30; } if (engine.keys['s'] || engine.keys['ы'] || engine.keys['S'] || engine.keys['Ы']) { player.vy = 30; } player.update(deltaTime, level); if (completed) { currentLevel++; level.fromArray(levels[currentLevel]); completed = false; } draw(); } function draw() { context.clear(); scene.draw(context); }