Browse Source

reorganized music files; added the start of GameEnemyFormation

develop
Rob Colbert 2 years ago
parent
commit
2865dbba47
  1. 17
      README.md
  2. 0
      dist/assets/audio/music/blueberries.mp3
  3. 0
      dist/assets/audio/music/blueberries.ogg
  4. 0
      dist/assets/audio/music/blueberries.wav
  5. 0
      dist/assets/audio/music/cyber_pulse.ogg
  6. 0
      dist/assets/audio/music/underwater.mp3
  7. 0
      dist/assets/audio/music/underwater.ogg
  8. 0
      dist/assets/audio/music/underwater.wav
  9. 0
      dist/assets/audio/music/victory.mp3
  10. 0
      dist/assets/audio/music/victory.ogg
  11. 0
      dist/assets/audio/music/victory.wav
  12. BIN
      dist/assets/audio/sfx/pew-pew-pew.wav
  13. BIN
      dist/assets/audio/sfx/spawn.ogg
  14. 48
      dist/js/game-app.js
  15. 1
      dist/js/lib/game-enemies.js
  16. 11
      dist/js/lib/game-enemy-beardson.js
  17. 99
      dist/js/lib/game-enemy-formation.js

17
README.md

@ -65,4 +65,21 @@ export default class GameApp extends NiceGame {
*/
}
}
```
## License
```
Copyright © 2022 Rob Colbert @rob@nicecrew.digital
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```

0
dist/assets/audio/blueberries.mp3 → dist/assets/audio/music/blueberries.mp3

0
dist/assets/audio/blueberries.ogg → dist/assets/audio/music/blueberries.ogg

0
dist/assets/audio/blueberries.wav → dist/assets/audio/music/blueberries.wav

0
dist/assets/audio/cyber_pulse.ogg → dist/assets/audio/music/cyber_pulse.ogg

0
dist/assets/audio/underwater.mp3 → dist/assets/audio/music/underwater.mp3

0
dist/assets/audio/underwater.ogg → dist/assets/audio/music/underwater.ogg

0
dist/assets/audio/underwater.wav → dist/assets/audio/music/underwater.wav

0
dist/assets/audio/victory.mp3 → dist/assets/audio/music/victory.mp3

0
dist/assets/audio/victory.ogg → dist/assets/audio/music/victory.ogg

0
dist/assets/audio/victory.wav → dist/assets/audio/music/victory.wav

BIN
dist/assets/audio/sfx/pew-pew-pew.wav

Binary file not shown.

BIN
dist/assets/audio/sfx/spawn.ogg

Binary file not shown.

48
dist/js/game-app.js

@ -6,12 +6,15 @@
const DTP_COMPONENT_NAME = 'game-app';
import { NiceGame } from '/dtp-nice-game/nice-game.js';
import { NiceGame, NiceVector2d } from '/dtp-nice-game/nice-game.js';
import GameBackground from './lib/game-background.js';
import GameEggSimulator from './lib/game-egg-simulator.js';
import GamePlayer from './lib/game-player.js';
import GameEggSimulator from './lib/game-egg-simulator.js';
import GameEnemies from './lib/game-enemies.js';
import GameEnemyFormation from './lib/game-enemy-formation.js';
export default class GameApp extends NiceGame {
@ -40,7 +43,7 @@ export default class GameApp extends NiceGame {
this.input.addButton('moveRight', 'btn-move-right');
this.input.addButton('throwEgg', 'btn-throw-egg');
await this.audio.setMusicStream('/dist/assets/audio/cyber_pulse.ogg');
await this.audio.setMusicStream('/dist/assets/audio/music/underwater');
await this.loadGameAssets();
this.mode = 'menu';
@ -70,6 +73,7 @@ export default class GameApp extends NiceGame {
const NOW = new Date();
this.nextSpawnInterval = 1000 * 5;
this.nextSpawnTime = NOW.valueOf() + this.nextSpawnInterval;
this.formations = [ ];
}
onGameUpdate ( ) {
@ -118,37 +122,56 @@ export default class GameApp extends NiceGame {
}
this.oldWantsThrowEgg = wantsThrowEgg;
this.eggs.update();
this.enemies.update();
/*
* Update the enemies, then the eggs.
* Spawn an enemy from the groyper army at scheduled intervals.
*/
this.enemies.update();
if (NOW.valueOf() >= this.nextSpawnTime) {
this.nextSpawnTime += this.nextSpawnInterval;
this.enemies.spawnBeardson();
}
this.eggs.update();
/*
* Process any current formations
*/
for (const formation of this.formations) {
formation.update();
}
}
renderGame (ctx) {
this.background.draw(ctx, 0, 0);
this.enemies.render(ctx);
for (const formation of this.formations) {
formation.render(ctx);
}
this.eggs.render(ctx);
this.tex.render(ctx);
}
throwEgg ( ) {
const moveSpeed = 4 + (Math.random() * 2);
this.log.info('throwEgg', 'throwing egg');
this.eggs.throwEgg({
x: this.tex.position.x,
y: this.tex.position.y - 16,
}, moveSpeed);
this.eggs.throwEgg(new NiceVector2d(
this.tex.position.x,
this.tex.position.y - 16,
), moveSpeed);
this.audio.playSound('throw-egg-001');
}
spawnFormation ( ) {
const formation = new GameEnemyFormation(this, new NiceVector2d(480, 20));
formation.addTier(3);
formation.addTier(7);
}
async loadGameAssets ( ) {
const jobs = [ ];
@ -172,6 +195,7 @@ export default class GameApp extends NiceGame {
async loadAudio ( ) {
const jobs = [ ];
jobs.push(this.audio.loadSound('enemy-spawn', '/dist/assets/audio/sfx/spawn.ogg'));
jobs.push(this.audio.loadSound('throw-egg-001', '/dist/assets/audio/sfx/throw-egg-001.wav'));
jobs.push(this.audio.loadSound('impact-001', '/dist/assets/audio/sfx/impact-001.wav'));
@ -186,6 +210,8 @@ export default class GameApp extends NiceGame {
jobs.push(this.audio.loadSound('tex-biggerfish', '/dist/assets/audio/vox/tex-biggerfish.wav'));
jobs.push(this.audio.loadSound('tex-shutuptwo', '/dist/assets/audio/vox/tex-shutuptwo.wav'));
jobs.push(this.audio.loadSound('beardson-touchdown', '/dist/assets/audio/sfx/pew-pew-pew.wav'));
await Promise.all(jobs);
}
}

1
dist/js/lib/game-enemies.js

@ -83,6 +83,7 @@ export default class GameEnemies extends NiceSprite {
},
);
this.enemies.push(beardson);
this.game.audio.playSound('enemy-spawn');
}
getRandomSpawnPoint ( ) {

11
dist/js/lib/game-enemy-beardson.js

@ -22,11 +22,18 @@ export default class GameEnemyBeardson extends NiceSprite {
x: moveSpeed.x,
y: moveSpeed.y,
};
this.isDescending = true;
}
update ( ) {
if (this.position.y < 480) {
this.position.y += this.moveSpeed.y;
if (this.isDescending) {
if (this.position.y < 480) {
this.position.y += this.moveSpeed.y;
} else {
this.position.y = 480;
this.isDescending = false;
this.game.audio.playSound('beardson-touchdown');
}
}
if (Math.random() > 0.998) {

99
dist/js/lib/game-enemy-formation.js

@ -0,0 +1,99 @@
// lib/game-enemy-formation.js
// Copyright (C) 2022 Rob Colbert @[email protected]
// License: Apache-2.0
'use strict';
import NiceVector2d from '/dtp-nice-game/nice-vector-2d.js';
/**
* A formation is a collection of enemies with tiers, and enemies are
* added to the tiers. They then render as a "formation" in the view,
* and can "pop out" of formation to execute a "run" then arrive back to
* the formation.
*/
export default class GameEnemyFormation {
constructor (game, position) {
this.game = game;
this.position = position;
this.moveSpeed = 2;
this.tiers = [ ];
}
/**
*
* @param {*} tierHeight
* @returns
*/
addTier (tierHeight = 64) {
const idx = this.tiers.length;
this.tiers.push({ height: tierHeight, enemies: [ ] });
return idx;
}
/**
* Adds an enemy object to the specified tier at the specified position
* offset. This is where the enemy will reside while in formation.
* @param {Number} tierIndex the index of the tier to which the enemy should be
* added
* @param {NiceSprite} enemy The enemy to be added to the specified tier
* @param {NiceVector2d} offset The positional offset from the formation's origin at
* which the enemy should reside while in formation
* @returns the index of the enemy added within the tier
*/
addEnemyToTier (tierIndex, enemy, offset) {
const idx = this.tiers[tierIndex].enemies.length;
this.tiers[tierIndex].enemies.push({
enemy, offset,
isInFormation: true,
});
return idx;
}
update ( ) {
const MARGIN_RIGHT = 480 + 200;
const MARGIN_LEFT = 480 - 200;
/*
* Update the position of the formation itself
*/
this.position.x += this.moveSpeed;
if (this.position.x > MARGIN_RIGHT) {
this.moveSpeed = -this.moveSpeed;
this.position.x = MARGIN_RIGHT;
}
if (this.position.x < MARGIN_LEFT) {
this.moveSpeed = -this.moveSpeed;
this.position.x = MARGIN_LEFT;
}
/*
* Iterate every enemy in the formation, and update their position to where
* they should be if currently in-formation.
*/
for (const tier of this.tiers) {
for (const enemy of tier) {
if (!enemy.isInFormation) {
continue;
}
enemy.position.x = this.position.x + enemy.position.x;
enemy.position.y = this.position.y + enemy.position.y;
}
}
/*
* Randomly or as scheduled, execute an "attack run" by selecting some
* enemies from the required tiers (if availble), and then starting the
* attack behavior.
*/
}
render (ctx) {
for (const tier of this.tiers) {
for (const enemy of tier) {
enemy.render(ctx);
}
}
}
}
Loading…
Cancel
Save