[READ-ONLY] Mirror of https://github.com/flo-bit/shadow-shmup. Fun and casual top-down, roguelike shoot 'em up browsergame with shadow elements and colorful neon effects flo-bit.dev/shadow-shmup/
browsergame pixijs rapier2d roguelike shoot-em-up typescript webgame
0

Configure Feed

Select the types of activity you want to include in your feed.

commit

Florian (Jul 31, 2024, 11:44 AM +0200) 51b1124d ef8b9252

+342 -115
+1 -3
src/enemy.ts
··· 24 24 25 25 healthBar?: PIXI.Graphics; 26 26 27 - damage: number = 10; 28 - 29 27 speed: number = 500; 30 28 31 29 shape?: PIXI.Graphics; ··· 598 596 } 599 597 600 598 createEyes() { 601 - this.size = 500; 599 + this.size = 100; 602 600 this.color = 0x0284c7; 603 601 this.eyes = new PIXI.Container(); 604 602 this.enemyContainer.addChild(this.eyes);
+1 -1
src/item.ts
··· 150 150 let dist = Math.hypot(dx, dy); 151 151 152 152 // move towards player 153 - if (dist < 80) { 153 + if (dist < closestPlayer.coinMagnetRange) { 154 154 let speed = 0.4; 155 155 this.x += (dx / dist) * speed * deltaTime; 156 156 this.y += (dy / dist) * speed * deltaTime;
+5 -1
src/player.ts
··· 61 61 62 62 weapons: Weapon[] = []; 63 63 64 + shootingRange: number = 200; 65 + 66 + coinMagnetRange: number = 80; 67 + 64 68 constructor(game: Game, num: number) { 65 69 this.game = game; 66 70 this.num = num; ··· 260 264 this.rightEye.update(deltaTime, 1); 261 265 262 266 // get closest enemy 263 - const closestEnemy = this.game.enemyManager?.getClosestEnemy(this.position, 200); 267 + const closestEnemy = this.game.enemyManager?.getClosestEnemy(this.position, this.shootingRange); 264 268 265 269 if (closestEnemy) { 266 270 this.weapon.fire(this.position, closestEnemy.position);
+2 -109
src/upgrade-manager.ts
··· 1 1 import Game from './app'; 2 2 import { Item } from './item'; 3 - import Player from './player'; 4 - import { addUpgradeOption, Icon } from './upgrades'; 5 - import { BallWeapon } from './weapons/ball'; 3 + import { addUpgradeOption } from './upgrades'; 4 + import { allUpgrades, Upgrade } from './upgrades-player'; 6 5 7 - type Upgrade = { 8 - upgrade: (player: Player) => void; 9 - perk: string; 10 - perkValue: string; 11 - 12 - icon: Icon; 13 - color: string; 14 - upgraded?: boolean; 15 - 16 - price: number; 17 - description?: string; 18 - }; 19 - /* 20 - - weapon fire rate 21 - - weapon shooting distance 22 - 23 - - bullet speed 24 - - bullet damage 25 - - bullet piercing 26 - 27 - - movement speed 28 - - player health 29 - - items stay longer 30 - */ 31 - const allUpgrades: Upgrade[][] = [ 32 - [ 33 - { 34 - upgrade: (player: Player) => (player.health = player.maxHealth), 35 - perk: 'Restore Health to', 36 - perkValue: '100%', 37 - icon: 'health', 38 - color: 'text-amber-500', 39 - price: 1 40 - } 41 - ], 42 - [ 43 - { 44 - upgrade: (player: Player) => (player.maxHealth *= 2), 45 - perk: 'Max Health', 46 - perkValue: '+10%', 47 - icon: 'health', 48 - color: 'text-green-500', 49 - price: 10 50 - } 51 - ], 52 - [ 53 - { 54 - upgrade: (player: Player) => (player.weapon.fireRate *= 0.9), 55 - perk: 'Gun cooldown', 56 - perkValue: '-10%', 57 - icon: 'fireRate', 58 - color: 'text-blue-500', 59 - price: 10 60 - } 61 - ], 62 - [ 63 - { 64 - upgrade: (player: Player) => (player.weapon.piercing += 1), 65 - perk: 'Piercing', 66 - perkValue: '+1', 67 - icon: 'piercing', 68 - color: 'text-red-500', 69 - price: 20 70 - } 71 - ], 72 - [ 73 - { 74 - upgrade: (player: Player) => { 75 - player.weapons.push(new BallWeapon(player.game, player.color)); 76 - }, 77 - perk: 'Chainsaw', 78 - perkValue: 'New Weapon', 79 - icon: 'new', 80 - color: 'text-red-500', 81 - price: 100 82 - }, 83 - { 84 - upgrade: (player: Player) => { 85 - // find chainsaw weapon 86 - let chainsaw = player.weapons.find((w) => w instanceof BallWeapon); 87 - if (chainsaw) { 88 - chainsaw.speed *= 2; 89 - } 90 - }, 91 - perk: 'Chainsaw Speed', 92 - perkValue: '+100%', 93 - icon: 'new', 94 - color: 'text-red-500', 95 - price: 200 96 - }, 97 - { 98 - upgrade: (player: Player) => { 99 - // find chainsaw weapon 100 - let chainsaw = player.weapons.find((w) => w instanceof BallWeapon); 101 - if (chainsaw) { 102 - chainsaw.damage *= 2; 103 - } 104 - }, 105 - perk: 'Chainsaw Damage', 106 - perkValue: '+100%', 107 - icon: 'new', 108 - color: 'text-red-500', 109 - price: 400 110 - } 111 - ] 112 - ]; 113 6 114 7 export class UpgradeManager { 115 8 colors_classes = ['bg-sky-500', 'bg-pink-500', 'bg-emerald-500'];
+305
src/upgrades-player.ts
··· 1 + import Player from './player'; 2 + import { Icon } from './upgrades'; 3 + import { BallWeapon } from './weapons/ball'; 4 + import { Knife } from './weapons/knife'; 5 + 6 + export type Upgrade = { 7 + upgrade: (player: Player) => void; 8 + perk: string; 9 + perkValue: string; 10 + 11 + icon: Icon; 12 + color: string; 13 + upgraded?: boolean; 14 + 15 + price: number; 16 + description?: string; 17 + }; 18 + /* 19 + - weapon fire rate 20 + - weapon shooting distance 21 + 22 + - bullet speed 23 + - bullet damage 24 + - bullet piercing 25 + 26 + - movement speed 27 + - player health 28 + */ 29 + 30 + const movementUpgrade: Upgrade[] = [ 31 + { 32 + upgrade: (player: Player) => (player.speed *= 1.2), 33 + perk: 'Movement speed', 34 + perkValue: '+20%', 35 + icon: 'movement', 36 + color: 'text-blue-500', 37 + price: 10 38 + }, 39 + { 40 + upgrade: (player: Player) => (player.speed *= 1.2), 41 + perk: 'Movement speed', 42 + perkValue: '+20%', 43 + icon: 'movement', 44 + color: 'text-blue-500', 45 + price: 10 46 + }, 47 + { 48 + upgrade: (player: Player) => (player.speed *= 1.2), 49 + perk: 'Movement speed', 50 + perkValue: '+20%', 51 + icon: 'movement', 52 + color: 'text-blue-500', 53 + price: 10 54 + }, 55 + { 56 + upgrade: (player: Player) => (player.speed *= 1.2), 57 + perk: 'Movement speed', 58 + perkValue: '+20%', 59 + icon: 'movement', 60 + color: 'text-blue-500', 61 + price: 10 62 + } 63 + ]; 64 + 65 + const maxHealthUpgrade: Upgrade[] = [ 66 + { 67 + upgrade: (player: Player) => (player.maxHealth *= 1.2), 68 + perk: 'Max Health', 69 + perkValue: '+20%', 70 + icon: 'health', 71 + color: 'text-blue-500', 72 + price: 10 73 + }, 74 + { 75 + upgrade: (player: Player) => (player.maxHealth *= 1.2), 76 + perk: 'Max Health', 77 + perkValue: '+20%', 78 + icon: 'health', 79 + color: 'text-blue-500', 80 + price: 10 81 + }, 82 + { 83 + upgrade: (player: Player) => (player.maxHealth *= 1.2), 84 + perk: 'Max Health', 85 + perkValue: '+20%', 86 + icon: 'health', 87 + color: 'text-blue-500', 88 + price: 10 89 + }, 90 + { 91 + upgrade: (player: Player) => (player.maxHealth *= 1.2), 92 + perk: 'Max Health', 93 + perkValue: '+20%', 94 + icon: 'health', 95 + color: 'text-blue-500', 96 + price: 10 97 + } 98 + ]; 99 + 100 + const coinMagnetUpgrade: Upgrade[] = [ 101 + { 102 + upgrade: (player: Player) => (player.coinMagnetRange *= 1.2), 103 + perk: 'Coin Magnet Range', 104 + perkValue: '+20%', 105 + icon: 'coins', 106 + color: 'text-blue-500', 107 + price: 10 108 + }, 109 + { 110 + upgrade: (player: Player) => (player.coinMagnetRange *= 1.2), 111 + perk: 'Coin Magnet Range', 112 + perkValue: '+20%', 113 + icon: 'coins', 114 + color: 'text-blue-500', 115 + price: 10 116 + }, 117 + { 118 + upgrade: (player: Player) => (player.coinMagnetRange *= 1.2), 119 + perk: 'Coin Magnet Range', 120 + perkValue: '+20%', 121 + icon: 'coins', 122 + color: 'text-blue-500', 123 + price: 10 124 + }, 125 + { 126 + upgrade: (player: Player) => (player.coinMagnetRange *= 1.2), 127 + perk: 'Coin Magnet Range', 128 + perkValue: '+20%', 129 + icon: 'coins', 130 + color: 'text-blue-500', 131 + price: 10 132 + } 133 + ]; 134 + 135 + // const playerUpgrades: Upgrade[] = [ 136 + // { 137 + // upgrade: (player: Player) => (player.speed *= 1.2), 138 + // perk: 'Movement speed', 139 + // perkValue: '+20%', 140 + // icon: 'movement', 141 + // color: 'text-blue-500', 142 + // price: 10 143 + // }, 144 + // { 145 + // upgrade: (player: Player) => (player.maxHealth *= 1.2), 146 + // perk: 'Max Health', 147 + // perkValue: '+20%', 148 + // icon: 'health', 149 + // color: 'text-blue-500', 150 + // price: 10 151 + // }, 152 + // { 153 + // upgrade: (player: Player) => (player.coinMagnetRange *= 1.2), 154 + // perk: 'Coin Magnet Range', 155 + // perkValue: '+20%', 156 + // icon: 'coins', 157 + // color: 'text-blue-500', 158 + // price: 10 159 + // } 160 + // ]; 161 + 162 + const gunUpgrades: Upgrade[] = [ 163 + { 164 + upgrade: (player: Player) => (player.weapon.fireRate *= 0.66), 165 + perk: 'Fire rate', 166 + perkValue: '+50%', 167 + icon: 'fireRate', 168 + color: 'text-blue-500', 169 + price: 10 170 + }, 171 + { 172 + upgrade: (player: Player) => (player.weapon.damage *= 1.5), 173 + perk: 'Damage', 174 + perkValue: '+50%', 175 + icon: 'damage', 176 + color: 'text-blue-500', 177 + price: 10 178 + }, 179 + { 180 + upgrade: (player: Player) => (player.weapon.piercing += 1), 181 + perk: 'Piercing', 182 + perkValue: '+1', 183 + icon: 'piercing', 184 + color: 'text-blue-500', 185 + price: 20 186 + }, 187 + { 188 + upgrade: (player: Player) => (player.shootingRange *= 1.2), 189 + perk: 'Shooting distance', 190 + perkValue: '+20%', 191 + icon: 'shootingRange', 192 + color: 'text-blue-500', 193 + price: 20 194 + }, 195 + { 196 + upgrade: (player: Player) => (player.weapon.projectileSpeed *= 1.2), 197 + perk: 'Bullet speed', 198 + perkValue: '+20%', 199 + icon: 'bulletSpeed', 200 + color: 'text-blue-500', 201 + price: 20 202 + }, 203 + { 204 + upgrade: (player: Player) => (player.weapon.fireRate *= 0.75), 205 + perk: 'Fire rate', 206 + perkValue: '+33%', 207 + icon: 'fireRate', 208 + color: 'text-blue-500', 209 + price: 10 210 + }, 211 + { 212 + upgrade: (player: Player) => (player.weapon.damage *= 1.5), 213 + perk: 'Damage', 214 + perkValue: '+50%', 215 + icon: 'damage', 216 + color: 'text-blue-500', 217 + price: 20 218 + } 219 + ]; 220 + 221 + const chainsawUpgrades: Upgrade[] = [ 222 + { 223 + upgrade: (player: Player) => { 224 + player.weapons.push(new BallWeapon(player.game, player.color)); 225 + }, 226 + perk: 'Chainsaw', 227 + perkValue: 'New Weapon', 228 + icon: 'new', 229 + color: 'text-red-500', 230 + price: 10 231 + }, 232 + { 233 + upgrade: (player: Player) => { 234 + // find chainsaw weapon 235 + let chainsaw = player.weapons.find((w) => w instanceof BallWeapon); 236 + if (chainsaw) { 237 + chainsaw.speed *= 2; 238 + } 239 + }, 240 + perk: 'Chainsaw Speed', 241 + perkValue: '+100%', 242 + icon: 'new', 243 + color: 'text-red-500', 244 + price: 200 245 + }, 246 + { 247 + upgrade: (player: Player) => { 248 + // find chainsaw weapon 249 + let chainsaw = player.weapons.find((w) => w instanceof BallWeapon); 250 + if (chainsaw) { 251 + chainsaw.damage *= 2; 252 + } 253 + }, 254 + perk: 'Chainsaw Damage', 255 + perkValue: '+100%', 256 + icon: 'new', 257 + color: 'text-red-500', 258 + price: 400 259 + }, 260 + { 261 + upgrade: (player: Player) => { 262 + // find chainsaw weapon 263 + const chainsaw = new BallWeapon(player.game, player.color); 264 + chainsaw.distance = 100; 265 + player.weapons.push(chainsaw); 266 + }, 267 + perk: 'Chainsaw', 268 + perkValue: '+1', 269 + icon: 'new', 270 + color: 'text-red-500', 271 + price: 200 272 + } 273 + ]; 274 + 275 + const knifeUpgrades: Upgrade[] = [ 276 + { 277 + upgrade: (player: Player) => { 278 + player.weapons.push(new Knife(player.game, player.color)); 279 + }, 280 + perk: 'Knife', 281 + perkValue: 'New Weapon', 282 + icon: 'new', 283 + color: 'text-red-500', 284 + price: 10 285 + } 286 + ]; 287 + 288 + export const allUpgrades: Upgrade[][] = [ 289 + [ 290 + { 291 + upgrade: (player: Player) => (player.health = player.maxHealth), 292 + perk: 'Restore Health to', 293 + perkValue: '100%', 294 + icon: 'health', 295 + color: 'text-amber-500', 296 + price: 1 297 + } 298 + ], 299 + movementUpgrade, 300 + maxHealthUpgrade, 301 + coinMagnetUpgrade, 302 + gunUpgrades, 303 + chainsawUpgrades, 304 + knifeUpgrades 305 + ];
+5 -1
src/upgrades.ts
··· 7 7 | 'health' 8 8 | 'piercing' 9 9 | 'itemTime' 10 - | 'new'; 10 + | 'new' 11 + | 'coins'; 11 12 12 13 const icons: Record<Icon, string> = { 13 14 movement: `<svg ··· 124 125 </svg>`, 125 126 new: `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6"> 126 127 <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v6m3-3H9m12 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" /> 128 + </svg>`, 129 + coins: `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6"> 130 + <path stroke-linecap="round" stroke-linejoin="round" d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125" /> 127 131 </svg>` 128 132 }; 129 133
+23
src/wave.ts
··· 217 217 enemy.value *= 1.5; 218 218 if (enemy instanceof SphereEnemy) { 219 219 enemy.weapon.damage *= 1.5; 220 + enemy.burstNumber *= 1.5; 221 + if(enemy.weapon.lifetime) enemy.weapon.lifetime *= 1.5; 222 + } 223 + } 224 + }, 225 + { 226 + type: TriangleEnemy, 227 + spawnRate: 3, 228 + upgradeFunction: (enemy) => { 229 + enemy.value *= 1.5; 230 + enemy.speed *= 1.2; 231 + if (enemy instanceof TriangleEnemy) { 232 + enemy.projectile.damage *= 2; 233 + } 234 + } 235 + }, 236 + { 237 + type: PentagonEnemy, 238 + spawnRate: 3, 239 + upgradeFunction: (enemy) => { 240 + enemy.value *= 1.5; 241 + if (enemy instanceof PentagonEnemy) { 242 + enemy.weapon.damage *= 1.5; 220 243 } 221 244 } 222 245 }