Skip to content

In this application, pokemon trainers can compete against each other and start a battle in a real-time Pokemon arena.

Notifications You must be signed in to change notification settings

RooyyDoe/Poke-Fight

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Poké fight

In deze applicatie kunnen pokemon-trainers het tegen elkaar opnemen en een gevecht starten in een realtime Pokemon arena.

Het concept

In deze applicatie kunnen de gebruikers een Pokemon battle met elkaar beginnen. Wanneer een gebruiker in de lobby komt, moet er een Pokemon uitgekozen worden die aan hun zijde gaat vechten. Wanneer een pokemon aanvalt, zal de damage worden gebaseerd op de typering van de pokemons (zie Damage-chart) . De pokemon battle gaat door totdat een van de pokemons niet meer kan vechten, wat zal gebeuren wanneer de health bar nul bereikt. Na een gevecht krijgt de winnende gebruiker een victory scherm en worden beide spelers terug gestuurd naar het begin scherm.

Als de gebruiker zich aanmeldt om een pokemon trainer te worden, wordt die doorverwezen naar de geselecteerde lobby. Wanneer er twee gebruikers in de lobby zijn en ze aan de voorwaardes voldoen, is het mogelijk om een battle te starten.

Damage-chart

Hierbij ga ik voornamelijk gebruik maken van de eerste drie in deze lijst.

  • 2 super-effective Super Effective
  • 1 normal-damage Normal
  • 0.5 not-very-effective Not Very Effective
  • 0 no-effect No Effect

Pokemon-Lets-Go-Type-Chart

Schermafbeelding 2021-04-09 om 11 03 58

Battle simulation!!

ezgif-2-a817eab2a3cf

inhoudsopgave

Features

Dit zijn de verschillende features die ik wil gaan toevoegen aan mijn applicatie (MOSCOW)

[M] Must haves

deze eisen moeten in het eindresultaat terugkomen, zonder deze eisen is het product niet bruikbaar

  • Het kunnen starten van een Pokemon battle wanneer er twee gebruikers aanwezig zijn in een lobby.
  • Het kunnen uitvechten als twee pokemon trainers in een battle waar maar een iemand de winnaar kan zijn.
    • Het kunnen ophalen van health uit de Poké API.
    • Beurten systeem waar gebruikers elkaar om de beurt kunnen aanvallen en door middel van deze aanvallen gaat de Pokemon health naar beneden (player one starts).
  • Victory/defeat message naar beide spelers.

[S] Should haves

deze eisen zijn zeer gewenst, maar zonder is het product wel bruikbaar

  • Het kunnen inloggen als Pokemon-trainer.
    • Naam: Jouw eigen pokemon-trainer naam.
    • Gym: Dit zijn de verschillende lobbies die toegetreden kunnen worden.
    • Gender: De mogelijkheid om een vrouwelijke of mannelijke personage te kiezen.
  • Het kunnen zien van een gebruikers lijst van de huidige lobby.
  • Het kunnen zien van lobby notificaties.
    • Gebruikers krijgen een welkomst notificatie te zien als ze de lobby toetreden
    • Gebruikers krijgen een notificatie te zien wanneer er een gebruiker toetreedt of weggaat.
  • Het kunnen zoeken en kiezen van een Pokemon om mee te gaan strijden.
  • Het weergeven van een Pokemon gerelateerde huisstijl.
  • Het kunnen zien van game-messages tijdens de Pokemon battle.
  • Het kunnen zien van een visuele health-bar die gelinkt is aan de Pokemon health
  • Als een gebruiker de battle room verlaat, heeft de andere speler automatisch gewonnen.
  • Victory/Defeat pop-up nadat de battle over is.

[C] Could haves


deze eisen zullen alleen aan bod komen als er tijd genoeg is

  • Het battle Interface design laten lijken op de ouderwetse Pokemon battles.
  • Een limiet aan de lobbies toevoegen van twee spelers (Disable option when full)
  • Er kunnen meerdere battles tegelijkertijd plaats vinden.
  • Pokemon attacks worden gebasseerd op de typering van de Pokemons.
    • Super Effective (Water > Fire)
    • Normal (Water = Normal)
    • Not Very Effective (Fire < Water)
    • No Effect (Normal < Ghost)
  • Tijdens een Pokemon battle kunnen gebruikers eenmaal hun eigen Pokemon healen.
  • Tooltip die de gebruiker navigeert naar de search functionaliteit
  • Error bericht wanneer gebruiker foute input geeft tijdens het zoeken van een pokemon.

[C] Wont haves


deze eisen zullen alleen aan bod komen als er tijd genoeg is

Lobby

  • Het kunnen bewegen van jouw gekozen personage op de city map.
  • Punten systeem dat wordt bijgehouden in een scoreboard systeem.
  • Winkels maken waar gebruikers hun punten kunnen spenderen. (Heal/ATT_BOOST/DEF_BOOST items)
  • Wanneer gebruikers tegen elkaar aanlopen of op elkaar klikken opent er een menu.
    • Gebruikers kunnen een battle starten.
    • Gebruikers kunnen elkaar toevoegen als vrienden (Profile/friend system).
    • Gebruikers kunnen elkaars Pokemon zien.
    • Gebruikers kunnen in-game items met elkaar traden.
    • Gebruikers kunnen elkaars balance zien.
  • Mogelijkheid om tegen een AI gym te vechten om op deze manier punten te verdienen.

Battle

  • De gebruiker heeft de keuze uit vier Pokemon attacks die gerelateerd zijn aan de gekozen Pokemon.
  • Tijdens een Pokemon battle kan de gebruiker items gebruiken die hij/zij heeft gekocht.

Installatie

Clone de repository van het project

git clone https://github.com/RooyyDoe/real-time-web-1920.git

Navigeer naar de map

cd real-time-web-1920

Installeer dependencies

npm install

Run de server in je terminal

npm run dev

Server runt dan op: localhost:5000

Demo kun je ook bekijken op: Poké fight

Ultieme applicatie schetsen

Poké fight lobby

WhatsApp Image 2021-04-12 at 15 14 37

  • Iedere socket die de lobby joined, krijgt een persoonlijke personage die hij/zij kan voortbewegen. Dit zou gebeuren via de pijltjes of de WASD toesten.

    • Gebruikers zouden alleen kunnen lopen op gebieden waar dit mogelijk is en door tegen bepaalde elementen aan te lopen zou er een interactie ontstaan.
  • Wanneer gebruikers tegen elkaar aan lopen of op elkaar klikken komt er een selectie menu tevoorschijn. In dit menu staan verschillende interactie opties:

    • Battle now: Hier kunnen gebruikers elkaar uitdagen om een battle te starten
    • Add friend: Dit zou een systeem moeten zijn om elkaar toe te voegen in een vriendenlijst. Dit zou het dan makkelijk maken om elkaar weer uit te nodigen voor een rematch battle.
    • Show pokemon: Hier kan je de pokemon zien die deze gebruiker heeft gekozen.
    • Trade now: Een mogelijk trade systeem waar je items kan traden met elkaar voor bijvoorbeeld in-game money
    • Balance: ... Hier zie je hoeveel punten/geld de gebruiker heeft
    • Inventory: Deze is alleen zichtbaar wanneer je op je eigen personage klikt. Op deze manier kan je kijken wat voor items je in je inventory hebt zitten.
  • Het is mogelijk om met de punten die je verdient tijdens het vechten van battles items te kopen die je kan gebruiken tijdens een battle. Hierbij kan je denken aan een healing potion of een strength boost.

  • Om het wat makkelijker te maken voor gebruikers wil ik AI custom battles maken door middel van de interactie met de gym van de city. Wanneer een gebruiker naar de gym toeloopt kan hij/zij een battle starten en wanneer je deze wint verdien je muntjes waar je dus uiteindelijk items mee kan kopen of kan ruilen.

    Er zijn hoogst waarschijnlijk genoeg develop functionaliteiten waar ik rekening mee moet houden. Zelf heb ik zitten denken aan functionaliteiten zoals: localStorage, Iets wat een live positie kan bijhouden, Punten systeem, Interactie met elkaar, Anti cheat ( timers op AI custom battles, etc )

Poké fight battle

WhatsApp Image 2021-04-12 at 15 14 37 (1)

  1. Wanneer de gebruiker op de attack button klikt veranderen de vier menu items naar vier verschillende aanvallen van jou geselecteerde pokemon. Deze aanvallen hebben een max aantal selecties, zodat je ze niet kan spammen. Elke aanval heeft zijn eigen damage en zal meer damage doen als het tegen een zwakker type is.
  2. Tijdens een battle kan je driemaal van items gebruik maken. Dit kan een boost voor je pokemon geven of hem/haar healen voor een bepaald percentage.
  3. Als je geen zin meer hebt in de battle kun je altijd leaven. Het geldt dan wel dat je automatisch hebt verloren en de punten dus naar de tegenstander gaan.
  4. Hier wordt er feedback gegeven aan de gebruiker door kleine pop-ups die vertellen wat er allemaal gedaan kan worden.
  5. Hier komen de feedback messages binnen die er komen tijdens een battle. Ook staat hier precies in wat er gaat gebeuren of moet gebeuren.
  6. Het algemene battle screen. Hier komen twee pokemons tegenover elkaar te staan die het tegen elkaar gaan opnemen. Vanuit je eigen view zal je altijd onder aan staan en is het rechter HP element van jou. Je zal zien wanneer er HP af gaat bij je pokemon en ook wanneer er HP afgaat bij de tegenstander.

Data lifecycle diagram

data-lifecycle-diagram-roy

Socket server events

on-join server events

notification

Elke keer wanneer een gebruiker de kamer toetreedt, zal hij een welkomst bericht krijgen. Als een nieuwe gebruiker zijn lobby toetreedt, komt hier een notificatie van. Deze notificatie is ook zichtbaar wanneer er een gebruiker de lobby verlaat.

gym-users

Met dit event wordt er een array doorgestuurd met hierin een lijst van gebruikers die in een bepaalde gym zijn toegetreden. Deze array wordt uitgelezen en weergegeven op het scherm van de gebruikers. De gebruikers zullen in de lobby een lijst zien met zichzelf en de tegenstander waar hij/zij tegen moet spelen.

lobby server events

return-search-results

Nadat alle API calls zijn gedaan, wordt de benodigde data naar de client gestuurd. In de API calls wordt een object gemaakt waar alle nodige informatie instaat over de gekozen pokemon. Door deze door te sturen naar de client kan alle data worden toegevoegd aan elementen in het lobby/battle scherm.

battle-start

Wanneer beide gebruikers op de start knop hebben gedrukt, begint de battle. De lobby layout verandert naar de battle room layout en alle elementen die nodig zijn voor de battle worden ingeladen. Hiermee moet je dus denken aan de health-bar, Pokemon naam, Pokemon image en battle-messages / attack-button

on-battle server events

health-checker

Elke keer wanneer er een aanval is geweest, wordt de nieuwe health doorgestuurd naar de client en hier geupdate. Op deze manier ziet de gebruiker precies hoeveel damage hij heeft aangericht bij zijn tegenstander.

turn-checker

In een pokemon battle moet je natuurlijk om de beurt kunnen aanvallen en dit event zorgt hiervoor. Hij checkt elke keer wanneer er een aanval is geweest welke speler er nu aan de beurt is. Dit doe ik door middel van een turn_player1 boolean. Deze houdt bij wanneer speler 1 aan de beurt is en op deze manier geeft die dit door aan de client-side

game-over

Wanneer een van de Pokemons op 0 health komt te staan heeft deze speler verloren. Dit wordt in elke aanval gecheckt en wanneer de if statement op true komt te staan geeft die een victory/defeat scherm door aan de winnaar en verliezer.

leave-lobby

Wanneer een gebruiker de applicatie verlaat wordt hij/zij uit de user-list verwijderd. Ook wordt de leave message afgevuurd waardoor de andere spelers hier een notificatie over krijgen.

leave-buster

Deze socket houd bij hoeveel gebruikers er in de lobby zitten tijdens de battle. Wanneer een gebruiker de battle verlaat zonder hem af te maken zal de andere speler een victory scherm te zien krijgen.

Socket client listeners

on-join client events

join-lobby

Als de gebruikers de benodigde gegevens hebben ingevuld op het inlog scherm en de lobby toetreden, wordt de ingevulde informatie direct doorgestuurd naar de server-side. De gebruikers informatie wordt bijgehouden in een user-array. Op deze manier houd ik bij hoeveel gebruikers er aanwezig zijn en in welke lobby ze zitten.

lobby client events

search-results

De gebruikers kunnen hun Pokemon uitkiezen door deze op te zoeken in de search-bar. Wanneer ze de Pokemon naam hebben geschreven in de search-bar en daarna op de knop hebben gedrukt, wordt de input waarde naar de server-side gestuurd.

join-battle

Wanneer de gebruikers op de start-battle knop drukken begint de battle en verandert het lobby scherm naar het battle scherm. Alle data verkregen vanaf de server-side wordt in elementen geladen, zodat de gebruikers een bruikbare interface krijgen.

on-battle client events

on-attack

Elke keer wanneer een gebruiker op de attack knop drukt, wordt er een event gestuurd naar de server-side. Hier worden alle functionaliteiten zoals de health-checker en turn-checker afgehandeld.

on-heal

Elke keer wanneer een gebruiker op de heal knop drukt, wordt er een event gestuurd naar de server-side. Hier worden alle functionaliteiten zoals de health-checker en turn-checker afgehandeld.

The RESTful Pokémon API

Dit is een RESTful API die zeer gedetailleerde objecten teruggeeft die opgebouwd zijn uit duizenden regels. De informatie uit deze API is volledig gerelateerd aan Pokémon en alles wat hierbij komt kijken. Om deze API te gebruiken heb je geen authenticatie nodig en alle bronnen zijn volledig open en beschikbaar.

Welke data kan je uit deze API verkrijgen?
  • Moves
  • Abilities
  • Pokémon (Including various forms)
  • Types
  • Game versions
  • Items
  • Pokédexes
  • Pokémon Evolution Chains

API call naar (endpoint) zonder resource ID of name

Wanneer je de API aanroept zonder een ID of naam mee te geven, krijg je het object hier beneden terug. Hier maken ze gebruik van pagination en je krijgt 20 resultaten per API aanroep. Als je het limiet van de resultaten wil vergroten, kan je een query parameter mee geven om op deze manier meer resultaten terug te krijgen.

{
  "count": 248,
  "next": "https://pokeapi.co/api/v2/ability/?limit=20&offset=20",
  "previous": null,
  "results": [
    {
      "name": "stench",
      "url": "https://pokeapi.co/api/v2/ability/1/"
    }
  ]
}

De API calls die ik nodig had

In eerste instantie heb ik de API (endpoint) nodig die één specifieke pokemon ophaalt doordat de gebruiker een search uitvoert. Als deze API call is gedaan kijk ik naar de typering die de pokémon heeft en doe met deze informatie nogmaals een API call om de damage_relations te verkrijgen uit de poké API.


GET https://pokeapi.co/api/v2/pokemon/{id or name}/  // For the pokemon data

GET https://pokeapi.co/api/v2/type/{id or name}/    // For the damage_relations data

RAW Json Pokémon API call
{
"id": 12,
"name": "butterfree",
"base_experience": 178,
"height": 11,
"is_default": true,
"order": 16,
"weight": 320,
"abilities": [
  {
    "is_hidden": true,
    "slot": 3,
    "ability": {
      "name": "tinted-lens",
      "url": "https://pokeapi.co/api/v2/ability/110/"
    }
  }
],
"forms": [
  {
    "name": "butterfree",
    "url": "https://pokeapi.co/api/v2/pokemon-form/12/"
  }
],
"game_indices": [
  {
    "game_index": 12,
    "version": {
      "name": "white-2",
      "url": "https://pokeapi.co/api/v2/version/22/"
    }
  }
],
"held_items": [
  {
    "item": {
      "name": "silver-powder",
      "url": "https://pokeapi.co/api/v2/item/199/"
    },
    "version_details": [
      {
        "rarity": 5,
        "version": {
          "name": "y",
          "url": "https://pokeapi.co/api/v2/version/24/"
        }
      }
    ]
  }
],
"location_area_encounters": "https://pokeapi.co/api/v2/pokemon/12/encounters",
"moves": [
  {
    "move": {
      "name": "flash",
      "url": "https://pokeapi.co/api/v2/move/148/"
    },
    "version_group_details": [
      {
        "level_learned_at": 0,
        "version_group": {
          "name": "x-y",
          "url": "https://pokeapi.co/api/v2/version-group/15/"
        },
        "move_learn_method": {
          "name": "machine",
          "url": "https://pokeapi.co/api/v2/move-learn-method/4/"
        }
      }
    ]
  }
],
"species": {
  "name": "butterfree",
  "url": "https://pokeapi.co/api/v2/pokemon-species/12/"
},
"sprites": {
  "back_female": "http://pokeapi.co/media/sprites/pokemon/back/female/12.png",
  "back_shiny_female": "http://pokeapi.co/media/sprites/pokemon/back/shiny/female/12.png",
  "back_default": "http://pokeapi.co/media/sprites/pokemon/back/12.png",
  "front_female": "http://pokeapi.co/media/sprites/pokemon/female/12.png",
  "front_shiny_female": "http://pokeapi.co/media/sprites/pokemon/shiny/female/12.png",
  "back_shiny": "http://pokeapi.co/media/sprites/pokemon/back/shiny/12.png",
  "front_default": "http://pokeapi.co/media/sprites/pokemon/12.png",
  "front_shiny": "http://pokeapi.co/media/sprites/pokemon/shiny/12.png",
  "other": {
    "dream_world": {},
    "official-artwork": {}
  },
  "versions": {
    "generation-i": {
      "red-blue": {},
      "yellow": {}
    },
    "generation-ii": {
      "crystal": {},
      "gold": {},
      "silver": {}
    },
    "generation-iii": {
      "emerald": {},
      "firered-leafgreen": {},
      "ruby-sapphire": {}
    },
    "generation-iv": {
      "diamond-pearl": {},
      "heartgold-soulsilver": {},
      "platinum": {}
    },
    "generation-v": {
      "black-white": {}
    },
    "generation-vi": {
      "omegaruby-alphasapphire": {},
      "x-y": {}
    },
    "generation-vii": {
      "icons": {},
      "ultra-sun-ultra-moon": {}
    },
    "generation-viii": {
      "icons": {}
    }
  }
},
"stats": [
  {
    "base_stat": 70,
    "effort": 0,
    "stat": {
      "name": "speed",
      "url": "https://pokeapi.co/api/v2/stat/6/"
    }
  }
],
"types": [
  {
    "slot": 2,
    "type": {
      "name": "flying",
      "url": "https://pokeapi.co/api/v2/type/3/"
    }
  }
]
}

Wat ik uiteindelijk nodig had voor mijn project was niet de volledige JSON. Daarom heb ik hiervoor een apart object gemaakt met hierin de benodigde informatie voor mijn applicatie.

Mijn Pokémon object

{
  name: **String**,
  sprites: {
    display: **String**,
    back: **String**,
    front: **String**,
  },
  health: **String**,
  in_health: **String**,
  type: **String**,
  weight: **String**,
}

Uiteindelijk wilde ik dat de damage_relations ook bij dit object kwamen om op deze manier te beïnvloeden welke types er meer of minder damage deden tegen elkaar.

Mijn uiteindelijke pokémon Object

{
  name: **String**,
  damage_relations: {
    double_damage_from: [ Array ],
    double_damage_to: [ Array ],
    half_damage_from: [ Array ],
    half_damage_to: [ Array ],
    no_damage_from: [ Array ],
    no_damage_to: [ Array ],
  }.
  sprites: {
    display: **String**,
    back: **String**,
    front: **String**,
  },
  health: **String**,
  in_health: **String**,
  type: **String**,
  weight: **String**,
}

Conclusie

Voordat ik aan dit vak was begonnen had ik een doel voor mijzelf gesteld. Dit doel was om een zo uitgebreid mogelijke real-time applicatie te bouwen. Vorig jaar is me dit niet gelukt en ik wilde mijzelf bewijzen dit jaar. Dit is mij zeker gelukt en ben hartstikke trots op het eind resultaat wat ik heb neer gezet. In eerste instantie wilde ik gewoon een pokemon battle maken waar twee speler tegen elkaar konden gaan spelen zonder teveel moeilijke functionaliteiten. Uiteindelijk is de applicatie toch een stuk groter geworden dan ik had verwacht en kwamen hier verschillende moeilijkheden bij kijken. Het bijhouden van player1 en player2 en alles wat hierbij kwam kijken vond ik lastig, maar deste meer tijd ik in het project had besteedt, lukte het me steeds beter. Ook het begrijpen van de sockets ging me steeds beter af, waardoor ik nog meer functionaliteiten kon toevoegen aan de applicatie.

De manier waarop de rubric is gemaakt vond ik erg lastig. Je wordt erg open gelaten in wat je kan doen en je moet eigenlijk zelf uitzoeken hoe je een hoger cijfer haalt dan een 5.5. Ik heb er natuurlijk zoveel mogelijk uitgehaald en heb geprobeerd wel degelijk meer te doen dan de basis van de rubric, maar toch weet ik nog steeds niet precies waar ik sta. Achteraf had ik hier misschien wat meer sturing in gehad.

al met al heb ik weer erg van dit vak genoten, ook al heb ik veel lastige momenten gehad waar ik echt niet meer wist hoe ik verder kon gaan. Door het volhouden en hulp vragen wanneer nodig heb ik het goed voor elkaar gekregen.

Bronnen

Credits

  • Thijs Spijker - Heeft me geholpen met een could have voor het lobby limiet en meer..
  • Isabella - Mijn Rubberduck en metale steun.

About

In this application, pokemon trainers can compete against each other and start a battle in a real-time Pokemon arena.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Handlebars 51.1%
  • JavaScript 31.4%
  • CSS 17.5%