Signed-off-by: Avior <florian.bouillon@delta-wings.net>
This commit is contained in:
Florian Bouillon 2021-05-27 22:57:53 +02:00
parent 7b70150b57
commit a9e6a70cd3
Signed by: Florian Bouillon
GPG Key ID: 50BD648F12C86AB6
4 changed files with 93 additions and 32 deletions

View File

@ -138,7 +138,7 @@ module.exports = {
"max-len": [ "max-len": [
"warn", "warn",
{ {
code: 120 code: 200
} }
], ],
"new-parens": "error", "new-parens": "error",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 595 B

After

Width:  |  Height:  |  Size: 361 B

View File

@ -1,7 +1,13 @@
import { Button, Table, Text, Util, NotificationManager, Col, Row } from '@dzeio/components' import { Button, Text, Util, NotificationManager, Col, Row, Input } from '@dzeio/components'
import { GetServerSideProps } from 'next'
import React, { MouseEvent as ReactMouseEvent } from 'react' import React, { MouseEvent as ReactMouseEvent } from 'react'
import css from './pokemon-shuffle.module.styl' import css from './pokemon-shuffle.module.styl'
interface Props {
itemCount: number
boardSize: number
}
interface Cell { interface Cell {
id: number id: number
id2: number id2: number
@ -20,18 +26,14 @@ interface States {
combo: number combo: number
comboMax: number comboMax: number
cursorPos: {x: number, y: number} cursorPos: {x: number, y: number}
hitBoss: boolean
boss: { boss: {
hp: number hp: number
id: number id: number
} }
} }
// up by 1 because of `1` export default class PokemonShuffle extends React.Component<Props, States> {
const ITEM_COUNT = 2 + 1
const BOARD_SIZE = 6
let n = BOARD_SIZE
export default class PokemonShuffle extends React.Component<unknown, States> {
public state: States = { public state: States = {
items: [[]], items: [[]],
@ -40,21 +42,33 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
combo: 0, combo: 0,
comboMax: 0, comboMax: 0,
cursorPos: {x: 0, y: 0}, cursorPos: {x: 0, y: 0},
hitBoss: false,
boss: { boss: {
hp: 10e3, hp: 10e4,
id: 2 id: 2
} }
} }
private n = this.props.boardSize
public async componentDidMount() { public async componentDidMount() {
await this.start() await this.start()
const boss = document.querySelector<HTMLElement>(`.${css.boss}`)
console.log(boss)
this.setState({ this.setState({
boss: Object.assign(this.state.boss, {pos: [boss?.offsetTop ?? 0, boss?.offsetLeft ?? 0]}),
comboMax: parseInt(window.localStorage.getItem('pokemon-shuffle/comboMax') ?? '0', 10) comboMax: parseInt(window.localStorage.getItem('pokemon-shuffle/comboMax') ?? '0', 10)
}) })
} }
public render = () => ( public render = () => (
<main> <main>
<form method="GET">
<Input name="boardSize" type="number" placeholder="Nombre de lignes" defaultValue={this.props.boardSize} max={10} />
<Input name="itemCount" type="number" placeholder="Nombre de pokémon différents" defaultValue={this.props.itemCount - 1} max={810} />
<Button>Changer</Button>
</form>
<ul> <ul>
<li><Text>Tour: {this.state.turn}</Text></li> <li><Text>Tour: {this.state.turn}</Text></li>
<li><Text>Combo: {this.state.combo}, Max: {this.state.comboMax}</Text></li> <li><Text>Combo: {this.state.combo}, Max: {this.state.comboMax}</Text></li>
@ -68,7 +82,8 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
css[`icon-${this.state.boss.id}`], css[`icon-${this.state.boss.id}`],
css.cell, css.cell,
css.noAnimation, css.noAnimation,
css.boss css.boss,
[css.loading, this.state.hitBoss]
)}> )}>
</Text> </Text>
</Col> </Col>
@ -116,7 +131,8 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
{this.state.movingItem && ( {this.state.movingItem && (
<div className={css.hoverItem} style={{ <div className={css.hoverItem} style={{
left: this.state.cursorPos.x, left: this.state.cursorPos.x,
top: this.state.cursorPos.y top: this.state.cursorPos.y,
// transform: 'scale(2)'
}}> }}>
<Text className={Util.buildClassName(css[`icon-${this.state.movingItem.cell?.id}`], css.cell)}> <Text className={Util.buildClassName(css[`icon-${this.state.movingItem.cell?.id}`], css.cell)}>
<div></div> <div></div>
@ -150,10 +166,10 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
loading: true, loading: true,
// generate datas // generate datas
items: Array items: Array
.from(Array(BOARD_SIZE)) .from(Array(this.props.boardSize))
.map( .map(
() => Array.from(Array(BOARD_SIZE)) () => Array.from(Array(this.props.boardSize))
.map(() => ({id: random(0, ITEM_COUNT), id2: n++})) .map(() => ({id: random(0, this.props.itemCount), id2: this.n++}))
) )
}) })
// Quickly calculate everythings to make it look like it was perfecly generated // Quickly calculate everythings to make it look like it was perfecly generated
@ -280,7 +296,8 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
items, items,
damage: this.state.damage + newPoints, damage: this.state.damage + newPoints,
combo, combo,
comboMax comboMax,
hitBoss: true
}) })
} }
return !!checkupCount return !!checkupCount
@ -329,13 +346,13 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
const cell = items[0][x] const cell = items[0][x]
if (!cell) { if (!cell) {
needContinue = true needContinue = true
items[0][x] = {id: random(0, ITEM_COUNT), id2: n++, justSpawned: true} items[0][x] = {id: random(0, this.props.itemCount), id2: this.n++, justSpawned: true}
} }
} }
// Need to wait for the falling animation // Need to wait for the falling animation
if (needContinue) { if (needContinue) {
await this.asyncSetState({items}) await this.asyncSetState({items, hitBoss: false})
if (!initial) { if (!initial) {
await wait(300) await wait(300)
} }
@ -392,7 +409,7 @@ function calculateScore(len: number, combo: number) {
score *= 1.1 score *= 1.1
} }
if (combo >= 5 && combo <= 9) { if (combo >= 5 && combo <= 9) {
score *= 1.1 score *= 1.15
} }
if (combo >= 10 && combo <= 24) { if (combo >= 10 && combo <= 24) {
score *= 1.2 score *= 1.2
@ -428,3 +445,15 @@ function random(min = 0, max = 100): number {
function wait(time: number): Promise<void> { function wait(time: number): Promise<void> {
return new Promise((res) => setTimeout(() => res(), time)) return new Promise((res) => setTimeout(() => res(), time))
} }
export const getServerSideProps: GetServerSideProps<Props> = async (ctx) => {
const { boardSize, itemCount } = ctx.query as Record<string, string>
return {
props: {
// add 1 to suppress the `?`
itemCount: itemCount ? parseInt(itemCount, 10) + 1 : 7,
boardSize: boardSize ? parseInt(boardSize, 10) : 7
}
}
}

View File

@ -7,9 +7,9 @@ $iconSize = 121px
.table .table
position relative position relative
transition filter .5s ease-in-out transition filter .3s ease-in-out
&.loading .cell &.loading .cell:not(.explode)
filter brightness(0.5) filter brightness(0.5)
.cellParent .cellParent
@ -22,15 +22,24 @@ $iconSize = 121px
border-radius 16px border-radius 16px
.table .table
background #7E6E5E background #80715E
border-spacing 8px border-spacing 8px
border-radius 16px border-radius 24px
border solid white 4px border solid white 4px
.boss .boss
// margin auto // margin auto
transform scale(3) transform scale(3)
margin ($iconSize)px auto margin ($iconSize)px auto
animation bossIdleAnimation ease-in-out 2.25s
animation-iteration-count infinite
&.loading
animation bossHitAnimation ease-in-out .5s
animation-iteration-count 1
transform-origin 50% 50%
animation-fill-mode forwards
.cell .cell
width $iconSize width $iconSize
@ -38,7 +47,7 @@ $iconSize = 121px
height $iconSize height $iconSize
background-image url('/assets/pokemon-shuffle/icons.png') background-image url('/assets/pokemon-shuffle/icons.png')
&:not(.noAnimation) &:not(.noAnimation)
animation idleAnimation ease-in-out 1s animation idleAnimation ease-in-out 2s
animation-iteration-count infinite animation-iteration-count infinite
transform-origin 50% 50% transform-origin 50% 50%
for num in (0..810) for num in (0..810)
@ -98,16 +107,14 @@ $iconSize = 121px
transition width .3s ease-in-out transition width .3s ease-in-out
@keyframes idleAnimation @keyframes idleAnimation
0% 10%
transform rotate(0)
20%
transform rotate(-10deg) transform rotate(-10deg)
40% 20%
transform rotate(10deg) transform rotate(10deg)
60% 25%
transform rotate(-5deg) transform rotate(-5deg)
80% 0%
transform rotate(5deg) 30%
100% 100%
transform rotate(0) transform rotate(0)
@ -133,13 +140,38 @@ $iconSize = 121px
20% 20%
transform scale(1.3) transform scale(1.3)
filter brightness(1.5) filter brightness(1.2)
100% 100%
transform scale(0) transform scale(0)
filter brightness(1.2) filter brightness(1)
@keyframes bossHitAnimation
25%
transform scale(3) rotate(15deg)
75%
transform scale(3) rotate(-15deg)
0%
100%
transform scale(3) rotate(-0deg)
$bossIdleScaleY = 2.85
@keyframes bossIdleAnimation
0%
50%
transform translate(0px,0px) scaleX(3) scaleY(3)
15%
transform translate(0px,14px) scaleX(3) scaleY($bossIdleScaleY)
20%
30%
transform translate(0px,-11px) scaleX(3) scaleY(3)
25%
transform translate(0px,-25px) scaleX(3) scaleY($bossIdleScaleY)
35%
transform translate(0px,24px) scaleX(3) scaleY($bossIdleScaleY)
@keyframes spawnAnimation @keyframes spawnAnimation