4 changed files with 305 additions and 0 deletions
@ -0,0 +1,201 @@
@@ -0,0 +1,201 @@
|
||||
let Fight = { |
||||
data() { |
||||
return { |
||||
loaded: false, |
||||
action: null, |
||||
step: 'choose', |
||||
sounds: { |
||||
battle: null, |
||||
victory: null |
||||
}, |
||||
player: { |
||||
name: 'Ash', |
||||
team: [ |
||||
{ |
||||
species: 'Pikachu', |
||||
nickname: 'Pikachu', |
||||
status: null, |
||||
hp: 100, |
||||
hpLeft: 100, |
||||
level: 5, |
||||
sprites: { |
||||
idle: 'https://www.pokewiki.de/images/thumb/0/0a/Pok%C3%A9monsprite_025_SWSH.gif/128px-Pok%C3%A9monsprite_025_SWSH.gif', |
||||
back: 'https://www.pokewiki.de/images/thumb/7/7c/Pok%C3%A9monsprite_025_R%C3%BCckseite_Schillernd_LGPE.png/100px-Pok%C3%A9monsprite_025_R%C3%BCckseite_Schillernd_LGPE.png' |
||||
}, |
||||
moves: [ |
||||
{ |
||||
name: 'Tackle', |
||||
strength: 35, |
||||
types: ['normal'], |
||||
class: 'physical', |
||||
ap: 15 |
||||
} |
||||
] |
||||
} |
||||
] |
||||
}, |
||||
enemy: { |
||||
name: 'Gary', |
||||
team: [ |
||||
{ |
||||
species: 'Evoli', |
||||
nickname: 'Evoli', |
||||
status: null, |
||||
hp: 100, |
||||
hpLeft: 100, |
||||
level: 5, |
||||
sprites: { |
||||
idle: 'https://www.pokewiki.de/images/thumb/a/a5/Pok%C3%A9monsprite_133_SWSH.gif/128px-Pok%C3%A9monsprite_133_SWSH.gif', |
||||
back: '' |
||||
}, |
||||
moves: [ |
||||
{ |
||||
name: 'Tackle', |
||||
strength: 35, |
||||
types: ['normal'], |
||||
class: 'physical', |
||||
ap: 15 |
||||
} |
||||
] |
||||
} |
||||
] |
||||
} |
||||
} |
||||
}, |
||||
mounted() { |
||||
this.start(); |
||||
|
||||
this.sounds.battle = new Audio('snd/battle.mp3'); |
||||
this.sounds.victory = new Audio('snd/victory.mp3'); |
||||
}, |
||||
methods: { |
||||
start() { |
||||
this.player.currentFighter = this.player.team[0]; |
||||
this.enemy.currentFighter = this.enemy.team[0]; |
||||
this.loaded = true; |
||||
}, |
||||
playerAttack(move) { |
||||
if (this.sounds.battle.paused) { |
||||
this.sounds.battle.play(); |
||||
} |
||||
this.attack(move, this.player.currentFighter, this.enemy.currentFighter); |
||||
this.step = 'playerAttacked'; |
||||
this.action = 'message'; |
||||
this.currentMessage = this.player.currentFighter.nickname + ' setzt ' + move.name + ' ein!'; |
||||
}, |
||||
enemyAttack() { |
||||
if (this.enemy.currentFighter.hpLeft <= 0) { |
||||
this.currentMessage = this.enemy.currentFighter.nickname + ' wurde besiegt!' |
||||
this.action = 'message'; |
||||
this.step = 'enemyPokemonDefeated'; |
||||
} else { |
||||
let move = this.enemy.currentFighter.moves[Math.floor(Math.random() * this.enemy.currentFighter.moves.length)]; |
||||
this.attack(move, this.enemy.currentFighter, this.player.currentFighter); |
||||
this.action = 'message'; |
||||
|
||||
this.step = 'enemyAttacked'; |
||||
this.currentMessage = 'Enemy ' + this.enemy.currentFighter.nickname + ' setzt ' + move.name + ' ein!'; |
||||
} |
||||
}, |
||||
enemyPokemonDefeated() { |
||||
this.enemy.currentFighter.status = 'defeated'; |
||||
let nextFighter = this.getNextFighterFromTeam(this.enemy.team); |
||||
console.log(nextFighter); |
||||
if (!nextFighter) { |
||||
this.enemy.currentFighter = null; |
||||
this.step = 'playerWon'; |
||||
this.fightWon() |
||||
} else { |
||||
this.enemy.currentFighter = this.enemy.team[nextFighter]; |
||||
} |
||||
}, |
||||
// playerPokemonDefeated() {
|
||||
// this.player.currentFighter.status = 'defeated';
|
||||
// let nextFighter = this.getNextFighterFromTeam(this.player.team);
|
||||
//
|
||||
// if (!nextFighter) {
|
||||
// this.step = 'playerWon';
|
||||
// this.currentMessage = this.enemy.name + ' wurde besiegt!';
|
||||
// } else {
|
||||
// alert('lol');
|
||||
// this.enemy.currentFighter = this.enemy.team[nextFighter];
|
||||
// }
|
||||
// },
|
||||
getNextFighterFromTeam(team) { |
||||
let nextFighterIndex = false; |
||||
team.forEach((member, teamPosition) => { |
||||
if (member.status !== 'defeated') { |
||||
nextFighterIndex = teamPosition; |
||||
} |
||||
}) |
||||
|
||||
return nextFighterIndex; |
||||
}, |
||||
attack(move, attacker, enemy) { |
||||
let newHpLeft = enemy.hpLeft - this.calculateDamageForAttack(move.strength, attacker.level); |
||||
enemy.hpLeft = newHpLeft; |
||||
}, |
||||
calculateDamageForAttack(strength, level) { |
||||
return strength / 10 * level; |
||||
}, |
||||
getLeftHpPercent(character) { |
||||
return character.currentFighter.hpLeft / 100 * character.currentFighter.hp; |
||||
}, |
||||
getColorForHealthBar(percent) { |
||||
if (percent > 52) { |
||||
return 'success'; |
||||
} |
||||
|
||||
if (percent > 17) { |
||||
return 'warning' |
||||
} |
||||
|
||||
return 'danger'; |
||||
}, |
||||
fightWon() { |
||||
this.sounds.battle.pause(); |
||||
this.sounds.victory.play(); |
||||
this.currentMessage = this.enemy.name + ' wurde besiegt!'; |
||||
}, |
||||
fightLost() { |
||||
|
||||
}, |
||||
continueRound() { |
||||
switch (this.step) { |
||||
case 'playerAttacked': |
||||
this.enemyAttack(); |
||||
break; |
||||
case 'enemyAttacked': |
||||
this.action = null; |
||||
break; |
||||
case 'enemyPokemonDefeated': |
||||
this.enemyPokemonDefeated(); |
||||
this.currentMessage = this.enemy.name + ' wurde besiegt!'; |
||||
break; |
||||
case 'playerPokemonDefeated': |
||||
// this.fightWon();
|
||||
break; |
||||
case 'playerWon': |
||||
this.fightWon(); |
||||
break; |
||||
case 'enemyWon': |
||||
this.fightLost(); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
this.$forceUpdate(); |
||||
} |
||||
}, |
||||
watch: { |
||||
step() { |
||||
console.log(this.step); |
||||
}, |
||||
action() { |
||||
console.log(this.action); |
||||
} |
||||
} |
||||
} |
||||
|
||||
Vue.createApp(Fight).mount('#fight'); |
@ -0,0 +1,104 @@
@@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="utf-8"> |
||||
<title>Fight</title> |
||||
<link rel="stylesheet" href="https://bootswatch.com/5/zephyr/bootstrap.min.css"> |
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no" name="viewport"> |
||||
<style> |
||||
body { |
||||
background-color: #8ab638; |
||||
} |
||||
|
||||
.container { |
||||
margin-top: 1em; |
||||
} |
||||
|
||||
.player-row, .menu { |
||||
margin-top: 3em; |
||||
} |
||||
|
||||
.player-pokemon { |
||||
-webkit-transform: scaleX(-1); |
||||
transform: scaleX(-1); |
||||
} |
||||
|
||||
.spacer-for-loser { |
||||
min-height: 5em; |
||||
} |
||||
</style> |
||||
</head> |
||||
<body> |
||||
<div id="fight"> |
||||
<div v-if="loaded" class="container"> |
||||
<div class="row" v-if="enemy.currentFighter"> |
||||
<div class="col-6"> |
||||
<div class="card"> |
||||
<div class="card-body"> |
||||
{{ enemy.currentFighter.nickname }} |
||||
<span class="float float-end"> |
||||
Lvl {{ enemy.currentFighter.level }} |
||||
</span> |
||||
<div class="progress"> |
||||
<div :class="'progress-bar bg-' + getColorForHealthBar(getLeftHpPercent(enemy))" role="progressbar" :style="'width: ' + getLeftHpPercent(enemy) + '%;'" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="col-6"> |
||||
<img :src="enemy.currentFighter.sprites.idle" alt="" class="float-end"> |
||||
</div> |
||||
</div> |
||||
<div class="row" class="spacer-for-loser" v-else> |
||||
|
||||
</div> |
||||
<div class="row player-row" v-if="player.currentFighter"> |
||||
<div class="col-6"> |
||||
<img :src="player.currentFighter.sprites.idle" alt="" class="player-pokemon"> |
||||
</div> |
||||
<div class="col-6"> |
||||
<div class="card"> |
||||
<div class="card-body"> |
||||
{{ player.currentFighter.nickname }} |
||||
<span class="float float-end"> |
||||
Lvl {{ player.currentFighter.level }} |
||||
</span> |
||||
<div class="progress"> |
||||
<div :class="'progress-bar bg-' + getColorForHealthBar(getLeftHpPercent(player))" role="progressbar" :style="'width: ' + getLeftHpPercent(player) + '%;'" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="row menu"> |
||||
<div class="card"> |
||||
<div class="card-body row"> |
||||
<div class="col-8" v-if="action !== 'message'"> |
||||
<div class="row" v-if="action === 'chooseAttack'"> |
||||
<div class="col-6 btn btn-light" v-for="move in player.currentFighter.moves" @click="playerAttack(move)"> |
||||
{{ move.name }} |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="col-4" v-if="action !== 'message'"> |
||||
<div class="row" v-if="action !== 'message'"> |
||||
<a href="javascript:" @click="action = 'chooseAttack'" v-if="!action" class="col-12 btn btn-dark">Angriff</a> |
||||
<a href="javascript:" @click="action = null" v-if="action" class="col-12 btn btn-dark">Zurück</a> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="row" v-else> |
||||
<div class="col-12 btn btn-light" @click="continueRound()"> |
||||
{{ currentMessage }} |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<script src="https://unpkg.com/vue@next"></script> |
||||
<script src="fight.js"></script> |
||||
</body> |
||||
</html> |
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue