Jogos: indo além do simples CSS 3.0

Preview:

Citation preview

Jogos: indo além do simples CSS

Fernanda Bernardo

Fernanda BernardoEngenheira de Software @Elo7

Mentora @Training Center

http://fernandabernardo.com.br

@Feh_Bernardo

GIFS ❤❤❤

Repositório: http://bit.ly/2c2RsV1

Palestra: http://bit.ly/2cbNs6h

Repositório: http://bit.ly/2c2RsV1

Palestra: http://bit.ly/2cbNs6h

Repositório: http://bit.ly/2eLXyeP

Palestra: http://bit.ly/2xDU5qq

Repositório: http://bit.ly/2eLXyeP

Palestra: http://bit.ly/2xDU5qq

Porque só CSS?

Divertido

Desafio

Aprendizado

We

CSS

We

CSS

Como representar os elementos

básicos do jogo?

<div class=“container”>

</div>

.container {

}

<div class=“container”>

</div>

.container {

}

<div class=“container”>

</div>

width: 100vw;height: 100vh;

cursor: url('images/bob.png'), default;

.container {

}

<div class=“container”>

</div>

width: 100vw;height: 100vh;

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }

VW VH

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }

Viewport Width Viewport Height

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }

vmax vmin

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }

vmax vmin

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }

cursor:

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }

cursor: default;

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }

cursor: pointer;

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }

cursor: url('images/bob.png'),default;

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default; }

cursor: url('images/bob.png'),default;

.container { width: 100vw; height: 100vh; cursor: url('images/bob.png'), default;

box-sizing: border-box; }

vw, vh, vmin, vmax cursor box-sizing

vw, vh, vmin, vmax cursor box-sizing

<div class=“container”>

</div>

<div class=“container”> <main class=“game">

</main> </div>

<div class=“container”> <main class=“game">

</main> </div> .container {

position: relative;}

<div class=“container”> <main class=“game">

</main> </div> .container {

position: relative;}

.game {background: url('images/fundo.jpg');position: absolute;

}

E os inimigos?

<main class=“game”>

</main>

<main class=“game”>

</main><div class="inimigo"></div>

<main class=“game”>

</main><div class="inimigo"></div>

.inimigo {

}

<main class=“game”>

</main><div class="inimigo"></div>

.inimigo {

}

width: 20px;height: 20px;

<main class=“game”>

</main><div class="inimigo"></div>

.inimigo {

}

width: 20px;height: 20px;border-radius: 50%;

<main class=“game”>

</main><div class="inimigo"></div>

.inimigo {

}

width: 20px;height: 20px;border-radius: 50%;background-color: white;

<main class=“game”>

</main><div class="inimigo"></div>

.inimigo {

}

width: 20px;height: 20px;border-radius: 50%;background-color: white;position: absolute;

<main class=“game”>

</main><div class="inimigo"></div>

.inimigo {

}

width: 20px;height: 20px;border-radius: 50%;background-color: white;position: absolute;left: 9%;

<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;

<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;

<main class=“game”>

</main><div class="inimigo"></div>

@keyframes moving {

<main class=“game”>

</main><div class="inimigo"></div>

@keyframes moving {0% {

top: 0;}

<main class=“game”>

</main><div class="inimigo"></div>

@keyframes moving {0% {

top: 0;}100% {

top: calc(100% - 25px);}

}

vw, vh, vmin, vmax cursor box-sizing animation

vw, vh, vmin, vmax cursor box-sizing animation

<main class=“game”>

</main>

<div class="inimigo"></div>

<main class=“game”>

</main>

<div class="inimigo"></div><div class="inimigo"></div><div class="inimigo"></div><div class="inimigo"></div><div class="inimigo"></div>

<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>

#i1 {left: 9%;

}

#i2 {left: 23%;

}

#i3 {left: 37%;

}

#i4 {left: 65%;

}

#i5 {left: 90%;

}

E como deixar os inimigos mais dinâmicos?

#i1 { animation-duration: 6s;animation-iteration-count: 2;}

#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;}

E se tiver mais inimigos?

E se tiver mais inimigos?

#i6, #i7, #i8, #i9, #i10 {animation-delay: 10s;background-color: red;

}

Como esconder?

Como esconder?.inimigo {z-index: -1;animation-fill-mode: backwards;

}

Como esconder?.inimigo { z-index: -1; animation-fill-mode: backwards;

}

Como esconder?.inimigo { z-index: -1; animation-fill-mode: backwards;

}

@keyframes moving {0% { z-index: -1; }1% { z-index: 2; }100% { z-index: 2; }

}

vw, vh, vmin, vmax cursor box-sizing animation z-index

vw, vh, vmin, vmax cursor box-sizing animation z-index

<main class=“game”>

</main>

<main class=“game”>

</main>

[...]

<div class=“oops">Game Over :(

</div>

<main class=“game”>

</main>

[...]

<div class=“oops">Game Over :(

</div>

.oops {

<main class=“game”>

</main>

[...]

<div class=“oops">Game Over :(

</div>

.oops {display: none;

<main class=“game”>

</main>

[...]

<div class=“oops">Game Over :(

</div>

.oops {display: none;position: absolute;

<main class=“game”>

</main>

[...]

<div class=“oops">Game Over :(

</div>

.oops {display: none;position: absolute;top: 0;left: 0;

<main class=“game”>

</main>

[...]

<div class=“oops">Game Over :(

</div>

.oops {display: none;position: absolute;top: 0;left: 0;width: 100%;height: 100%;

<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;

}

.oops { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: red; z-index: 10; }

.oops { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: red; z-index: 10; }

.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 { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: red; z-index: 10; }

.inimigo:hover ~ .oops {display: block;

}

.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 { 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;

}

.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;

}

vw, vh, vmin, vmax cursor box-sizing animation z-index seletores

vw, vh, vmin, vmax cursor box-sizing animation z-index seletores

O que vamos conquistar?

<main class=“game”>

</main>

<div class="inimigo" id="i1"></div>[...] <div class="inimigo" id="i5"></div>

<main class=“game”>

</main>

<div class="inimigo" id="i1"></div>[...]

<div class="inimigo" id="i5"></div>

<input class=“coin” type="checkbox" id="c1"> </input>

.coin {

.coin {width: 20px;height: 20px;

.coin {width: 20px;height: 20px;background-color: yellow;

.coin {width: 20px;height: 20px;background-color: yellow;border-radius: 50%;

.coin {width: 20px;height: 20px;background-color: yellow;border-radius: 50%;position: absolute;

.coin {width: 20px;height: 20px;background-color: yellow;border-radius: 50%;position: absolute;left: 9%;

.coin {width: 20px;height: 20px;background-color: yellow;border-radius: 50%;position: absolute;left: 9%;-webkit-appearance: none;

.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 {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 {

.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;}

<main class=“game”>

<main class=“game”><div class="inimigo" id="i1"></div>

<main class=“game”><div class="inimigo" id="i1"></div><div class="inimigo" id="i2"></div>

<main class=“game”><div class="inimigo" id="i1"></div><div class="inimigo" id="i2"></div><div class="inimigo" id="i3"></div>

<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>

<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>

<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>

<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>

Como contar os pontos?

.game { counter-reset: pontos; }

.game { counter-reset: pontos; }

.game:after { content: counter(pontos) ‘/2'; }

.game { counter-reset: pontos; }

.game:after { content: counter(pontos) ‘/2'; }

.coin:checked { counter-increment: pontos; }

.game { counter-reset: pontos; }

.game:after { content: counter(pontos) ‘/2'; }

.coin:checked { counter-increment: pontos; }

.game { counter-reset: pontos; }

.game:after { content: counter(pontos) ‘/2'; }

.coin:checked { counter-increment: pontos; }

.game { counter-reset: blah; }

.game:after { content: counter(blah) ‘/2'; }

.coin:checked { counter-increment: blah; }

.coin:checked { counter-increment: pontos; }

.coin:checked { counter-increment: pontos; visibility: hidden; }

.coin:checked { counter-increment: pontos; visibility: hidden; }

display: none;

.coin:checked { counter-increment: pontos; visibility: hidden; }

display: none; ???

.coin:checked { counter-increment: pontos; visibility: hidden; }

.coin:checked { counter-increment: pontos; visibility: hidden; }

Visibility hidden X Display

none

vw, vh, vmin, vmax cursor box-sizing animation z-index seletores counter

vw, vh, vmin, vmax cursor box-sizing animation z-index seletores counter

Como vence?

Como vence?

<main class=“game”>[...]

<main class=“game”>[...]<div class="venceu">Venceu! :)

</div></main>

.venceu {display: none;position: absolute;width: 100%;height: 100%;background-color: green;top: 0;left: 0;

}

.venceu {display: none;position: absolute;width: 100%;height: 100%;background-color: green;top: 0;left: 0;

}

#c1:checked ~ #c2:checked

.venceu {display: none;position: absolute;width: 100%;height: 100%;background-color: green;top: 0;left: 0;

}

#c1:checked ~ #c2:checked~ .venceu {

.venceu {display: none;position: absolute;width: 100%;height: 100%;background-color: green;top: 0;left: 0;

}

#c1:checked ~ #c2:checked~ .venceu {

display: block;}

.venceu {display: none;position: absolute;width: 100%;height: 100%;background-color: green;top: 0;left: 0;

}

#c1:checked ~ #c2:checked~ .venceu {

display: block;}

Mais moedas?

#c1:checked ~ #c2:checked

~ .venceu { display: block; }

Mais moedas?

#c1:checked ~ #c2:checked

~ .venceu { display: block; }

Mais moedas?~ #c3:checked

#c1:checked ~ #c2:checked

~ .venceu { display: block; }

Mais moedas?~ #c3:checked

~ #c4:checked

#c1:checked ~ #c2:checked

~ .venceu { display: block; }

Mais moedas?~ #c3:checked

~ #c4:checked ~ #c5:checked

<main class=“game”> [...] <input class="coin" type="checkbox" id="c1"></input> [...] <input class="coin" type="checkbox" id=“c2"></input> [...]

</main>

<main class=“game”> [...] <input class="coin" tabindex="-1" type="checkbox" id=“c1"></input> [...] <input class="coin” tabindex="-1" type="checkbox" id=“c2"></input> [...]

</main>

vw, vh, vmin, vmax cursor box-sizing animation z-index seletores counter tabindex

vw, vh, vmin, vmax cursor box-sizing animation z-index seletores counter tabindex

<main class=“game”>

<main class=“game”><input type="checkbox" id="pause-button"></input>

<main class=“game”><input type="checkbox" id="pause-button"></input><label for="pause-button"></label>

<main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...]

</main>

<main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...]

</main>

#pause-button + label {

<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');

}

<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 {

<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');

}

<main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...]

</main>

#pause-button ~ .inimigo,

<main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...]

</main>

#pause-button ~ .inimigo,#pause-button ~ .coin {

<main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...]

</main>

#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 ~ .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 ~ .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 {

#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;}

<main class=“game”> <input type="checkbox" id="pause-button"></input> <label for="pause-button"></label> [...] <div class="pause-container"></div>

</main>

.pause-container {display: none;background-color: black;opacity: 0.7;

}

#pause-button:checked ~ .pause-container {display: block;

}

.pause-container

.pause-container

.pause-container:before

Como colocar instruções?

<div class="container"><input id="intro" type="checkbox">

<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 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>

div .container input #intro

section .intro h2 p label for=intro

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; }

div .container input #intro

section .intro h2 p label for=intro

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; }

div .container input #intro

section .intro h2 p label for=intro

div .container input #intro

section .intro h2 p label for=intro

#intro:checked ~ .intro { display: none; }

div .container input #intro

section .intro h2 p label for=intro

<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>

#intro:checked + #rules:checked ~ .rules { display: none; }

http://fernandabernardo.com.br/space-game/

vw, vh, vmin, vmax cursor box-sizing animation z-index seletores counter tabindex

• 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

http://fernandabernardo.com.br

@Feh_Bernardo

http://fernandabernardo.com.br

@Feh_Bernardo

PARE

PARE

PENSE

PARE

PENSE

DIVIRTA-SE

PARE

PENSE

DIVIRTA-SE

APRENDA

PARE

PENSE

DIVIRTA-SE

APRENDA

IMPLEMENTE

PARE

PENSE

DIVIRTA-SE

APRENDA

IMPLEMENTE

COMPARTILHE