From 6c37585ef4ef2535aff8c45c64850be0a6c26eab Mon Sep 17 00:00:00 2001 From: Maksymilian Jopek Date: Thu, 2 Jun 2022 08:54:02 +0200 Subject: Death animations --- src/Animation.ts | 14 ++++-- src/Drawable.ts | 4 +- src/Images.ts | 112 +++++++++++++++++++++++++++++++++++++++----- src/Player.ts | 11 +++-- src/consts.ts | 2 +- src/drawables/Background.ts | 3 +- src/drawables/Bullet.ts | 27 ++++++----- src/enemies/BigCircle.ts | 20 +++++++- src/enemies/Enemy.ts | 9 ++-- src/enemies/Green1.ts | 18 ++++++- src/enemies/Green2.ts | 17 ++++++- src/enemies/Red1.ts | 6 ++- src/enemies/Red2.ts | 8 ++-- src/enemies/Straight.ts | 17 ++++++- src/enemies/Strange.ts | 21 ++++++++- src/enemies/White.ts | 9 ++-- src/game.ts | 76 ++++++++++-------------------- src/helpers.ts | 5 ++ src/imgs/bg.png | Bin 21631 -> 24897 bytes src/imgs/bg2.xcf | Bin 76507 -> 121313 bytes src/imgs/big-death1.png | Bin 0 -> 6753 bytes src/imgs/big-death10.png | Bin 0 -> 4865 bytes src/imgs/big-death11.png | Bin 0 -> 656 bytes src/imgs/big-death2.png | Bin 0 -> 8829 bytes src/imgs/big-death3.png | Bin 0 -> 8888 bytes src/imgs/big-death4.png | Bin 0 -> 10882 bytes src/imgs/big-death5.png | Bin 0 -> 10672 bytes src/imgs/big-death6.png | Bin 0 -> 10162 bytes src/imgs/big-death7.png | Bin 0 -> 10711 bytes src/imgs/big-death8.png | Bin 0 -> 8546 bytes src/imgs/big-death9.png | Bin 0 -> 9459 bytes src/imgs/bulletEnemy.png | Bin 0 -> 574 bytes src/imgs/player-bullet2.png | Bin 0 -> 586 bytes src/imgs/player-bullet3.png | Bin 0 -> 583 bytes src/imgs/player-death1.png | Bin 0 -> 10034 bytes src/imgs/player-death10.png | Bin 0 -> 10336 bytes src/imgs/player-death11.png | Bin 0 -> 11076 bytes src/imgs/player-death12.png | Bin 0 -> 789 bytes src/imgs/player-death13.png | Bin 0 -> 761 bytes src/imgs/player-death14.png | Bin 0 -> 756 bytes src/imgs/player-death15.png | Bin 0 -> 761 bytes src/imgs/player-death16.png | Bin 0 -> 789 bytes src/imgs/player-death17.png | Bin 0 -> 783 bytes src/imgs/player-death18.png | Bin 0 -> 756 bytes src/imgs/player-death19.png | Bin 0 -> 761 bytes src/imgs/player-death2.png | Bin 0 -> 13694 bytes src/imgs/player-death20.png | Bin 0 -> 783 bytes src/imgs/player-death21.png | Bin 0 -> 10388 bytes src/imgs/player-death3.png | Bin 0 -> 12295 bytes src/imgs/player-death4.png | Bin 0 -> 12113 bytes src/imgs/player-death5.png | Bin 0 -> 790 bytes src/imgs/player-death6.png | Bin 0 -> 10282 bytes src/imgs/player-death7.png | Bin 0 -> 10287 bytes src/imgs/player-death8.png | Bin 0 -> 756 bytes src/imgs/player-death9.png | Bin 0 -> 761 bytes src/imgs/small-death1.png | Bin 0 -> 6892 bytes src/imgs/small-death2.png | Bin 0 -> 10707 bytes src/imgs/small-death3.png | Bin 0 -> 7891 bytes src/imgs/small-death4.png | Bin 0 -> 8362 bytes src/imgs/small-death5.png | Bin 0 -> 10846 bytes src/imgs/small-death6.png | Bin 0 -> 4962 bytes 61 files changed, 273 insertions(+), 106 deletions(-) create mode 100644 src/imgs/big-death1.png create mode 100644 src/imgs/big-death10.png create mode 100644 src/imgs/big-death11.png create mode 100644 src/imgs/big-death2.png create mode 100644 src/imgs/big-death3.png create mode 100644 src/imgs/big-death4.png create mode 100644 src/imgs/big-death5.png create mode 100644 src/imgs/big-death6.png create mode 100644 src/imgs/big-death7.png create mode 100644 src/imgs/big-death8.png create mode 100644 src/imgs/big-death9.png create mode 100644 src/imgs/bulletEnemy.png create mode 100644 src/imgs/player-bullet2.png create mode 100644 src/imgs/player-bullet3.png create mode 100644 src/imgs/player-death1.png create mode 100644 src/imgs/player-death10.png create mode 100644 src/imgs/player-death11.png create mode 100644 src/imgs/player-death12.png create mode 100644 src/imgs/player-death13.png create mode 100644 src/imgs/player-death14.png create mode 100644 src/imgs/player-death15.png create mode 100644 src/imgs/player-death16.png create mode 100644 src/imgs/player-death17.png create mode 100644 src/imgs/player-death18.png create mode 100644 src/imgs/player-death19.png create mode 100644 src/imgs/player-death2.png create mode 100644 src/imgs/player-death20.png create mode 100644 src/imgs/player-death21.png create mode 100644 src/imgs/player-death3.png create mode 100644 src/imgs/player-death4.png create mode 100644 src/imgs/player-death5.png create mode 100644 src/imgs/player-death6.png create mode 100644 src/imgs/player-death7.png create mode 100644 src/imgs/player-death8.png create mode 100644 src/imgs/player-death9.png create mode 100644 src/imgs/small-death1.png create mode 100644 src/imgs/small-death2.png create mode 100644 src/imgs/small-death3.png create mode 100644 src/imgs/small-death4.png create mode 100644 src/imgs/small-death5.png create mode 100644 src/imgs/small-death6.png diff --git a/src/Animation.ts b/src/Animation.ts index 820a6dd..968a57d 100644 --- a/src/Animation.ts +++ b/src/Animation.ts @@ -5,21 +5,25 @@ export default class Anime extends Drawable { i = 0; j = 0; - constructor(drawable: Drawable, public frames: Array) { + constructor(public drawable: Drawable, public frames: Array) { super(drawable._x, drawable._y) this.width = drawable.width this.height = drawable.height - if (frames.length === 0) debugger + // if (frames.length === 0) debugger } draw(): boolean { if (typeof this.frames[0] === "string") { ctx.fillStyle = (this.frames as string[])[this.i]; - ctx.fillRect(this.x, this.y, this.width, this.height); + ctx.fillRect(this.drawable.x, this.drawable.y, this.drawable.width, this.drawable.height); } else { - ctx.drawImage((this.frames as HTMLImageElement[])[this.i], this.x, this.y) + try { + const f = (this.frames as HTMLImageElement[])[this.i] + if (f) + ctx.drawImage(f, this.drawable.x, this.drawable.y) + } catch (e) { debugger } } - if (++this.j === 4) { this.i++; this.j = 0; } + if (++this.j === 5) { this.i++; this.j = 0; } return this.i !== this.frames.length; } } diff --git a/src/Drawable.ts b/src/Drawable.ts index 9ed9a2a..375d515 100644 --- a/src/Drawable.ts +++ b/src/Drawable.ts @@ -73,7 +73,7 @@ export default abstract class Drawable { if (val <= 15 + 24) this._y = 15 + 24; // else if (val + this.height >= canvas.height - 15) this._y = canvas.height - 15 - this.height + diff; else if (val + this.height >= canvas.height - 15) { - if (left || right) return + if (left || right) this._y = canvas.height - 15 - this.height + diff + 1; else this._y = canvas.height - 15 - this.height + diff; } else this._y = val @@ -90,6 +90,7 @@ export default abstract class Drawable { } export class Rectangle extends Drawable { + sprite = "rgba(128,0,128, 0.5)" constructor(public begetter: Drawable, x?: number, y?: number, width?: number, height?: number) { if (begetter.width === PLAYER_SIZE) { console.log(begetter.x, begetter.y, begetter.width, begetter.height); @@ -111,7 +112,6 @@ export class Rectangle extends Drawable { set y(val) { this._y = val } get x2() { return this.x + this.width } get y2() { return this.y + this.height } - sprite = "rgba(128,0,128, 0.5)" } // export abstract class Square { // constructor(public x: number, public y: number, public width: number, public height: number) { } diff --git a/src/Images.ts b/src/Images.ts index eeda006..99e9b02 100644 --- a/src/Images.ts +++ b/src/Images.ts @@ -1,9 +1,8 @@ -// const URLS = [ -// "/src/imgs/bg2.png", -// "/src/imgs/topbar.png", -// ]; +import Anime from "./Animation"; import { allChars, alphabet } from "./consts"; +import Enemy from "./enemies/Enemy"; import { toKebabCase } from "./helpers"; +import Player from "./Player"; export const IMGS = { bg: {} as HTMLImageElement, @@ -61,13 +60,54 @@ export const IMGS = { whiteTurnRight: {} as HTMLImageElement, whiteStrangeLeft: {} as HTMLImageElement, whiteStrangeRight: {} as HTMLImageElement, + playerDeath1: {} as HTMLImageElement, + playerDeath2: {} as HTMLImageElement, + playerDeath3: {} as HTMLImageElement, + playerDeath4: {} as HTMLImageElement, + playerDeath5: {} as HTMLImageElement, + playerDeath6: {} as HTMLImageElement, + playerDeath7: {} as HTMLImageElement, + playerDeath8: {} as HTMLImageElement, + playerDeath9: {} as HTMLImageElement, + playerDeath10: {} as HTMLImageElement, + playerDeath11: {} as HTMLImageElement, + playerDeath12: {} as HTMLImageElement, + playerDeath13: {} as HTMLImageElement, + playerDeath14: {} as HTMLImageElement, + playerDeath15: {} as HTMLImageElement, + playerDeath16: {} as HTMLImageElement, + playerDeath17: {} as HTMLImageElement, + playerDeath18: {} as HTMLImageElement, + playerDeath19: {} as HTMLImageElement, + playerDeath20: {} as HTMLImageElement, + playerDeath21: {} as HTMLImageElement, + smallDeath1: {} as HTMLImageElement, + smallDeath2: {} as HTMLImageElement, + smallDeath3: {} as HTMLImageElement, + smallDeath4: {} as HTMLImageElement, + smallDeath5: {} as HTMLImageElement, + smallDeath6: {} as HTMLImageElement, + bigDeath1: {} as HTMLImageElement, + bigDeath2: {} as HTMLImageElement, + bigDeath3: {} as HTMLImageElement, + bigDeath4: {} as HTMLImageElement, + bigDeath5: {} as HTMLImageElement, + bigDeath6: {} as HTMLImageElement, + bigDeath7: {} as HTMLImageElement, + bigDeath8: {} as HTMLImageElement, + bigDeath9: {} as HTMLImageElement, + bigDeath10: {} as HTMLImageElement, + bigDeath11: {} as HTMLImageElement, + playerBullet2: {} as HTMLImageElement, + playerBullet3: {} as HTMLImageElement, + enemyBullet: {} as HTMLImageElement, planeIcon: {} as HTMLImageElement, rollIcon: {} as HTMLImageElement, - startScreen0: {} as HTMLImageElement, - startScreen1: {} as HTMLImageElement, - startScreen2: {} as HTMLImageElement, - startScreen3: {} as HTMLImageElement, - startScreen4: {} as HTMLImageElement, + // startScreen0: {} as HTMLImageElement, + // startScreen1: {} as HTMLImageElement, + // startScreen2: {} as HTMLImageElement, + // startScreen3: {} as HTMLImageElement, + // startScreen4: {} as HTMLImageElement, font: { white: {} as any, yellow: {} as any, @@ -89,8 +129,8 @@ export default async function loadAllImages() { if (["empty", "font"].includes(key)) continue; IMGS[key as keyof typeof IMGS] = await asyncImageLoader("/src/imgs/" + toKebabCase(key) + ".png") as any } - for (const color of ['yellow', 'white', 'blue', 'red', 'green', 'purple']) { - // for (const color of ['white']) { + // for (const color of ['yellow', 'white', 'blue', 'red', 'green', 'purple']) { + for (const color of ['white']) { for (const char of allChars) { (((IMGS.font as any)[color] as any)[char]) = await asyncImageLoader("/src/imgs/font/" + color + "/" + encodeURIComponent(char) + ".png") as any } @@ -116,3 +156,53 @@ async function asyncImageLoader(url: string): Promise { }) } +export function getSmallDeathAnim(t: Enemy) { + return new Anime(t, [ + IMGS.smallDeath1, + IMGS.smallDeath2, + IMGS.smallDeath3, + IMGS.smallDeath4, + IMGS.smallDeath5, + IMGS.smallDeath6, + ]) +} +export function getBigDeathAnim(t: Enemy) { + return new Anime(t, [ + IMGS.bigDeath1, + IMGS.bigDeath2, + IMGS.bigDeath3, + IMGS.bigDeath4, + IMGS.bigDeath5, + IMGS.bigDeath6, + IMGS.bigDeath7, + IMGS.bigDeath8, + IMGS.bigDeath9, + IMGS.bigDeath10, + IMGS.bigDeath11, + ]) +} +export function getPlayerDeathAnim(t: Player) { + return new Anime(t, [ + IMGS.playerDeath1, + IMGS.playerDeath2, + IMGS.playerDeath3, + IMGS.playerDeath4, + IMGS.playerDeath5, + IMGS.playerDeath6, + IMGS.playerDeath7, + IMGS.playerDeath8, + IMGS.playerDeath9, + IMGS.playerDeath10, + IMGS.playerDeath11, + IMGS.playerDeath12, + IMGS.playerDeath13, + IMGS.playerDeath14, + IMGS.playerDeath15, + IMGS.playerDeath16, + IMGS.playerDeath17, + IMGS.playerDeath18, + IMGS.playerDeath19, + IMGS.playerDeath20, + IMGS.playerDeath21, + ]) +} diff --git a/src/Player.ts b/src/Player.ts index eb76fbe..f79211f 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1,9 +1,8 @@ -import Anime from "./Animation"; import Bullet from "./drawables/Bullet"; import { BULLET_VEL, canvas, ctx, FIRE_DELAY, PLAYER_VEL } from "./consts"; import Drawable, { Rectangle } from "./Drawable"; import { keys } from "./Events"; -import { IMGS } from "./Images"; +import { getPlayerDeathAnim, IMGS } from "./Images"; export default class Player extends Drawable { static startx = 175; @@ -19,8 +18,8 @@ export default class Player extends Drawable { // squares: Rectangle[] = [new Rectangle(this)] squares: Rectangle[] = [] - lifes = 3; power = 2; + alive = true; constructor() { super(Player.startx, Player.starty) @@ -30,10 +29,11 @@ export default class Player extends Drawable { if (!keys.fire || keys.repeat) return; if (Date.now() - this.lastShoot < FIRE_DELAY) return; this.lastShoot = Date.now() - bullet.push(new Bullet(this.x + (this.width / 2) - Bullet.width / 2, this.y - Bullet.height, 0, -BULLET_VEL, true)) + bullet.push(new Bullet(this.x + 2, this.y + 7, 0, -BULLET_VEL, true, this.power)) } move() { + if (!this.alive) return false if (+keys.right ^ +keys.left) { keys.right ? this.xvel = PLAYER_VEL : this.xvel = -PLAYER_VEL; } else { @@ -62,6 +62,7 @@ export default class Player extends Drawable { return true; } draw() { + if (!this.alive) return this.sprite = this.sprite ?? IMGS.playerUp; try { ctx.drawImage(this.sprite, this.x, this.y) @@ -70,5 +71,5 @@ export default class Player extends Drawable { } } - get deathAnimation() { return new Anime(this, ["red", "green", "blue"]) } + deathAnimation = getPlayerDeathAnim(this) } diff --git a/src/consts.ts b/src/consts.ts index 63f9917..5443a1a 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -4,7 +4,7 @@ ctx.imageSmoothingEnabled = false; export const PLAYER_SIZE = 20; // canvas-dot export const PLAYER_VEL = 3.5; // canvas-dot / frame -export const BULLET_VEL = 4.5; // canvas-dot / frame +export const BULLET_VEL = 4; // canvas-dot / frame export const FIRE_DELAY = 300; // ms export const TOPBAR_HEIGHT = 24; // ms diff --git a/src/drawables/Background.ts b/src/drawables/Background.ts index da091a1..622a608 100644 --- a/src/drawables/Background.ts +++ b/src/drawables/Background.ts @@ -10,8 +10,9 @@ export class Background extends Drawable { super(0, 0) } // delta = -1751 + 24 + 2693; - delta = 0 + delta = 2500 move() { + if (this.delta + 1 > 2580) return true this.delta += 1; return true; } diff --git a/src/drawables/Bullet.ts b/src/drawables/Bullet.ts index a745a06..f121cfa 100644 --- a/src/drawables/Bullet.ts +++ b/src/drawables/Bullet.ts @@ -1,29 +1,30 @@ -import { canvas } from "../consts"; import Drawable, { Rectangle } from "../Drawable"; +import { IMGS } from "../Images"; export default class Bullet extends Drawable { static width = 2; static height = 5; static color = "black"; - width = 2; - height = 5; - color = "black"; - sprite = "black"; + // width = 2; + // height = 5; + // color = "black"; - squares: Rectangle[] = [new Rectangle(this)] - constructor(x: number, y: number, public xvel: number, public yvel: number, public players: boolean) { - super(x, y); - // this.width = Bullet.width; - // this.height = Bullet.height; + constructor(x: number, y: number, public xvel: number, public yvel: number, public players: boolean, public power?: number) { + super(Math.floor(x), Math.floor(y)); + //@ts-expect-error + if (players) this.sprite = IMGS["playerBullet" + power] + else this.sprite = IMGS.enemyBullet; + this.width = (this.sprite as HTMLImageElement).width + this.height = (this.sprite as HTMLImageElement).height + this.squares = [new Rectangle(this)] + console.log(this.width, this.height); } move(): boolean { this.x += this.xvel; this.y += this.yvel; - return ( - this.x + this.width < 0 || this.y + this.height < 0 || this.x > canvas.width || this.y > canvas.height - ); + return this.isOutsideMap() } } diff --git a/src/enemies/BigCircle.ts b/src/enemies/BigCircle.ts index 5525b13..1f9f7dd 100644 --- a/src/enemies/BigCircle.ts +++ b/src/enemies/BigCircle.ts @@ -1,7 +1,9 @@ import { canvas } from "../consts"; import { Rectangle } from "../Drawable"; +import Bullet from "../drawables/Bullet"; +import { random } from "../helpers"; // import { keys } from "../Events"; -import { IMGS } from "../Images"; +import { getBigDeathAnim, IMGS } from "../Images"; import Enemy from "./Enemy"; export default class BigCircle extends Enemy { @@ -232,6 +234,21 @@ export default class BigCircle extends Enemy { return this.x2 < 0 || this.y2 < 0 || this.x > canvas.width || this.y > canvas.height } + hasShooted0 = false + hasShooted32 = false + shoot(bullets: Bullet[]): boolean { + if (this.phase !== 0 && this.phase !== 32) return false + if (this.phase === 0 && this.hasShooted0) return false + if (this.phase === 32 && this.hasShooted32) return false + if (random(0.05)) { + if (super.shoot(bullets)) + //@ts-expect-error + this["hasShooted" + this.phase] = true + } + return true; + // (new Bullet(this.width / 2, this.y2, 0, 2, false)) + } + readonly allSqaures = { bigCircleDown: [new Rectangle(this, 14, 0, 20, 8), new Rectangle(this, 20, 0, 8, 40), new Rectangle(this, 0, 22, 48, 12)], bigCircleDownToRight1: [new Rectangle(this, 4, 0, 14, 16), new Rectangle(this, 14, 10, 24, 20), new Rectangle(this, 0, 20, 24, 20)], @@ -251,5 +268,6 @@ export default class BigCircle extends Enemy { bigCircleLeftToDown3: [new Rectangle(this, 20, 2, 14, 10), new Rectangle(this, 18, 12, 8, 26), new Rectangle(this, 26, 24, 12, 14), new Rectangle(this, 0, 12, 14, 12), new Rectangle(this, 14, 24, 4, 14), new Rectangle(this, 4, 24, 10, 6), new Rectangle(this, 12, 14, 8, 14)], }; + deathAnim = getBigDeathAnim(this) } diff --git a/src/enemies/Enemy.ts b/src/enemies/Enemy.ts index d85b11e..224e66c 100644 --- a/src/enemies/Enemy.ts +++ b/src/enemies/Enemy.ts @@ -1,14 +1,17 @@ import Bullet from "../drawables/Bullet"; -import { BULLET_VEL } from "../consts"; +import { BULLET_VEL, TOPBAR_HEIGHT } from "../consts"; import Drawable, { Rectangle } from "../Drawable"; +import Anime from "../Animation"; export default abstract class Enemy extends Drawable { squares: Array = [new Rectangle(this)] points = 5; health = 2 - deathAnim: (string | HTMLImageElement)[] = ["red"] + deathAnim!: Anime; - shoot(bullet: Bullet[]) { + shoot(bullet: Bullet[]): boolean { + if (this.y2 < TOPBAR_HEIGHT) return false bullet.push(new Bullet(this.x + (this.width / 2) - Bullet.width / 2, this.y2, 0, BULLET_VEL, false)) + return true } } diff --git a/src/enemies/Green1.ts b/src/enemies/Green1.ts index 034ab15..2510f97 100644 --- a/src/enemies/Green1.ts +++ b/src/enemies/Green1.ts @@ -1,5 +1,7 @@ import { Rectangle } from "../Drawable"; -import { IMGS } from "../Images"; +import Bullet from "../drawables/Bullet"; +import { random } from "../helpers"; +import { getSmallDeathAnim, IMGS } from "../Images"; import Enemy from "./Enemy"; export default class Green1 extends Enemy { @@ -53,7 +55,19 @@ export default class Green1 extends Enemy { this.y += dy; this.width = this.sprite.width this.height = this.sprite.height - this.squares = [new Rectangle(this, 2, 2, this.width - 2, this.height - 2)] + this.squares = [new Rectangle(this, 2, 2, this.width - 4, this.height - 4)] return this.isOutsideMap() } + + hasShooted = false; + shoot(bullets: Bullet[]): boolean { + if (this.sprite !== IMGS.greenDown || this.hasShooted) return false; + if (random(0.008)) { + if (super.shoot(bullets)) + this.hasShooted = true + } + return true; + } + + deathAnim = getSmallDeathAnim(this) } diff --git a/src/enemies/Green2.ts b/src/enemies/Green2.ts index b4d9ddc..a6adb74 100644 --- a/src/enemies/Green2.ts +++ b/src/enemies/Green2.ts @@ -1,5 +1,7 @@ import { Rectangle } from "../Drawable"; -import { IMGS } from "../Images"; +import Bullet from "../drawables/Bullet"; +import { random } from "../helpers"; +import { getSmallDeathAnim, IMGS } from "../Images"; import Enemy from "./Enemy"; export default class Green2 extends Enemy { @@ -107,7 +109,18 @@ export default class Green2 extends Enemy { this.y += dy; this.width = this.sprite.width this.height = this.sprite.height - this.squares = [new Rectangle(this, 2, 2, this.width - 2, this.height - 2)] + this.squares = [new Rectangle(this, 2, 2, this.width - 4, this.height - 4)] return this.isOutsideMap() } + + hasShooted = false; + shoot(bullets: Bullet[]): boolean { + if (this.sprite !== IMGS.greenDown || this.hasShooted) return false; + if (random(0.008)) { + if (super.shoot(bullets)) + this.hasShooted = true + } + return true; + } + deathAnim = getSmallDeathAnim(this) } diff --git a/src/enemies/Red1.ts b/src/enemies/Red1.ts index 67a8729..9c50820 100644 --- a/src/enemies/Red1.ts +++ b/src/enemies/Red1.ts @@ -1,5 +1,5 @@ import { Rectangle } from "../Drawable"; -import { IMGS } from "../Images"; +import { getSmallDeathAnim, IMGS } from "../Images"; import Enemy from "./Enemy"; export default class Red1 extends Enemy { @@ -187,7 +187,9 @@ export default class Red1 extends Enemy { this.y += dy; this.width = this.sprite.width this.height = this.sprite.height - this.squares = [new Rectangle(this, 2, 2, this.width - 2, this.height - 2)] + this.squares = [new Rectangle(this, 2, 2, this.width - 4, this.height - 4)] return this.isOutsideMap() } + shoot(): boolean { return false } + deathAnim = getSmallDeathAnim(this) } diff --git a/src/enemies/Red2.ts b/src/enemies/Red2.ts index 6cfa672..ced55cd 100644 --- a/src/enemies/Red2.ts +++ b/src/enemies/Red2.ts @@ -1,5 +1,5 @@ import { Rectangle } from "../Drawable"; -import { IMGS } from "../Images"; +import { getSmallDeathAnim, IMGS } from "../Images"; import Enemy from "./Enemy"; export default class Red2 extends Enemy { @@ -96,7 +96,6 @@ export default class Red2 extends Enemy { break; case 16: dy = this.vel - console.log(this.x); break; default: @@ -107,8 +106,11 @@ export default class Red2 extends Enemy { this.y += dy; this.width = this.sprite.width this.height = this.sprite.height - this.squares = [new Rectangle(this, 2, 2, this.width - 2, this.height - 2)] + this.squares = [new Rectangle(this, 2, 2, this.width - 4, this.height - 4)] return this.isOutsideMap() && this.phase > 12 } + shoot(): boolean { return false } + + deathAnim = getSmallDeathAnim(this) } diff --git a/src/enemies/Straight.ts b/src/enemies/Straight.ts index 895ec01..7bc82f9 100644 --- a/src/enemies/Straight.ts +++ b/src/enemies/Straight.ts @@ -1,6 +1,8 @@ import { canvas } from "../consts"; import { Rectangle } from "../Drawable"; -import { IMGS } from "../Images"; +import Bullet from "../drawables/Bullet"; +import { random } from "../helpers"; +import { getSmallDeathAnim, IMGS } from "../Images"; import Enemy from "./Enemy"; export default class Straight extends Enemy { @@ -36,4 +38,17 @@ export default class Straight extends Enemy { this.squares = [new Rectangle(this, 2, 2, this.width - 2, this.height - 2)] return this.y + this.height < 0 } + + hasShooted = false + shoot(bullets: Bullet[]): boolean { + if (this.hasShooted || this.phase !== 0) return false + if (random(0.008)) { + if (super.shoot(bullets)) + this.hasShooted = true + } + return true; + // (new Bullet(this.width / 2, this.y2, 0, 2, false)) + } + + deathAnim = getSmallDeathAnim(this) } diff --git a/src/enemies/Strange.ts b/src/enemies/Strange.ts index 69fd9c0..036409a 100644 --- a/src/enemies/Strange.ts +++ b/src/enemies/Strange.ts @@ -1,5 +1,8 @@ +import { BULLET_VEL, TOPBAR_HEIGHT } from "../consts"; import { Rectangle } from "../Drawable"; -import { IMGS } from "../Images"; +import Bullet from "../drawables/Bullet"; +import { random } from "../helpers"; +import { getBigDeathAnim, IMGS } from "../Images"; import Enemy from "./Enemy"; export default class Strange extends Enemy { @@ -88,5 +91,21 @@ export default class Strange extends Enemy { // this.squares = [new Rectangle(this, 2, 2, this.width - 2, this.height - 2)] return this.isOutsideMap() } + + shoot(bullets: Bullet[]): boolean { + if (this.y2 < TOPBAR_HEIGHT) return false + if (random(0.01)) { + if (random(0.5)) { + bullets.push(new Bullet(this.x + (this.width / 2) - Bullet.width / 2, this.y2, 0, BULLET_VEL, false)) + } else { + if (random(0.5)) bullets.push(new Bullet(this.x + (this.width / 2) - Bullet.width / 2, this.y2, BULLET_VEL - 1, BULLET_VEL - 1, false)) + else bullets.push(new Bullet(this.x + (this.width / 2) - Bullet.width / 2, this.y2, -BULLET_VEL + 1, BULLET_VEL - 1, false)) + } + + } + return true + } + + deathAnim = getBigDeathAnim(this) } diff --git a/src/enemies/White.ts b/src/enemies/White.ts index 2987985..e5b22ae 100644 --- a/src/enemies/White.ts +++ b/src/enemies/White.ts @@ -1,5 +1,5 @@ import { Rectangle } from "../Drawable"; -import { IMGS } from "../Images"; +import { getSmallDeathAnim, IMGS } from "../Images"; import Enemy from "./Enemy"; export default class White extends Enemy { @@ -11,7 +11,7 @@ export default class White extends Enemy { phase = 0; spriteNum = 1; i = 0; - squares: Rectangle[] = [new Rectangle(this, 2, 2, this.width - 2, this.height - 2)] + squares: Rectangle[] = [new Rectangle(this)] constructor(x: number, y: number, public left: boolean) { super(x, y) @@ -61,8 +61,11 @@ export default class White extends Enemy { this.y += dy; this.width = this.sprite.width this.height = this.sprite.height - this.squares = [new Rectangle(this, 2, 2, this.width - 2, this.height - 2)] + this.squares = [new Rectangle(this)] return this.isOutsideMap() } + + shoot(): boolean { return false } + deathAnim = getSmallDeathAnim(this) } diff --git a/src/game.ts b/src/game.ts index 7991d94..adb7326 100644 --- a/src/game.ts +++ b/src/game.ts @@ -28,37 +28,24 @@ let bullets = [] as Bullet[] const playerBullets = () => bullets.filter(b => b.players) const enemyBullets = () => bullets.filter(b => !b.players) let enemies = [] as Enemy[] -// let bg = new Background(); let animations = [] as Anime[] let intervalId = 0; let rafId = 0; -let menu = true +let showMenu = false const bg = new Background() const tb = new TopBar() const hg = new Highscore() -// const ss = new Startscreen(); export function start() { p = new Player() bullets = [] as Bullet[] enemies = [] as Enemy[] animations = [] as Anime[] - // enemies.push(new BigCircle(25, -20)) - // enemies.push(new Straight(20, 0)) - // enemies.push(new Red1(0, 51)) - // enemies.push(new Green1(115, canvas.height, true), new Green1(170, canvas.height, false)) - // enemies.push(new Strange(160, canvas.height)) - // enemies.push(new White(60, 0, true), new White(230, 0, false)) - // enemies.push(new Red2(100, 0, true), new Red2(180, 0, false)) - // enemies.push(new Green2(100, 0, true), new Green2(180, 0, false)) newTimeout() rafId = requestAnimationFrame(gpuLoop) } export function cpuLoop() { - // ss.move() - // newTimeout() - // return - if (menu) { + if (showMenu) { cpuMenu() newTimeout() return @@ -74,24 +61,9 @@ export function cpuLoop() { bg.move() spawnEnemies() tb.setData(score, pLifes, rolls, highscore) - if (enemies.length === 0) { - // enemies.push(new BigCircle(25, -20)) - // enemies.push(new Straight(25, -20)) - // enemies.push(new Red1(25, -20)) - // enemies.push(new Green1(115, canvas.height, true), new Green1(170, canvas.height, false)) - // enemies.push(new Strange(160, canvas.height)) - // enemies.push(new White(60, 0, true), new White(230, 0, false)) - // enemies.push(new Red2(100, 0, true), new Red2(180, 0, false)) - // enemies.push(new Green2(100, 0, true), new Green2(180, 0, false)) - // setTimeout(() => enemies.push(new Straight(25, -20)), 1000) - // setTimeout(() => enemies.push(new BigCircle(25, -20)), 1000) - // setTimeout(() => enemies.push(new Red1(25, -20)), 1000) - // setTimeout(() => enemies.push(new Green1(115, canvas.height, true), new Green1(170, canvas.height, false)), 1000) - // setTimeout(() => enemies.push(new Strange(160, canvas.height)), 1000) - } // enemies = enemies.filter(e => !bullets.some(b => b.collides(e))) - enemies.forEach(e => Math.random() < 0.05 && e.shoot(bullets)) + enemies.forEach(e => e.shoot(bullets)) enemies = enemies.filter(e => !e.move()) bullets = bullets.filter(b => !b.move()) @@ -106,20 +78,21 @@ export function cpuLoop() { enemies = enemies.filter(e => { if (e.collides(playerBullets())) { e.health -= p.power; - animations.push(new Anime(e, e.deathAnim)) bullets = bullets.filter(b => !b.collides([e])) if (e.health < 1) { + animations.push(e.deathAnim) score += e.points return false } - return true } return true; }) // console.log("aft: ", enemies.length); // playerDied({} as Enemy) if (bullCollPlay.length || enemCollPlay.length) playerDied(enemCollPlay) - else newTimeout() + // if (bullCollPlay.length || enemCollPlay.length) animations.push(p.deathAnimation) + // else newTimeout() + newTimeout() } export function gpuLoop() { @@ -127,7 +100,7 @@ export function gpuLoop() { clearCtx() - if (menu) { + if (showMenu) { gpuMenu() return } @@ -139,10 +112,12 @@ export function gpuLoop() { bg.draw() bullets.forEach(b => b.draw()) + bullets.forEach(b => b.squares.forEach(s => s.draw())) p.squares.forEach(s => s.draw()) p.draw() enemies.forEach(e => { e.draw() + e.squares.forEach(s => s.draw()) if (e instanceof BigCircle) { e.squares.forEach(s => s.draw()) } @@ -153,19 +128,19 @@ export function gpuLoop() { export async function playerDied(_enemy: Enemy[]) { animations.push(p.deathAnimation) - p.width = 0; - p.height = 0; - clearTimeout(intervalId) - cancelAnimationFrame(rafId) - pLifes -= 1; - if (pLifes !== 0) { - await drawRestartScreen(); - start() - } else { - hg.show = true - newTimeout() - requestAnimationFrame(gpuLoop) - } + p.alive = false + p.squares = [] + // clearTimeout(intervalId) + // cancelAnimationFrame(rafId) + // pLifes -= 1; + // if (pLifes !== 0) { + // await drawRestartScreen(); + // start() + // } else { + // hg.show = true + // newTimeout() + // requestAnimationFrame(gpuLoop) + // } } export async function drawRestartScreen() { @@ -180,6 +155,7 @@ const startscreen = new Startscreen() tb.setData(score, pLifes, rolls, highscore) function cpuMenu() { startscreen.move() + if (keys.fire === true) showMenu = false; } function gpuMenu() { tb.draw() @@ -215,6 +191,6 @@ function spawnEnemies() { if (bg.delta === 2000 + 85 * 2) enemies.push(new White(60, 0, true), new White(230, 0, false)) if (bg.delta === 2000 + 85 * 3) enemies.push(new White(60, 0, true)) - if (bg.delta > 2200) - console.log(bg.delta); + // if (bg.delta > 2200) + // console.log(bg.delta); } diff --git a/src/helpers.ts b/src/helpers.ts index 8a17555..9bb1eac 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -6,3 +6,8 @@ export const toKebabCase = (str: string) => str .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) ?.map(x => x.toLowerCase()) .join('-'); + +export function random(p: number): boolean { + if (p < 0 || p > 1) throw Error("Wrong probability - " + p) + return Math.random() < p; +} diff --git a/src/imgs/bg.png b/src/imgs/bg.png index cef05ec..6dcd662 100644 Binary files a/src/imgs/bg.png and b/src/imgs/bg.png differ diff --git a/src/imgs/bg2.xcf b/src/imgs/bg2.xcf index 04604c9..0c7fe71 100644 Binary files a/src/imgs/bg2.xcf and b/src/imgs/bg2.xcf differ diff --git a/src/imgs/big-death1.png b/src/imgs/big-death1.png new file mode 100644 index 0000000..3e8b9e3 Binary files /dev/null and b/src/imgs/big-death1.png differ diff --git a/src/imgs/big-death10.png b/src/imgs/big-death10.png new file mode 100644 index 0000000..a99f721 Binary files /dev/null and b/src/imgs/big-death10.png differ diff --git a/src/imgs/big-death11.png b/src/imgs/big-death11.png new file mode 100644 index 0000000..7b3a140 Binary files /dev/null and b/src/imgs/big-death11.png differ diff --git a/src/imgs/big-death2.png b/src/imgs/big-death2.png new file mode 100644 index 0000000..469f4a1 Binary files /dev/null and b/src/imgs/big-death2.png differ diff --git a/src/imgs/big-death3.png b/src/imgs/big-death3.png new file mode 100644 index 0000000..684999e Binary files /dev/null and b/src/imgs/big-death3.png differ diff --git a/src/imgs/big-death4.png b/src/imgs/big-death4.png new file mode 100644 index 0000000..96a9150 Binary files /dev/null and b/src/imgs/big-death4.png differ diff --git a/src/imgs/big-death5.png b/src/imgs/big-death5.png new file mode 100644 index 0000000..bcc6dac Binary files /dev/null and b/src/imgs/big-death5.png differ diff --git a/src/imgs/big-death6.png b/src/imgs/big-death6.png new file mode 100644 index 0000000..d8f6dd6 Binary files /dev/null and b/src/imgs/big-death6.png differ diff --git a/src/imgs/big-death7.png b/src/imgs/big-death7.png new file mode 100644 index 0000000..08a75e2 Binary files /dev/null and b/src/imgs/big-death7.png differ diff --git a/src/imgs/big-death8.png b/src/imgs/big-death8.png new file mode 100644 index 0000000..68a3640 Binary files /dev/null and b/src/imgs/big-death8.png differ diff --git a/src/imgs/big-death9.png b/src/imgs/big-death9.png new file mode 100644 index 0000000..f49b775 Binary files /dev/null and b/src/imgs/big-death9.png differ diff --git a/src/imgs/bulletEnemy.png b/src/imgs/bulletEnemy.png new file mode 100644 index 0000000..ecd1ebc Binary files /dev/null and b/src/imgs/bulletEnemy.png differ diff --git a/src/imgs/player-bullet2.png b/src/imgs/player-bullet2.png new file mode 100644 index 0000000..b46731d Binary files /dev/null and b/src/imgs/player-bullet2.png differ diff --git a/src/imgs/player-bullet3.png b/src/imgs/player-bullet3.png new file mode 100644 index 0000000..2632d03 Binary files /dev/null and b/src/imgs/player-bullet3.png differ diff --git a/src/imgs/player-death1.png b/src/imgs/player-death1.png new file mode 100644 index 0000000..cb2e8a0 Binary files /dev/null and b/src/imgs/player-death1.png differ diff --git a/src/imgs/player-death10.png b/src/imgs/player-death10.png new file mode 100644 index 0000000..5a9700d Binary files /dev/null and b/src/imgs/player-death10.png differ diff --git a/src/imgs/player-death11.png b/src/imgs/player-death11.png new file mode 100644 index 0000000..6486c7e Binary files /dev/null and b/src/imgs/player-death11.png differ diff --git a/src/imgs/player-death12.png b/src/imgs/player-death12.png new file mode 100644 index 0000000..da8dee6 Binary files /dev/null and b/src/imgs/player-death12.png differ diff --git a/src/imgs/player-death13.png b/src/imgs/player-death13.png new file mode 100644 index 0000000..28c1505 Binary files /dev/null and b/src/imgs/player-death13.png differ diff --git a/src/imgs/player-death14.png b/src/imgs/player-death14.png new file mode 100644 index 0000000..3fbb436 Binary files /dev/null and b/src/imgs/player-death14.png differ diff --git a/src/imgs/player-death15.png b/src/imgs/player-death15.png new file mode 100644 index 0000000..fff792f Binary files /dev/null and b/src/imgs/player-death15.png differ diff --git a/src/imgs/player-death16.png b/src/imgs/player-death16.png new file mode 100644 index 0000000..2e71f03 Binary files /dev/null and b/src/imgs/player-death16.png differ diff --git a/src/imgs/player-death17.png b/src/imgs/player-death17.png new file mode 100644 index 0000000..6d4059c Binary files /dev/null and b/src/imgs/player-death17.png differ diff --git a/src/imgs/player-death18.png b/src/imgs/player-death18.png new file mode 100644 index 0000000..8c429b9 Binary files /dev/null and b/src/imgs/player-death18.png differ diff --git a/src/imgs/player-death19.png b/src/imgs/player-death19.png new file mode 100644 index 0000000..dab2a3b Binary files /dev/null and b/src/imgs/player-death19.png differ diff --git a/src/imgs/player-death2.png b/src/imgs/player-death2.png new file mode 100644 index 0000000..331823a Binary files /dev/null and b/src/imgs/player-death2.png differ diff --git a/src/imgs/player-death20.png b/src/imgs/player-death20.png new file mode 100644 index 0000000..a7ef1bf Binary files /dev/null and b/src/imgs/player-death20.png differ diff --git a/src/imgs/player-death21.png b/src/imgs/player-death21.png new file mode 100644 index 0000000..de40a1f Binary files /dev/null and b/src/imgs/player-death21.png differ diff --git a/src/imgs/player-death3.png b/src/imgs/player-death3.png new file mode 100644 index 0000000..e4f1dd8 Binary files /dev/null and b/src/imgs/player-death3.png differ diff --git a/src/imgs/player-death4.png b/src/imgs/player-death4.png new file mode 100644 index 0000000..0baed09 Binary files /dev/null and b/src/imgs/player-death4.png differ diff --git a/src/imgs/player-death5.png b/src/imgs/player-death5.png new file mode 100644 index 0000000..1314a54 Binary files /dev/null and b/src/imgs/player-death5.png differ diff --git a/src/imgs/player-death6.png b/src/imgs/player-death6.png new file mode 100644 index 0000000..953e02e Binary files /dev/null and b/src/imgs/player-death6.png differ diff --git a/src/imgs/player-death7.png b/src/imgs/player-death7.png new file mode 100644 index 0000000..f00315b Binary files /dev/null and b/src/imgs/player-death7.png differ diff --git a/src/imgs/player-death8.png b/src/imgs/player-death8.png new file mode 100644 index 0000000..810788f Binary files /dev/null and b/src/imgs/player-death8.png differ diff --git a/src/imgs/player-death9.png b/src/imgs/player-death9.png new file mode 100644 index 0000000..b6f4b05 Binary files /dev/null and b/src/imgs/player-death9.png differ diff --git a/src/imgs/small-death1.png b/src/imgs/small-death1.png new file mode 100644 index 0000000..696c925 Binary files /dev/null and b/src/imgs/small-death1.png differ diff --git a/src/imgs/small-death2.png b/src/imgs/small-death2.png new file mode 100644 index 0000000..35deb86 Binary files /dev/null and b/src/imgs/small-death2.png differ diff --git a/src/imgs/small-death3.png b/src/imgs/small-death3.png new file mode 100644 index 0000000..d507c25 Binary files /dev/null and b/src/imgs/small-death3.png differ diff --git a/src/imgs/small-death4.png b/src/imgs/small-death4.png new file mode 100644 index 0000000..7409df0 Binary files /dev/null and b/src/imgs/small-death4.png differ diff --git a/src/imgs/small-death5.png b/src/imgs/small-death5.png new file mode 100644 index 0000000..3586fae Binary files /dev/null and b/src/imgs/small-death5.png differ diff --git a/src/imgs/small-death6.png b/src/imgs/small-death6.png new file mode 100644 index 0000000..ff24364 Binary files /dev/null and b/src/imgs/small-death6.png differ -- cgit v1.3.1