Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Jogos: indo além do simples CSS 3.0

444 views

Published on

Há quem pense que o CSS serve somente para aplicar estilos a determinados elementos, e realmente seu principal objetivo é esse! Mas alguém já pensou que seria possível capturar eventos, como um evento de clique por exemplo, e gerar algum tipo de animação com isso? E falar que com isso é possível criar um jogo? Neste talk explicarei como criar um jogo simples, sem uma linha de javascript, usando apenas HTML e CSS. Além de muitas de suas funcionalidades: pseudo-elementos, pseudo-classes, animations, entre outras.

Published in: Technology
  • Be the first to comment

Jogos: indo além do simples CSS 3.0

  1. 1. Jogos: indo além do simples CSS Fernanda Bernardo
  2. 2. Fernanda Bernardo Engenheira de Software @Elo7 Mentora @Training Center http://fernandabernardo.com.br @Feh_Bernardo
  3. 3. GIFS ❤❤❤
  4. 4. Repositório: http://bit.ly/2c2RsV1 Palestra: http://bit.ly/2cbNs6h
  5. 5. Repositório: http://bit.ly/2c2RsV1 Palestra: http://bit.ly/2cbNs6h
  6. 6. Repositório: http://bit.ly/2eLXyeP Palestra: http://bit.ly/2xDU5qq
  7. 7. Repositório: http://bit.ly/2eLXyeP Palestra: http://bit.ly/2xDU5qq
  8. 8. Porque só CSS?
  9. 9. Divertido
  10. 10. Desafio
  11. 11. Aprendizado
  12. 12. We CSS
  13. 13. We CSS
  14. 14. Como representar os elementos básicos do jogo?
  15. 15. <div class=“container”> </div>
  16. 16. .container { } <div class=“container”> </div>
  17. 17. .container { } <div class=“container”> </div> width: 100vw; height: 100vh;
  18. 18. cursor: url('images/bob.png'), default; .container { } <div class=“container”> </div> width: 100vw; height: 100vh;
  19. 19. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }
  20. 20. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }
  21. 21. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; } VW VH
  22. 22. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; } Viewport Width Viewport Height
  23. 23. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; } vmax vmin
  24. 24. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; } vmax vmin
  25. 25. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }
  26. 26. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; } cursor:
  27. 27. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; } cursor: default;
  28. 28. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; } cursor: pointer;
  29. 29. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; } cursor: url('images/bob.png'), default;
  30. 30. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; } cursor: url('images/bob.png'), default;
  31. 31. .container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; box-sizing: border-box; }
  32. 32. vw, vh, vmin, vmax cursor box-sizing
  33. 33. vw, vh, vmin, vmax cursor box-sizing
  34. 34. <div class=“container”> </div>
  35. 35. <div class=“container”> <main class=“game"> </main> </div>
  36. 36. <div class=“container”> <main class=“game"> </main> </div> .container { position: relative; }
  37. 37. <div class=“container”> <main class=“game"> </main> </div> .container { position: relative; } .game { background: url('images/fundo.jpg'); position: absolute; }
  38. 38. E os inimigos?
  39. 39. <main class=“game”> </main>
  40. 40. <main class=“game”> </main> <div class="inimigo"></div>
  41. 41. <main class=“game”> </main> <div class="inimigo"></div> .inimigo { }
  42. 42. <main class=“game”> </main> <div class="inimigo"></div> .inimigo { } width: 20px; height: 20px;
  43. 43. <main class=“game”> </main> <div class="inimigo"></div> .inimigo { } width: 20px; height: 20px; border-radius: 50%;
  44. 44. <main class=“game”> </main> <div class="inimigo"></div> .inimigo { } width: 20px; height: 20px; border-radius: 50%; background-color: white;
  45. 45. <main class=“game”> </main> <div class="inimigo"></div> .inimigo { } width: 20px; height: 20px; border-radius: 50%; background-color: white; position: absolute;
  46. 46. <main class=“game”> </main> <div class="inimigo"></div> .inimigo { } width: 20px; height: 20px; border-radius: 50%; background-color: white; position: absolute; left: 9%;
  47. 47. <main class=“game”> </main> <div class="inimigo"></div> .inimigo { } width: 20px; height: 20px; border-radius: 50%; background-color: white; position: absolute; left: 9%; animation-name: moving;
  48. 48. <main class=“game”> </main> <div class="inimigo"></div> .inimigo { } width: 20px; height: 20px; border-radius: 50%; background-color: white; position: absolute; left: 9%; animation-name: moving; animation-duration: 6s;
  49. 49. <main class=“game”> </main> <div class="inimigo"></div> @keyframes moving {
  50. 50. <main class=“game”> </main> <div class="inimigo"></div> @keyframes moving { 0% { top: 0; }
  51. 51. <main class=“game”> </main> <div class="inimigo"></div> @keyframes moving { 0% { top: 0; } 100% { top: calc(100% - 25px); } }
  52. 52. vw, vh, vmin, vmax cursor box-sizing animation
  53. 53. vw, vh, vmin, vmax cursor box-sizing animation
  54. 54. <main class=“game”> </main> <div class="inimigo"></div>
  55. 55. <main class=“game”> </main> <div class="inimigo"></div> <div class="inimigo"></div> <div class="inimigo"></div> <div class="inimigo"></div> <div class="inimigo"></div>
  56. 56. <main class=“game”> </main> <div class="inimigo" id="i1"></div> <div class="inimigo" id="i2"></div> <div class="inimigo" id="i3"></div> <div class="inimigo" id="i4"></div> <div class="inimigo" id="i5"></div>
  57. 57. #i1 { left: 9%; } #i2 { left: 23%; } #i3 { left: 37%; } #i4 { left: 65%; } #i5 { left: 90%; }
  58. 58. E como deixar os inimigos mais dinâmicos?
  59. 59. #i1 { animation-duration: 6s; animation-iteration-count: 2;}
  60. 60. #i1 { animation-duration: 6s; animation-iteration-count: 2;} #i2 { animation-duration: 5s; animation-iteration-count: 2;} #i3 { animation-duration: 7s; animation-iteration-count: 2;} #i4 { animation-duration: 12s; animation-iteration-count: 1;} #i5 { animation-duration: 10s; animation-iteration-count: 1;}
  61. 61. E se tiver mais inimigos?
  62. 62. E se tiver mais inimigos? #i6, #i7, #i8, #i9, #i10 { animation-delay: 10s; background-color: red; }
  63. 63. Como esconder?
  64. 64. Como esconder? .inimigo { z-index: -1; animation-fill-mode: backwards; }
  65. 65. Como esconder? .inimigo { z-index: -1; animation-fill-mode: backwards; }
  66. 66. Como esconder? .inimigo { z-index: -1; animation-fill-mode: backwards; } @keyframes moving { 0% { z-index: -1; } 1% { z-index: 2; } 100% { z-index: 2; } }
  67. 67. vw, vh, vmin, vmax cursor box-sizing animation z-index
  68. 68. vw, vh, vmin, vmax cursor box-sizing animation z-index
  69. 69. <main class=“game”> </main>
  70. 70. <main class=“game”> </main> [...] <div class=“oops"> Game Over :( </div>
  71. 71. <main class=“game”> </main> [...] <div class=“oops"> Game Over :( </div> .oops {
  72. 72. <main class=“game”> </main> [...] <div class=“oops"> Game Over :( </div> .oops { display: none;
  73. 73. <main class=“game”> </main> [...] <div class=“oops"> Game Over :( </div> .oops { display: none; position: absolute;
  74. 74. <main class=“game”> </main> [...] <div class=“oops"> Game Over :( </div> .oops { display: none; position: absolute; top: 0; left: 0;
  75. 75. <main class=“game”> </main> [...] <div class=“oops"> Game Over :( </div> .oops { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%;
  76. 76. <main class=“game”> </main> [...] <div class=“oops"> Game Over :( </div> .oops { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: red; z-index: 10; }
  77. 77. .oops { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: red; z-index: 10; }
  78. 78. .oops { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: red; z-index: 10; }
  79. 79. .oops { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: red; z-index: 10; } .inimigo:hover ~ .oops { display: block; }
  80. 80. .oops { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: red; z-index: 10; } .inimigo:hover ~ .oops { display: block; }
  81. 81. .oops { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: red; z-index: 10; } .inimigo:hover ~ .oops { display: block; }
  82. 82. .oops { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: red; z-index: 10; } .inimigo:hover ~ .oops { display: block; } .oops:hover { display: block; }
  83. 83. .oops { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: red; z-index: 10; } .inimigo:hover ~ .oops { display: block; } .oops:hover { display: block; }
  84. 84. vw, vh, vmin, vmax cursor box-sizing animation z-index seletores
  85. 85. vw, vh, vmin, vmax cursor box-sizing animation z-index seletores
  86. 86. O que vamos conquistar?
  87. 87. <main class=“game”> </main> <div class="inimigo" id="i1"></div> [...] <div class="inimigo" id="i5"></div>
  88. 88. <main class=“game”> </main> <div class="inimigo" id="i1"></div> [...] <div class="inimigo" id="i5"></div> <input class=“coin” type="checkbox" id="c1"> </input>
  89. 89. .coin {
  90. 90. .coin { width: 20px; height: 20px;
  91. 91. .coin { width: 20px; height: 20px; background-color: yellow;
  92. 92. .coin { width: 20px; height: 20px; background-color: yellow; border-radius: 50%;
  93. 93. .coin { width: 20px; height: 20px; background-color: yellow; border-radius: 50%; position: absolute;
  94. 94. .coin { width: 20px; height: 20px; background-color: yellow; border-radius: 50%; position: absolute; left: 9%;
  95. 95. .coin { width: 20px; height: 20px; background-color: yellow; border-radius: 50%; position: absolute; left: 9%; -webkit-appearance: none;
  96. 96. .coin { width: 20px; height: 20px; background-color: yellow; border-radius: 50%; position: absolute; left: 9%; -webkit-appearance: none; animation-name: moving; animation-duration: 6s; }
  97. 97. .coin { width: 20px; height: 20px; background-color: yellow; border-radius: 50%; position: absolute; left: 9%; -webkit-appearance: none; animation-name: moving; animation-duration: 6s; } .coin:checked {
  98. 98. .coin { width: 20px; height: 20px; background-color: yellow; border-radius: 50%; position: absolute; left: 9%; -webkit-appearance: none; animation-name: moving; animation-duration: 6s; } .coin:checked { visibility: hidden; }
  99. 99. <main class=“game”>
  100. 100. <main class=“game”> <div class="inimigo" id="i1"></div>
  101. 101. <main class=“game”> <div class="inimigo" id="i1"></div> <div class="inimigo" id="i2"></div>
  102. 102. <main class=“game”> <div class="inimigo" id="i1"></div> <div class="inimigo" id="i2"></div> <div class="inimigo" id="i3"></div>
  103. 103. <main class=“game”> <div class="inimigo" id="i1"></div> <div class="inimigo" id="i2"></div> <div class="inimigo" id="i3"></div> <input class="coin" type="checkbox" id=“c1"> </input>
  104. 104. <main class=“game”> <div class="inimigo" id="i1"></div> <div class="inimigo" id="i2"></div> <div class="inimigo" id="i3"></div> <input class="coin" type="checkbox" id=“c1"> </input> <div class="inimigo" id="i4"></div>
  105. 105. <main class=“game”> <div class="inimigo" id="i1"></div> <div class="inimigo" id="i2"></div> <div class="inimigo" id="i3"></div> <input class="coin" type="checkbox" id=“c1"> </input> <div class="inimigo" id="i4"></div> <input class=“coin" type="checkbox" id=“c2"> </input>
  106. 106. <main class=“game”> <div class="inimigo" id="i1"></div> <div class="inimigo" id="i2"></div> <div class="inimigo" id="i3"></div> <input class="coin" type="checkbox" id=“c1"> </input> <div class="inimigo" id="i4"></div> <input class=“coin" type="checkbox" id=“c2"> </input> <div class="inimigo" id="i5"></div>
  107. 107. Como contar os pontos?
  108. 108. .game { counter-reset: pontos; }
  109. 109. .game { counter-reset: pontos; } .game:after { content: counter(pontos) ‘/2'; }
  110. 110. .game { counter-reset: pontos; } .game:after { content: counter(pontos) ‘/2'; } .coin:checked { counter-increment: pontos; }
  111. 111. .game { counter-reset: pontos; } .game:after { content: counter(pontos) ‘/2'; } .coin:checked { counter-increment: pontos; }
  112. 112. .game { counter-reset: pontos; } .game:after { content: counter(pontos) ‘/2'; } .coin:checked { counter-increment: pontos; }
  113. 113. .game { counter-reset: blah; } .game:after { content: counter(blah) ‘/2'; } .coin:checked { counter-increment: blah; }
  114. 114. .coin:checked { counter-increment: pontos; }
  115. 115. .coin:checked { counter-increment: pontos; visibility: hidden; }
  116. 116. .coin:checked { counter-increment: pontos; visibility: hidden; } display: none;
  117. 117. .coin:checked { counter-increment: pontos; visibility: hidden; } display: none; ???
  118. 118. .coin:checked { counter-increment: pontos; visibility: hidden; }
  119. 119. .coin:checked { counter-increment: pontos; visibility: hidden; } Visibility hidden X Display none
  120. 120. vw, vh, vmin, vmax cursor box-sizing animation z-index seletores counter
  121. 121. vw, vh, vmin, vmax cursor box-sizing animation z-index seletores counter
  122. 122. Como vence?
  123. 123. Como vence?
  124. 124. <main class=“game”> [...]
  125. 125. <main class=“game”> [...] <div class="venceu"> Venceu! :) </div> </main>
  126. 126. .venceu { display: none; position: absolute; width: 100%; height: 100%; background-color: green; top: 0; left: 0; }
  127. 127. .venceu { display: none; position: absolute; width: 100%; height: 100%; background-color: green; top: 0; left: 0; } #c1:checked ~ #c2:checked
  128. 128. .venceu { display: none; position: absolute; width: 100%; height: 100%; background-color: green; top: 0; left: 0; } #c1:checked ~ #c2:checked ~ .venceu {
  129. 129. .venceu { display: none; position: absolute; width: 100%; height: 100%; background-color: green; top: 0; left: 0; } #c1:checked ~ #c2:checked ~ .venceu { display: block; }
  130. 130. .venceu { display: none; position: absolute; width: 100%; height: 100%; background-color: green; top: 0; left: 0; } #c1:checked ~ #c2:checked ~ .venceu { display: block; }
  131. 131. Mais moedas?
  132. 132. #c1:checked ~ #c2:checked ~ .venceu { display: block; } Mais moedas?
  133. 133. #c1:checked ~ #c2:checked ~ .venceu { display: block; } Mais moedas? ~ #c3:checked
  134. 134. #c1:checked ~ #c2:checked ~ .venceu { display: block; } Mais moedas? ~ #c3:checked ~ #c4:checked
  135. 135. #c1:checked ~ #c2:checked ~ .venceu { display: block; } Mais moedas? ~ #c3:checked ~ #c4:checked ~ #c5:checked
  136. 136. <main class=“game”> [...] <input class="coin" type="checkbox" id="c1"></input> [...] <input class="coin" type="checkbox" id=“c2"></input> [...] </main>
  137. 137. <main class=“game”> [...] <input class="coin" tabindex="-1" type="checkbox" id=“c1"></input> [...] <input class="coin” tabindex="-1" type="checkbox" id=“c2"></input> [...] </main>
  138. 138. vw, vh, vmin, vmax cursor box-sizing animation z-index seletores counter tabindex
  139. 139. vw, vh, vmin, vmax cursor box-sizing animation z-index seletores counter tabindex
  140. 140. <main class=“game”>
  141. 141. <main class=“game”> <input type="checkbox" id="pause-button"></input>
  142. 142. <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label>
  143. 143. <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] </main>
  144. 144. <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] </main> #pause-button + label {
  145. 145. <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] </main> #pause-button + label { background-image: url('images/pause.png'); }
  146. 146. <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] </main> #pause-button + label { background-image: url('images/pause.png'); } #pause-button:checked + label {
  147. 147. <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] </main> #pause-button + label { background-image: url('images/pause.png'); } #pause-button:checked + label { background-image: url('images/play.png'); }
  148. 148. <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] </main>
  149. 149. #pause-button ~ .inimigo, <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] </main>
  150. 150. #pause-button ~ .inimigo, #pause-button ~ .coin { <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] </main>
  151. 151. #pause-button ~ .inimigo, #pause-button ~ .coin { animation-play-state: running; } <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] </main>
  152. 152. #pause-button ~ .inimigo, #pause-button ~ .coin { animation-play-state: running; } <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] </main> #pause-button:checked ~ .inimigo,
  153. 153. #pause-button ~ .inimigo, #pause-button ~ .coin { animation-play-state: running; } <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] </main> #pause-button:checked ~ .inimigo, #pause-button:checked ~ .coin {
  154. 154. #pause-button ~ .inimigo, #pause-button ~ .coin { animation-play-state: running; } <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] </main> #pause-button:checked ~ .inimigo, #pause-button:checked ~ .coin { animation-play-state: paused; }
  155. 155. <main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] <div class="pause-container"></div> </main>
  156. 156. .pause-container { display: none; background-color: black; opacity: 0.7; } #pause-button:checked ~ .pause-container { display: block; }
  157. 157. .pause-container
  158. 158. .pause-container .pause-container:before
  159. 159. Como colocar instruções?
  160. 160. <div class="container"> <input id="intro" type="checkbox">
  161. 161. <div class="container"> <input id="intro" type="checkbox"> <section class="intro"> <h2>Space Game</h2> <p>Jogo só com CSS, sem Javascript ;D</p> <label for=“intro">Play!</label> </section> [… .game]
  162. 162. <div class="container"> <input id="intro" type="checkbox"> <section class="intro"> <h2>Space Game</h2> <p>Jogo só com CSS, sem Javascript ;D</p> <label for=“intro">Play!</label> </section> [… .game] </div>
  163. 163. div .container input #intro section .intro h2 p label for=intro
  164. 164. div .container input #intro section .intro h2 p label for=intro .intro { width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 15; }
  165. 165. div .container input #intro section .intro h2 p label for=intro
  166. 166. div .container input #intro section .intro h2 p label for=intro label[for=“intro"] { padding: 1em; font-size: 1.2em; background-color: purple; border-radius: 5px; margin: 1em 25%; display: inline-block; border: 1px solid purple; }
  167. 167. div .container input #intro section .intro h2 p label for=intro
  168. 168. div .container input #intro section .intro h2 p label for=intro #intro:checked ~ .intro { display: none; }
  169. 169. div .container input #intro section .intro h2 p label for=intro
  170. 170. <section class="rules"> <div> <h3>Regras</h3> <ul> <li>Mova seu personagem com o mouse</li> <li>Clique nas moedas para coletá-las</li> <li>Fuja dos tiros</li> </ul> <label for="rules">Entendi :)</label> </div> </section>
  171. 171. #intro:checked + #rules:checked ~ .rules { display: none; }
  172. 172. http://fernandabernardo.com.br/space-game/
  173. 173. vw, vh, vmin, vmax cursor box-sizing animation z-index seletores counter tabindex
  174. 174. • http://minocernota.com/articles/pure_css_game/ • http://codepen.io/vaielab/full/yoKEF/ • http://dabblet.com/gist/2076449 • http://ryan-kahn.com/static/onlyCSS/ • http://fernandabernardo.com.br/piano-tiles/ • https://github.com/FernandaBernardo/timberman-css Biografia
  175. 175. http://fernandabernardo.com.br @Feh_Bernardo
  176. 176. http://fernandabernardo.com.br @Feh_Bernardo
  177. 177. PARE
  178. 178. PARE PENSE
  179. 179. PARE PENSE DIVIRTA-SE
  180. 180. PARE PENSE DIVIRTA-SE APRENDA
  181. 181. PARE PENSE DIVIRTA-SE APRENDA IMPLEMENTE
  182. 182. PARE PENSE DIVIRTA-SE APRENDA IMPLEMENTE COMPARTILHE

×