├── .gitignore ├── README.md ├── favicon.ico ├── fonts ├── pokemon-italic.woff ├── pokemon-italic.woff2 ├── pokemon-normal.woff └── pokemon-normal.woff2 ├── img ├── ball_empty.svg ├── ball_full.svg ├── blue_balls.svg ├── blue_front.svg ├── blue_line.svg ├── eevee_back.svg ├── eevee_front.svg ├── frame.svg ├── hp.svg ├── level.svg ├── marker.svg ├── pikachu_back.svg ├── pikachu_front.svg ├── pokemon.svg ├── red_back.svg ├── red_balls.svg ├── red_front.svg └── red_line.svg ├── index.html ├── main.css ├── pokemon-min.js ├── sfx ├── battle.mp3 ├── eevee.mp3 ├── pikachu.mp3 └── victory.mp3 └── src ├── Pokemon Sketch Source.sketch ├── index.haml ├── main.sass ├── pokemon.js ├── promo.png ├── screenshot_1998.png ├── screenshot_2014.png └── screenshot_2016.png /.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache 2 | .DS_Store 3 | config.codekit3 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pokemon-js 2 | #### Classic Pokémon Yellow battles built for the web 3 | ![Screenshot](/src/screenshot_2016.png?raw=true "Screenshot 2016") 4 | 5 | #### Demo 6 | 7 | 8 | #### About 9 | A clone of the very first battle in the first generation of Pokémon GAMEBOY games by Game Freak published by Nintendo. 10 | 11 | It started in 2013 as a way of refining web technology skills for Pascal Pixel and now Superpencil, then evolved to include (originally, perhaps not in the current iteration) `PHP`, `GET` requests, `jQuery`, `JSON` to dynamically call specific monsters from an index (Pokédex), `API` usage, `SVG`, dynamic SVG coloring, CSS 3D `transforms`, responsive interfaces based on `em` units, and full mastery of `SASS` and `SCSS`. 12 | 13 | We plan to move the project into React & Redux next to get a hold on those new technologies as well. 14 | 15 | #### Authors 16 | [Pascal Pixel](http://github.com/Superpencil) 17 | 18 | #### To-do 19 | - Re-implement JSON Pokedex to call different teams 20 | - Implement moves 21 | - Implement real stats 22 | - Implement different trainers 23 | - Remove MissingNo bug 24 | - Convert to React/Redux 25 | - Make multiplayer 26 | 27 | #### Clones & Forks 28 | If you use this code please mention and link to the original repository. 29 | 30 | If you make improvements, please issue a pull request, we're very happy to have your involvement and look forward to learn from your code. 31 | 32 | 33 | 34 | #### Disclaimer 35 | Pokémon and Pikachu are trademarks of The Pokémon Company International, this is an internal project used to study new web technologies, it is free to use. 36 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/favicon.ico -------------------------------------------------------------------------------- /fonts/pokemon-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/fonts/pokemon-italic.woff -------------------------------------------------------------------------------- /fonts/pokemon-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/fonts/pokemon-italic.woff2 -------------------------------------------------------------------------------- /fonts/pokemon-normal.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/fonts/pokemon-normal.woff -------------------------------------------------------------------------------- /fonts/pokemon-normal.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/fonts/pokemon-normal.woff2 -------------------------------------------------------------------------------- /img/ball_empty.svg: -------------------------------------------------------------------------------- 1 | ball_empty 2 | -------------------------------------------------------------------------------- /img/ball_full.svg: -------------------------------------------------------------------------------- 1 | ball_full 2 | -------------------------------------------------------------------------------- /img/blue_balls.svg: -------------------------------------------------------------------------------- 1 | blue_balls 2 | -------------------------------------------------------------------------------- /img/blue_front.svg: -------------------------------------------------------------------------------- 1 | blue_front 2 | -------------------------------------------------------------------------------- /img/blue_line.svg: -------------------------------------------------------------------------------- 1 | blue_line 2 | -------------------------------------------------------------------------------- /img/eevee_back.svg: -------------------------------------------------------------------------------- 1 | eevee_back 2 | -------------------------------------------------------------------------------- /img/eevee_front.svg: -------------------------------------------------------------------------------- 1 | eevee_front 2 | -------------------------------------------------------------------------------- /img/frame.svg: -------------------------------------------------------------------------------- 1 | frame 2 | -------------------------------------------------------------------------------- /img/hp.svg: -------------------------------------------------------------------------------- 1 | hp 2 | -------------------------------------------------------------------------------- /img/level.svg: -------------------------------------------------------------------------------- 1 | level 2 | -------------------------------------------------------------------------------- /img/marker.svg: -------------------------------------------------------------------------------- 1 | marker 2 | -------------------------------------------------------------------------------- /img/pikachu_back.svg: -------------------------------------------------------------------------------- 1 | pikachu_back 2 | -------------------------------------------------------------------------------- /img/pikachu_front.svg: -------------------------------------------------------------------------------- 1 | pikachu_front 2 | -------------------------------------------------------------------------------- /img/pokemon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pokemon-js 5 | Created with Sketch. 6 | 7 | 8 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /img/red_back.svg: -------------------------------------------------------------------------------- 1 | red_back 2 | -------------------------------------------------------------------------------- /img/red_balls.svg: -------------------------------------------------------------------------------- 1 | red_balls 2 | -------------------------------------------------------------------------------- /img/red_front.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | red_front 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /img/red_line.svg: -------------------------------------------------------------------------------- 1 | red_line 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | pokemon-js by Superpencil 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 |
17 |
18 | 19 |
20 |
21 |
22 |
23 | 24 | 25 |
26 |
27 | 28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | 37 |
38 |
39 | 40 |
41 |
42 |
43 |
44 |
45 |
46 | 47 |
48 |
49 | 50 |
51 |
52 |
53 |
54 | 55 |
56 |
57 |
58 |
59 | 60 | 61 |
62 |
63 | 64 |
65 |
66 |
67 |
68 |
69 | 70 | / 71 | 72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | 92 |
93 |
94 |
95 |
96 |
cancel
97 |
98 | TYPE/ 99 | NORMAL 100 |
101 |
102 |
103 |
104 | POTION x 105 | 1 106 |
107 |
cancel
108 |
109 |
110 |
111 | 112 |
113 |
cancel
114 |
115 |
116 |
117 |
118 |
119 |

120 | pokemon-js by Superpencil 121 |

122 |
123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /main.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:'Pokemon';src:url("fonts/pokemon-normal.woff2") format("woff2"),url("fonts/pokemon-normal.woff") format("woff");font-weight:400;font-style:normal}@font-face{font-family:'Pokemon';src:url("fonts/pokemon-italic.woff2") format("woff2"),url("fonts/pokemon-italic.woff") format("woff");font-weight:400;font-style:italic}body{background-color:#bbac58;color:#2f3622;font-family:'Pokemon', monospace;font-size:20px;margin:0;padding:0;line-height:1.3em}a{color:#FCE600;text-decoration:none}h1,h2,h3,h4,h5,h6{color:#7d7f4c}::-moz-selection{background:#4d5d31;color:#bbac58}::selection{background:#4d5d31;color:#bbac58}button{background:#bbac58;color:#4d5d31;border:1px solid #4d5d31;border-radius:0.3em;padding:0.4em 0.8em 0.5em;cursor:pointer}button.active{background:#4d5d31;color:#bbac58}.gb-dark{fill:#2f3622}.gb-normal{fill:#4d5d31}.gb-light{fill:#7d7f4c}.text-area{margin:0 auto;font-size:0.5em;width:32em;line-height:1.6em}#pokemon{width:16.0em;height:14.4em;position:relative;margin:0 auto;-webkit-transform:translateZ(0em) translateY(0em) translateX(0em) rotateX(0deg) rotateY(0deg);transform:translateZ(0em) translateY(0em) translateX(0em) rotateX(0deg) rotateY(0deg)}.button:hover{cursor:pointer;position:relative}.button:hover:before{position:absolute;background-image:url("img/marker.svg");background-repeat:no-repeat;left:-1em;top:0.1em;width:0.5em;height:0.7em;background-size:0.5em;content:""}img,svg{width:100%;height:auto}span,.button,.level,.name{font-size:0.8em}span span,.button span,.level span,.name span{font-size:1em}.layer{position:absolute;width:16.0em;height:14.4em;overflow:hidden}.images{position:absolute;width:5.6em}.info{position:absolute;width:7.7em}.name{height:1.1em}.balls{margin-top:1.6em}.stats{background-position:bottom;background-size:7.7em;background-repeat:no-repeat}.level-wrap{margin-top:-0.1em;height:0.8em}.level-wrap img,.level-wrap svg{width:0.6em;display:inline-block;margin-right:-0.8em}.health{margin-left:2.5em}.health span{display:inline-block;width:0.8em}.hp-wrap{height:0.9em}.hp-wrap img,.hp-wrap svg{width:1.1em;display:inline-block}.hp-bar{border:0.1em solid #2f3622;border-radius:0.4em;height:0.3em;width:4.8em;display:inline-block;margin-left:-0.7em;display:inline-block}.hp-bar-active{background-color:#7d7f4c;height:100%;width:100%;border-radius:0.4em}.foe .images{right:0.8em}.foe .info{left:1.1em}.foe .stats{height:3em;background-image:url("img/blue_line.svg")}.foe .name{margin-left:-0.3em;margin-top:-0.1em}.foe .level-wrap{margin-left:2.2em}.foe .hp-wrap{margin-left:0.6em}.player{padding-top:4em}.player .images{left:0.8em}.player .info{right:1.1em}.player .stats{background-image:url("img/red_line.svg")}.player .name{margin-left:1em;margin-top:1.8em}.player .level-wrap{margin-left:4.1em}.player .hp-wrap{margin-left:0.9em}.player .balls{margin-top:4em}.windows .window{position:absolute;-o-border-image:url("img/frame.svg") 45% stretch;border-image:url("img/frame.svg") 45% stretch;border-style:solid;border-width:0.7em;background:#bbac58}.windows .window.texts{margin:0;height:3.2em;left:0.1em;right:0.1em;bottom:0.1em}.windows .window.texts .text span{height:1em;width:1em;display:inline-block}.windows .window.texts .text.text1{margin-top:0.5em}.windows .window.texts .text.text2{margin-top:0.1em}.windows .window.menu{display:none;bottom:0.1em;right:0.1em;height:2.7em;width:7.4em;padding:0.5em 0 0 0.8em}.windows .window.menu sup,.windows .window.menu sub{display:inline-block;margin-right:-1.3em;font-size:0.7em;margin-left:-0.4em}.windows .window.fight{display:none;bottom:0.1em;right:0.1em;left:3.3em;min-height:4.6em;padding:0.5em 0 0 0.8em}.windows .window.fight .fight-details{top:-3.9em;left:-3.9em;width:6.6em;height:2.4em}.windows .window.fight .fight-details span{height:0.8em;margin-top:-0.3em}.windows .window.item{display:none;top:1.7em;bottom:4.1em;left:3.3em;right:0.1em;padding:0.6em}.windows .window.pkmn{display:none;top:0.1em;bottom:0.1em;left:0.1em;right:0.1em}.perspective{-webkit-perspective:30em;perspective:30em;-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.perspective .depth{-webkit-transform:rotateX(0deg) rotateY(0deg);transform:rotateX(0deg) rotateY(0deg);-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.perspective .foe{-webkit-transform:translateZ(-8em);transform:translateZ(-8em);-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.perspective .player{-webkit-transform:translateZ(-4em);transform:translateZ(-4em);-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.perspective .windows{-webkit-transform:translateZ(0em);transform:translateZ(0em);-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.perspective .window.menu{-webkit-transform:translateZ(4em);transform:translateZ(4em);-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.perspective .window.fight,.perspective .window.item,.perspective .window.pkmn{-webkit-transform:translateZ(8em);transform:translateZ(8em);-webkit-transform-style:preserve-3d;transform-style:preserve-3d} 2 | -------------------------------------------------------------------------------- /pokemon-min.js: -------------------------------------------------------------------------------- 1 | "use strict";$(document).ready(function(){$(".three-dee").click(function(){$("#pokemon").toggleClass("perspective"),$("button").toggleClass("active"),$(".depth").removeAttr("style")});var t=function t(e){var i=$("#pokemon").offset(),o=$("#pokemon").width(),n=$("#pokemon").height(),a=.15*(100-(e.pageX-i.left)/o*100-50),s=.15*((e.pageY-i.top)/n*100-50),m="rotateX("+s+"deg) rotateY("+a+"deg)";$(".depth").css({"-webkit-transform":m,"-moz-transform":m,"-ms-transform":m,"-o-transform":m,transform:m})},e=void 0;$("#pokemon").mousemove(function(i){$(this).hasClass("perspective")&&e&&(t(i),e=!1)}),window.setInterval(function(){e=!0},20);var i="Red",o=5,n={name:"Pikachu",hp:35,atk:70,def:30},a=n.hp,s=a;$(".player .level").text(o),$(".player .hp").text(a),$(".player .hpTotal").text(a),$(".player .name").text(n.name.toUpperCase()),$("#move0").html("TACKLE"),$("#move1").html("TAIL WHIP"),$("#move2").html("-");var m="Blue",c={name:"Eevee",hp:40,atk:55,def:50},r=c.hp,u=r,w=c.def;$(".foe .level").text(o),$(".foe .name").text(c.name.toUpperCase());var f=function t(){$(".window.menu").hide(),$(".window.item").hide(),$(".window.pkmn").hide(),$(".window.fight").hide()},p=function t(){$(".text1").text(""),$(".text2").text(""),$(".window.item").hide(),$(".window.pkmn").hide(),$(".window.fight").hide(),$(".window.menu").show()},d=function t(e,i){var o=e,n=i,a=100,s=o*a/n;return s},l=function t(){u<=0?($(".window.menu").hide(),$(".foe .hp-bar-active").css("width","0%"),window.setTimeout(function(){$(".foe .images").delay(500).animate({bottom:"-35em"},1e3),$(".text1").text(c.name.toUpperCase()+" fainted!"),$(".text2").text(""),y(),window.setTimeout(function(){$(".foe .stats").hide(),$(".text1").text("Got $"+Math.floor(2.5*o)+" for"),$(".text2").text("winning!"),y(),window.setTimeout(function(){$(".text1").text(m.toUpperCase()+": I can't"),$(".text2").text("believe it!"),y(),window.setTimeout(function(){$(".text1").text("I chose the"),$(".text2").text("wrong POKéMON!"),y()},2e3)},2e3)},2e3)},2e3)):window.setTimeout(function(){$(".text1").text(c.name.toUpperCase()+" used"),$(".text2").text("TACKLE!"),y(),$(".foe .images").animate({right:"0em"},100,"linear").animate({right:"1.8em"},50,"linear").delay(100).animate({right:"0.8em"},10,"linear"),window.setTimeout(function(){$(".player .images").css("opacity",0),window.setTimeout(function(){$(".player .images").css("opacity",1),window.setTimeout(function(){$(".player .images").css("opacity",0),window.setTimeout(function(){$(".player .images").css("opacity",1),window.setTimeout(function(){$(".player .images").css("opacity",0),window.setTimeout(function(){$(".player .images").css("opacity",1),window.setTimeout(function(){var t=40,e=Math.floor(Math.floor(Math.floor(2*o/5+2)*t*c.atk/n.def)/50)+2;s-=e,s<=0?($(".window.menu").hide(),$(".player .hp").text("0"),$(".player .hp-bar-active").css("width","0%"),$(".player .stats").hide(),window.setTimeout(function(){$(".player .images").delay(500).animate({bottom:"-35.714em"},1e3),$(".text1").text(n.name.toUpperCase()+" fainted..."),$(".text2").text(""),y(),window.setTimeout(function(){$(".text1").text(i.toUpperCase()+" is out of"),$(".text2").text("useable POKéMON..."),y(),window.setTimeout(function(){$(".text1").text(i.toUpperCase()+" whited out!"),$(".text2").text(""),y()},2e3)},2e3)},2e3)):($(".player .hp").text(s),$(".player .hp-bar-active").animate({width:d(s,a)+"%"},500),window.setTimeout(function(){p()},2400))},100)},100)},100)},100)},100)},100)},100)},2e3)},h=function t(){f(),$(".text1").text(n.name.toUpperCase()),$(".text2").text("used GROWL!"),y(),window.setTimeout(function(){w=a?($(".text1").text("HP already"),$(".text2").text("full!"),y(),window.setTimeout(function(){p()},1e3)):($(".text1").text("Used POTION!"),$(".text2").text(""),y(),s+=i,s>=a&&(s=a),$(".player .hp").text(s),$(".player .hp-bar-active").animate({width:d(s,a)+"%"},500),T--,l()),$(".potionCount").text(T),T<=0&&$(".potion").hide()},y=function t(){var e=void 0;$(".text1, .text2").each(function(){$(this).text($(this).text().replace(new RegExp(" ","g")," "))}),e=$(".text1, .text2"),e.hide().contents().each(function(){var t=void 0;t=void 0,t=" "+this.data.split("").join(" ")+" ",$(this).replaceWith(t)}),e.find("span").hide().each(function(){$.trim(this.innerHTML)||$(this).remove()}),e.show().find("span").each(function(t){$(this).delay(40*t).fadeIn(0)})},T=1;$(".potionCount").text(T),$(".button.item").click(function(){$(".window.item").show(),$(".window.menu").hide()}),$(".button.potion").click(function(){g("normal")}),$(".button.fight").click(function(){$(".window.fight").show()}),$(".button.growl").click(function(){h()}),$(".button#move0").click(function(){x("tackle")}),$(".button#move1").click(function(){x("tail whip")}),$(".button#move2").click(function(){x("-")}),$(".button.back").click(function(){p()}),$(".button.pkmn").click(function(){$(".window.pkmn").show()}),$(".button.run").click(function(){f(),$(".text1").text("No! There's no"),$(".text2").text("running from a"),y(),window.setTimeout(function(){$(".text1").text("trainer battle!"),$(".text2").text(""),y(),window.setTimeout(function(){p()},2e3)},2e3)});var v=function t(){$(".foe .images").css("right","16em"),$(".player .images").css("left","16em"),$(".player .pokemon, .foe .pokemon, .stats, .balls, .window.item, .window.pkmn, .window.fight, .window.menu").hide(),window.setTimeout(function(){$(".foe .images").animate({right:"0.8em"},800,"linear"),$(".player .images").animate({left:"0.8em"},800,"linear"),window.setTimeout(function(){$(".trainer, .balls").show(),window.setTimeout(function(){$(".text1").text(m.toUpperCase()+" wants"),$(".text2").text("to fight!"),y(),window.setTimeout(function(){$(".balls").hide(),$(".foe .images").animate({right:"-21em"},400,"linear"),window.setTimeout(function(){$(".text1").text(m.toUpperCase()+" sent"),$(".text2").text("out "+c.name.toUpperCase()+"!"),y(),$(".foe .pokemon").show(),$(".foe .trainer").hide(),$(".foe .images").animate({right:"0.8em"},700,"linear"),window.setTimeout(function(){$(".foe .stats").show(),$(".player .images").animate({left:"-21em"},400,"linear"),window.setTimeout(function(){$(".player .trainer").hide(),$(".player .pokemon").show(),$(".player .images").animate({left:"0.8em"},700,"linear"),$(".text1").text("Go! "+n.name.toUpperCase()+"!"),$(".text2").text(""),y(),$(".player .stats").show(),window.setTimeout(function(){p()},2e3)},800)},1500)},1e3)},2500)},400)},800)},600)};v()}); -------------------------------------------------------------------------------- /sfx/battle.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/sfx/battle.mp3 -------------------------------------------------------------------------------- /sfx/eevee.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/sfx/eevee.mp3 -------------------------------------------------------------------------------- /sfx/pikachu.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/sfx/pikachu.mp3 -------------------------------------------------------------------------------- /sfx/victory.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/sfx/victory.mp3 -------------------------------------------------------------------------------- /src/Pokemon Sketch Source.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/src/Pokemon Sketch Source.sketch -------------------------------------------------------------------------------- /src/index.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang: 'en'} 3 | %head 4 | %meta{charset: 'utf-8'} 5 | %meta{content: 'width=device-width, initial-scale=1, shrink-to-fit=no', name: 'viewport'} 6 | %meta{content: 'ie=edge', :'http-equiv' => 'x-ua-compatible'} 7 | %title pokemon-js by Superpencil 8 | %link{rel: 'shortcut icon', href: '/favicon.ico', type: 'image/x-icon'} 9 | %link{rel: 'icon', href: '/favicon.ico', type: 'image/x-icon'} 10 | %link{href: 'main.css', rel: 'stylesheet'} 11 | %body 12 | #pokemon 13 | .depth 14 | .layer.foe 15 | .info 16 | .balls 17 | %img{src: 'img/blue_balls.svg'} 18 | .stats 19 | .name 20 | .level-wrap 21 | %img{src: 'img/level.svg'} 22 | %span.level 23 | .hp-wrap 24 | %img{src: 'img/hp.svg'} 25 | .hp-bar 26 | .hp-bar-active 27 | .images 28 | .trainer 29 | %img{src: 'img/blue_front.svg'} 30 | .pokemon 31 | %img{src: 'img/eevee_front.svg'} 32 | .layer.player 33 | .images 34 | .trainer 35 | %img{src: 'img/red_back.svg'} 36 | .pokemon 37 | %img{src: 'img/pikachu_back.svg'} 38 | .info 39 | .balls 40 | %img{src: 'img/red_balls.svg'} 41 | .stats 42 | .name 43 | .level-wrap 44 | %img{src: 'img/level.svg'} 45 | %span.level 46 | .hp-wrap 47 | %img{src: 'img/hp.svg'} 48 | .hp-bar 49 | .hp-bar-active 50 | .health 51 | %span.hp 52 | %span / 53 | %span.hpTotal 54 | .layer.windows 55 | .window.texts 56 | .text.text1 57 | .text.text2 58 | .window.menu 59 | %span.button.fight FIGHT 60 | %span.button.pkmn 61 | %sup P 62 | %sub K 63 | %sup M 64 | %sub N 65 | %span.button.item ITEM 66 | %span.button.run RUN 67 | .window.fight 68 | #move0.button 69 | #move1.button 70 | #move2.button 71 | .button.back cancel 72 | .window.fight-details 73 | %span.type-header TYPE/ 74 | %span.type NORMAL 75 | .window.item 76 | .button.potion 77 | %span POTION x 78 | %span.potionCount 1 79 | .button.back cancel 80 | .window.pkmn 81 | .button.playerPokemonButton 82 | %span.playerpokemonname 83 | .button.back cancel 84 | 85 | .text-area 86 | %p 87 | pokemon-js by 88 | %a{href: 'http://www.superpencil.com'} Superpencil 89 | 90 | %script{crossorigin: 'anonymous', integrity: 'sha384-3ceskX3iaEnIogmQchP8opvBy3Mi7Ce34nWjpBIwVTHfGYWQS9jwHDVRnpKKHJg7', src: 'https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js'} 91 | -# %script{src: 'https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js'} 92 | %script{src: 'pokemon-min.js'} 93 | -------------------------------------------------------------------------------- /src/main.sass: -------------------------------------------------------------------------------- 1 | $gameboy-dark: #2f3622 2 | $gameboy-normal: #4d5d31 3 | $gameboy-light: #7d7f4c 4 | $gameboy-base: #bbac58 5 | $font-weights: 400 6 | $font-types: normal italic 7 | 8 | @each $font-type in $font-types 9 | @each $font-weight in $font-weights 10 | @font-face 11 | font-family: 'Pokemon' 12 | src: url("fonts/pokemon-#{$font-type}.woff2") format('woff2'), url("fonts/pokemon-#{$font-type}.woff") format('woff') 13 | font-weight: $font-weight 14 | font-style: $font-type 15 | 16 | body 17 | background-color: $gameboy-base 18 | color: $gameboy-dark 19 | font-family: 'Pokemon', monospace 20 | font-size: 20px 21 | margin: 0 22 | padding: 0 23 | line-height: 1.3em 24 | 25 | a 26 | color: #FCE600 27 | text-decoration: none 28 | 29 | h1, h2, h3, h4, h5, h6 30 | color: $gameboy-light 31 | 32 | ::selection 33 | background: $gameboy-normal 34 | color: $gameboy-base 35 | 36 | button 37 | background: $gameboy-base 38 | color: $gameboy-normal 39 | border: 1px solid $gameboy-normal 40 | border-radius: 0.3em 41 | padding: 0.4em 0.8em 0.5em 42 | cursor: pointer 43 | &.active 44 | background: $gameboy-normal 45 | color: $gameboy-base 46 | 47 | // Color inline SVG's 48 | .gb-dark 49 | fill: $gameboy-dark 50 | .gb-normal 51 | fill: $gameboy-normal 52 | .gb-light 53 | fill: $gameboy-light 54 | 55 | .text-area 56 | margin: 0 auto 57 | font-size: 0.5em 58 | width: 32em 59 | line-height: 1.6em 60 | 61 | #pokemon 62 | width: 16.0em 63 | height: 14.4em 64 | position: relative 65 | // user-select: none 66 | margin: 0 auto 67 | // image-rendering: pixelated 68 | // -webkit-font-smoothing: none 69 | transform: translateZ(0em) translateY(0em) translateX(0em) rotateX(0deg) rotateY(0deg) 70 | 71 | // Image background to compare positioning 72 | // background-image: url('src/screenshot_1998.png') 73 | // background-size: cover 74 | // background-repeat: no-repeat 75 | 76 | .button:hover 77 | cursor: pointer 78 | position: relative 79 | &:before 80 | position: absolute 81 | background-image: url('img/marker.svg') 82 | background-repeat: no-repeat 83 | left: -1em 84 | top: 0.1em 85 | width: 0.5em 86 | height: 0.7em 87 | background-size: 0.5em 88 | content: "" 89 | 90 | img, 91 | svg 92 | width: 100% 93 | height: auto 94 | 95 | span, 96 | .button, 97 | .level, 98 | .name 99 | font-size: 0.8em 100 | span 101 | font-size: 1em 102 | 103 | .layer 104 | position: absolute 105 | width: 16.0em 106 | height: 14.4em 107 | overflow: hidden 108 | 109 | .images 110 | position: absolute 111 | width: 5.6em 112 | 113 | .info 114 | position: absolute 115 | width: 7.7em 116 | 117 | .name 118 | height: 1.1em 119 | 120 | .balls 121 | margin-top: 1.6em 122 | 123 | .stats 124 | background-position: bottom 125 | background-size: 7.7em 126 | background-repeat: no-repeat 127 | 128 | .level-wrap 129 | margin-top: -0.1em 130 | height: 0.8em 131 | img, 132 | svg 133 | width: 0.6em 134 | display: inline-block 135 | margin-right: -0.8em 136 | 137 | .health 138 | margin-left: 2.5em 139 | span 140 | display: inline-block 141 | width: 0.8em 142 | 143 | .hp-wrap 144 | height: 0.9em 145 | img, 146 | svg 147 | width: 1.1em 148 | display: inline-block 149 | 150 | .hp-bar 151 | border: 0.1em solid $gameboy-dark 152 | border-radius: 0.4em 153 | height: 0.3em 154 | width: 4.8em 155 | display: inline-block 156 | margin-left: -0.7em 157 | display: inline-block 158 | 159 | .hp-bar-active 160 | background-color: $gameboy-light 161 | height: 100% 162 | width: 100% 163 | border-radius: 0.4em 164 | 165 | .foe 166 | .images 167 | right: 0.8em 168 | 169 | .info 170 | left: 1.1em 171 | 172 | .stats 173 | height: 3em 174 | background-image: url('img/blue_line.svg') 175 | 176 | .name 177 | margin-left: -0.3em 178 | margin-top: -0.1em 179 | 180 | .level-wrap 181 | margin-left: 2.2em 182 | 183 | .hp-wrap 184 | margin-left: 0.6em 185 | 186 | .player 187 | padding-top: 4em 188 | 189 | .images 190 | left: 0.8em 191 | 192 | .info 193 | right: 1.1em 194 | 195 | .stats 196 | background-image: url('img/red_line.svg') 197 | 198 | .name 199 | margin-left: 1em 200 | margin-top: 1.8em 201 | 202 | .level-wrap 203 | margin-left: 4.1em 204 | 205 | .hp-wrap 206 | margin-left: 0.9em 207 | 208 | .balls 209 | margin-top: 4em 210 | 211 | .windows 212 | .window 213 | position: absolute 214 | border-image: url('img/frame.svg') 45% stretch 215 | border-style: solid 216 | border-width: 0.7em 217 | background: $gameboy-base 218 | &.texts 219 | margin: 0 220 | height: 3.2em 221 | left: 0.1em 222 | right: 0.1em 223 | bottom: 0.1em 224 | .text 225 | span 226 | height: 1em 227 | width: 1em 228 | display: inline-block 229 | &.text1 230 | margin-top: 0.5em 231 | &.text2 232 | margin-top: 0.1em 233 | &.menu 234 | display: none 235 | bottom: 0.1em 236 | right: 0.1em 237 | height: 2.7em 238 | width: 7.4em 239 | padding: 0.5em 0 0 0.8em 240 | sup, 241 | sub 242 | display: inline-block 243 | margin-right: -1.3em 244 | font-size: 0.7em 245 | margin-left: -0.4em 246 | &.fight 247 | display: none 248 | bottom: 0.1em 249 | right: 0.1em 250 | left: 3.3em 251 | min-height: 4.6em 252 | padding: 0.5em 0 0 0.8em 253 | .fight-details 254 | top: -3.9em 255 | left: -3.9em 256 | width: 6.6em 257 | height: 2.4em 258 | span 259 | height: 0.8em 260 | margin-top: -0.3em 261 | &.item 262 | display: none 263 | top: 1.7em 264 | bottom: 4.1em 265 | left: 3.3em 266 | right: 0.1em 267 | padding: 0.6em 268 | &.pkmn 269 | display: none 270 | top: 0.1em 271 | bottom: 0.1em 272 | left: 0.1em 273 | right: 0.1em 274 | 275 | // 3D 276 | .perspective 277 | perspective: 30em 278 | transform-style: preserve-3d 279 | .depth 280 | transform: rotateX(0deg) rotateY(0deg) 281 | transform-style: preserve-3d 282 | .foe 283 | transform: translateZ(-8em) 284 | transform-style: preserve-3d 285 | .player 286 | transform: translateZ(-4em) 287 | transform-style: preserve-3d 288 | .windows 289 | transform: translateZ(0em) 290 | transform-style: preserve-3d 291 | .window.menu 292 | transform: translateZ(4em) 293 | transform-style: preserve-3d 294 | .window.fight, 295 | .window.item, 296 | .window.pkmn 297 | transform: translateZ(8em) 298 | transform-style: preserve-3d 299 | -------------------------------------------------------------------------------- /src/pokemon.js: -------------------------------------------------------------------------------- 1 | $(document).ready(() => { 2 | // 3D angle 3 | $('.three-dee').click(() => { 4 | $('#pokemon').toggleClass('perspective') 5 | $('button').toggleClass('active') 6 | $('.depth').removeAttr('style') 7 | }) 8 | const handleMouseMove = e => { 9 | const offset = $('#pokemon').offset() 10 | const width = $('#pokemon').width() 11 | const height = $('#pokemon').height() 12 | const posX = (100 - (((e.pageX - offset.left) / width * 100)) - 50) * 0.15 13 | const posY = (((e.pageY - offset.top) / height * 100) - 50) * 0.15 14 | const moving = `rotateX(${posY}deg) rotateY(${posX}deg)` 15 | $('.depth').css({'-webkit-transform': moving, '-moz-transform': moving, '-ms-transform': moving, '-o-transform': moving, 'transform': moving}) 16 | } 17 | let enableHandler 18 | $('#pokemon').mousemove(function(e) { 19 | if ($(this).hasClass('perspective') && enableHandler) { 20 | handleMouseMove(e) 21 | enableHandler = false 22 | } 23 | }) 24 | window.setInterval(() => { 25 | enableHandler = true 26 | }, 20) 27 | 28 | // Pokédex 29 | // const pokedex = (dex, level) => { 30 | // $.ajax({ 31 | // 'async': false, 32 | // 'global': false, 33 | // 'url': "js/pokemon.json", 34 | // 'dataType': "json", 35 | // 'success': function (data) { 36 | // poke = data 37 | // } 38 | // }) 39 | // var stats = new Object() 40 | // stats['id'] = poke[dex].id 41 | // stats.name = poke[dex].name 42 | // stats.hp = Math.floor((poke[dex].stats.hp * 2 + 193) * level / 100 + 5) 43 | // stats['atk'] = Math.floor(((poke[dex].stats.attack * 2 + 193) * level / 100 + 10) * level / 100 + 20) 44 | // stats.def = Math.floor((poke[dex].stats.defense * 2 + 193) * level / 100 + 10) 45 | // stats['spa'] = Math.floor(((poke[dex].stats.spattack * 2 + 193) * level / 100 + 10) * level / 100) 46 | // stats['spd'] = Math.floor((poke[dex].stats.spdefense * 2 + 193) * level / 100 + 10) 47 | // stats['spe'] = Math.floor((poke[dex].stats.speed * 2 + 193) * level / 100 + 10) 48 | // return stats 49 | // } 50 | 51 | // Player setup 52 | const player = 'Red' 53 | // var playerID = 25 54 | const playerLevel = 5 55 | const playerPokemon = { 56 | 'name': 'Pikachu', 57 | 'hp': 35, 58 | 'atk': 70, 59 | 'def': 30 60 | } 61 | const hpPlayerTotal = playerPokemon.hp 62 | let hpPlayer = hpPlayerTotal 63 | // var playerBaseAttack = playerPokemon.atk 64 | // var playerBaseDefense = playerPokemon.def 65 | $('.player .level').text(playerLevel) 66 | $('.player .hp').text(hpPlayerTotal) 67 | $('.player .hpTotal').text(hpPlayerTotal) 68 | $('.player .name').text(playerPokemon.name.toUpperCase()) 69 | $('#move0').html('TACKLE') 70 | $('#move1').html('TAIL WHIP') 71 | $('#move2').html('-') 72 | 73 | // Foe setup 74 | const foe = 'Blue' 75 | // var foeID = 133 76 | const foePokemon = { 77 | 'name': 'Eevee', 78 | 'hp': 40, 79 | 'atk': 55, 80 | 'def': 50 81 | } 82 | const hpFoeFull = foePokemon.hp 83 | let hpFoe = hpFoeFull 84 | // var foeBaseAttack = foePokemon.atk 85 | let foeBaseDefense = foePokemon.def 86 | $('.foe .level').text(playerLevel) 87 | $('.foe .name').text(foePokemon.name.toUpperCase()) 88 | 89 | // Hide all menus except dialog 90 | const hider = () => { 91 | $('.window.menu').hide() 92 | $('.window.item').hide() 93 | $('.window.pkmn').hide() 94 | $('.window.fight').hide() 95 | } 96 | 97 | // Reset to battle ready mode for turn or cancel 98 | const reset = () => { 99 | $('.text1').text('') 100 | $('.text2').text('') 101 | $('.window.item').hide() 102 | $('.window.pkmn').hide() 103 | $('.window.fight').hide() 104 | $('.window.menu').show() 105 | } 106 | 107 | // Health bar width calculation and health numbers 108 | const healthbar = (current, total) => { 109 | const hpCurrent = current 110 | const hpTotal = total 111 | const percentTotal = 100 112 | const percentCurrent = hpCurrent * percentTotal / hpTotal 113 | return percentCurrent 114 | } 115 | 116 | // Enemy turn 117 | const attackEnd = () => { 118 | if (hpFoe <= 0) { 119 | $('.window.menu').hide() 120 | $('.foe .hp-bar-active').css('width', '0%') 121 | window.setTimeout( () => { 122 | $('.foe .images').delay(500).animate({ 123 | bottom: '-35em' 124 | }, 1000) 125 | $('.text1').text(`${foePokemon.name.toUpperCase()} fainted!`) 126 | $('.text2').text('') 127 | typer() 128 | window.setTimeout( () => { 129 | $('.foe .stats').hide() 130 | $('.text1').text(`Got $${Math.floor(playerLevel * 2.5)} for`) 131 | $('.text2').text('winning!') 132 | typer() 133 | window.setTimeout( () => { 134 | $('.text1').text(`${foe.toUpperCase()}: I can't`) 135 | $('.text2').text('believe it!') 136 | typer() 137 | window.setTimeout( () => { 138 | $('.text1').text('I chose the') 139 | $('.text2').text('wrong POKéMON!') 140 | typer() 141 | }, 2000) 142 | }, 2000) 143 | }, 2000) 144 | }, 2000) 145 | } else { 146 | window.setTimeout( () => { 147 | $('.text1').text(`${foePokemon.name.toUpperCase()} used`) 148 | $('.text2').text('TACKLE!') 149 | typer() 150 | $('.foe .images').animate({ 151 | right: '0em' 152 | }, 100, 'linear').animate({ 153 | right: '1.8em' 154 | }, 50, 'linear').delay(100).animate({ 155 | right: '0.8em' 156 | }, 10, 'linear') 157 | window.setTimeout( () => { 158 | $('.player .images').css('opacity', 0) 159 | window.setTimeout( () => { 160 | $('.player .images').css('opacity', 1) 161 | window.setTimeout( () => { 162 | $('.player .images').css('opacity', 0) 163 | window.setTimeout( () => { 164 | $('.player .images').css('opacity', 1) 165 | window.setTimeout( () => { 166 | $('.player .images').css('opacity', 0) 167 | window.setTimeout( () => { 168 | $('.player .images').css('opacity', 1) 169 | window.setTimeout( () => { 170 | const basePower = 40 171 | const baseDamage = Math.floor(Math.floor(Math.floor(2 * playerLevel / 5 + 2) * basePower * foePokemon.atk / playerPokemon.def) / 50) + 2 172 | hpPlayer -= baseDamage 173 | if (hpPlayer <= 0) { 174 | $('.window.menu').hide() 175 | $('.player .hp').text('0') 176 | $('.player .hp-bar-active').css('width', '0%') 177 | $('.player .stats').hide() 178 | window.setTimeout( () => { 179 | $('.player .images').delay(500).animate({ 180 | bottom: '-35.714em' 181 | }, 1000) 182 | $('.text1').text(`${playerPokemon.name.toUpperCase()} fainted...`) 183 | $('.text2').text('') 184 | typer() 185 | window.setTimeout( () => { 186 | $('.text1').text(`${player.toUpperCase()} is out of`) 187 | $('.text2').text('useable POKéMON...') 188 | typer() 189 | window.setTimeout( () => { 190 | $('.text1').text(`${player.toUpperCase()} whited out!`) 191 | $('.text2').text('') 192 | typer() 193 | }, 2000) 194 | }, 2000) 195 | }, 2000) 196 | } else { 197 | $('.player .hp').text(hpPlayer) 198 | $('.player .hp-bar-active').animate({ 199 | width: `${healthbar(hpPlayer, hpPlayerTotal)}%` 200 | }, 500) 201 | window.setTimeout( () => { 202 | reset() 203 | }, 2400) 204 | } 205 | }, 100) 206 | }, 100) 207 | }, 100) 208 | }, 100) 209 | }, 100) 210 | }, 100) 211 | }, 100) 212 | }, 2000) 213 | } 214 | } 215 | 216 | // Growl 217 | const growl = () => { 218 | hider() 219 | $('.text1').text(playerPokemon.name.toUpperCase()) 220 | $('.text2').text('used GROWL!') 221 | typer() 222 | window.setTimeout( () => { 223 | if (foeBaseDefense < foePokemon.def - 20) { 224 | $('.text1').text(`${foePokemon.name.toUpperCase()}'s defense`) 225 | $('.text2').text('can\'t drop lower!') 226 | typer() 227 | window.setTimeout( () => { 228 | attackEnd() 229 | }, 2000) 230 | } else { 231 | $('.text1').text(`${foePokemon.name.toUpperCase()}'s defense`) 232 | $('.text2').text('dropped by 2!') 233 | foeBaseDefense =- 2 234 | typer() 235 | window.setTimeout( () => { 236 | attackEnd() 237 | }, 2000) 238 | } 239 | }, 2000) 240 | } 241 | 242 | const attack = moveName => { 243 | hider() 244 | $('.text1').text(`${playerPokemon.name.toUpperCase()} used`) 245 | $('.text2').text(`${moveName.toUpperCase()}!`) 246 | typer() 247 | $('.player .images').animate({ 248 | left: '0em' 249 | }, 100, 'linear').animate({ 250 | left: '1.8em' 251 | }, 50, 'linear').delay(100).animate({ 252 | left: '0.8em' 253 | }, 10, 'linear') 254 | window.setTimeout( () => { 255 | $('.foe .images').css('opacity', 0) 256 | window.setTimeout( () => { 257 | $('.foe .images').css('opacity', 1) 258 | window.setTimeout( () => { 259 | $('.foe .images').css('opacity', 0) 260 | window.setTimeout( () => { 261 | $('.foe .images').css('opacity', 1) 262 | window.setTimeout( () => { 263 | $('.foe .images').css('opacity', 0) 264 | window.setTimeout( () => { 265 | $('.foe .images').css('opacity', 1) 266 | const basePower = 40 267 | const baseDamage = Math.floor(Math.floor(Math.floor(2 * playerLevel / 5 + 2) * basePower * playerPokemon.atk / foePokemon.def) / 50) + 2 268 | hpFoe -= baseDamage 269 | $('.foe .hp-bar-active').animate({ 270 | width: `${healthbar(hpFoe, hpFoeFull)}%` 271 | }, 500) 272 | attackEnd() 273 | }, 100) 274 | }, 100) 275 | }, 100) 276 | }, 100) 277 | }, 100) 278 | }, 100) 279 | } 280 | 281 | // Use potion 282 | const potion = potionType => { 283 | let strength 284 | hider() 285 | if (potionType === 'normal') { 286 | strength = 20 287 | } else if (potionType === 'super') { 288 | strength = 50 289 | } else if (potionType === 'hyper') { 290 | strength = 200 291 | } else { 292 | strength = 999 293 | } 294 | if (hpPlayer >= hpPlayerTotal) { 295 | $('.text1').text('HP already') 296 | $('.text2').text('full!') 297 | typer() 298 | window.setTimeout( () => { 299 | reset() 300 | }, 1000) 301 | } else { 302 | $('.text1').text('Used POTION!') 303 | $('.text2').text('') 304 | typer() 305 | hpPlayer += strength 306 | if (hpPlayer >= hpPlayerTotal) { 307 | hpPlayer = hpPlayerTotal 308 | } 309 | $('.player .hp').text(hpPlayer) 310 | $('.player .hp-bar-active').animate({ 311 | width: `${healthbar(hpPlayer, hpPlayerTotal)}%` 312 | }, 500) 313 | potionCount-- 314 | attackEnd() 315 | } 316 | $('.potionCount').text(potionCount) 317 | if (potionCount <= 0) { 318 | $('.potion').hide() 319 | } 320 | } 321 | 322 | // Animated typing of text 323 | var typer = () => { 324 | let line 325 | $('.text1, .text2').each(function() { 326 | $(this).text($(this).text().replace(new RegExp(' ', 'g'), ' ')) 327 | }) 328 | line = $('.text1, .text2') 329 | line.hide().contents().each(function() { 330 | let letters 331 | letters = void 0 332 | letters = ` ${this.data.split('').join(' ')} ` 333 | $(this).replaceWith(letters) 334 | }) 335 | line.find('span').hide().each(function() { 336 | if (!$.trim(this.innerHTML)) { 337 | $(this).remove() 338 | } 339 | }) 340 | line.show().find('span').each(function(i) { 341 | $(this).delay(40 * i).fadeIn(0) 342 | }) 343 | } 344 | 345 | // Click elements 346 | var potionCount = 1 347 | $('.potionCount').text(potionCount) 348 | $('.button.item').click(() => { 349 | $('.window.item').show() 350 | $('.window.menu').hide() 351 | }) 352 | $('.button.potion').click(() => { 353 | potion('normal') 354 | }) 355 | $('.button.fight').click(() => { 356 | $('.window.fight').show() 357 | }) 358 | $('.button.growl').click(() => { 359 | growl() 360 | }) 361 | $('.button#move0').click(() => { 362 | attack('tackle') 363 | }) 364 | $('.button#move1').click(() => { 365 | attack('tail whip') 366 | }) 367 | $('.button#move2').click(() => { 368 | attack('-') 369 | }) 370 | $('.button.back').click(() => { 371 | reset() 372 | }) 373 | $('.button.pkmn').click(() => { 374 | $('.window.pkmn').show() 375 | }) 376 | $('.button.run').click(() => { 377 | hider() 378 | $('.text1').text('No! There\'s no') 379 | $('.text2').text('running from a') 380 | typer() 381 | window.setTimeout( () => { 382 | $('.text1').text('trainer battle!') 383 | $('.text2').text('') 384 | typer() 385 | window.setTimeout( () => { 386 | reset() 387 | }, 2000) 388 | }, 2000) 389 | }) 390 | 391 | // Start animation 392 | const playPokemon = () => { 393 | $('.foe .images').css('right', '16em') 394 | $('.player .images').css('left', '16em') 395 | $('.player .pokemon, .foe .pokemon, .stats, .balls, .window.item, .window.pkmn, .window.fight, .window.menu').hide() 396 | window.setTimeout(() => { 397 | $('.foe .images').animate({ 398 | right: '0.8em' 399 | }, 800, 'linear') 400 | $('.player .images').animate({ 401 | left: '0.8em' 402 | }, 800, 'linear') 403 | window.setTimeout(() => { 404 | $('.trainer, .balls').show() 405 | window.setTimeout(() => { 406 | $('.text1').text(`${foe.toUpperCase()} wants`) 407 | $('.text2').text('to fight!') 408 | typer() 409 | window.setTimeout(() => { 410 | $('.balls').hide() 411 | $('.foe .images').animate({ 412 | right: '-21em' 413 | }, 400, 'linear') 414 | window.setTimeout(() => { 415 | $('.text1').text(`${foe.toUpperCase()} sent`) 416 | $('.text2').text(`out ${foePokemon.name.toUpperCase()}!`) 417 | typer() 418 | $('.foe .pokemon').show() 419 | $('.foe .trainer').hide() 420 | $('.foe .images').animate({ 421 | right: '0.8em' 422 | }, 700, 'linear') 423 | window.setTimeout(() => { 424 | $('.foe .stats').show() 425 | $('.player .images').animate({ 426 | left: '-21em' 427 | }, 400, 'linear') 428 | window.setTimeout(() => { 429 | $('.player .trainer').hide() 430 | $('.player .pokemon').show() 431 | $('.player .images').animate({ 432 | left: '0.8em' 433 | }, 700, 'linear') 434 | $('.text1').text(`Go! ${playerPokemon.name.toUpperCase()}!`) 435 | $('.text2').text('') 436 | typer() 437 | $('.player .stats').show() 438 | window.setTimeout(() => { 439 | reset() 440 | }, 2000) 441 | }, 800) 442 | }, 1500) 443 | }, 1000) 444 | }, 2500) 445 | }, 400) 446 | }, 800) 447 | }, 600) 448 | } 449 | 450 | // Start 451 | playPokemon() 452 | }) 453 | -------------------------------------------------------------------------------- /src/promo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/src/promo.png -------------------------------------------------------------------------------- /src/screenshot_1998.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/src/screenshot_1998.png -------------------------------------------------------------------------------- /src/screenshot_2014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/src/screenshot_2014.png -------------------------------------------------------------------------------- /src/screenshot_2016.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalPixel/pokemon-js/a809db12bb10bdce8cbbb481a06fd54e451bbf9a/src/screenshot_2016.png --------------------------------------------------------------------------------