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": [
"warn",
{
code: 120
code: 200
}
],
"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 css from './pokemon-shuffle.module.styl'
interface Props {
itemCount: number
boardSize: number
}
interface Cell {
id: number
id2: number
@ -20,18 +26,14 @@ interface States {
combo: number
comboMax: number
cursorPos: {x: number, y: number}
hitBoss: boolean
boss: {
hp: number
id: number
}
}
// up by 1 because of `1`
const ITEM_COUNT = 2 + 1
const BOARD_SIZE = 6
let n = BOARD_SIZE
export default class PokemonShuffle extends React.Component<unknown, States> {
export default class PokemonShuffle extends React.Component<Props, States> {
public state: States = {
items: [[]],
@ -40,21 +42,33 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
combo: 0,
comboMax: 0,
cursorPos: {x: 0, y: 0},
hitBoss: false,
boss: {
hp: 10e3,
hp: 10e4,
id: 2
}
}
private n = this.props.boardSize
public async componentDidMount() {
await this.start()
const boss = document.querySelector<HTMLElement>(`.${css.boss}`)
console.log(boss)
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)
})
}
public render = () => (
<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>
<li><Text>Tour: {this.state.turn}</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.cell,
css.noAnimation,
css.boss
css.boss,
[css.loading, this.state.hitBoss]
)}>
</Text>
</Col>
@ -116,7 +131,8 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
{this.state.movingItem && (
<div className={css.hoverItem} style={{
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)}>
<div></div>
@ -150,10 +166,10 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
loading: true,
// generate datas
items: Array
.from(Array(BOARD_SIZE))
.from(Array(this.props.boardSize))
.map(
() => Array.from(Array(BOARD_SIZE))
.map(() => ({id: random(0, ITEM_COUNT), id2: n++}))
() => Array.from(Array(this.props.boardSize))
.map(() => ({id: random(0, this.props.itemCount), id2: this.n++}))
)
})
// 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,
damage: this.state.damage + newPoints,
combo,
comboMax
comboMax,
hitBoss: true
})
}
return !!checkupCount
@ -329,13 +346,13 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
const cell = items[0][x]
if (!cell) {
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
if (needContinue) {
await this.asyncSetState({items})
await this.asyncSetState({items, hitBoss: false})
if (!initial) {
await wait(300)
}
@ -392,7 +409,7 @@ function calculateScore(len: number, combo: number) {
score *= 1.1
}
if (combo >= 5 && combo <= 9) {
score *= 1.1
score *= 1.15
}
if (combo >= 10 && combo <= 24) {
score *= 1.2
@ -428,3 +445,15 @@ function random(min = 0, max = 100): number {
function wait(time: number): Promise<void> {
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
position relative
transition filter .5s ease-in-out
transition filter .3s ease-in-out
&.loading .cell
&.loading .cell:not(.explode)
filter brightness(0.5)
.cellParent
@ -22,15 +22,24 @@ $iconSize = 121px
border-radius 16px
.table
background #7E6E5E
background #80715E
border-spacing 8px
border-radius 16px
border-radius 24px
border solid white 4px
.boss
// margin auto
transform scale(3)
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
width $iconSize
@ -38,7 +47,7 @@ $iconSize = 121px
height $iconSize
background-image url('/assets/pokemon-shuffle/icons.png')
&:not(.noAnimation)
animation idleAnimation ease-in-out 1s
animation idleAnimation ease-in-out 2s
animation-iteration-count infinite
transform-origin 50% 50%
for num in (0..810)
@ -98,16 +107,14 @@ $iconSize = 121px
transition width .3s ease-in-out
@keyframes idleAnimation
0%
transform rotate(0)
20%
10%
transform rotate(-10deg)
40%
20%
transform rotate(10deg)
60%
25%
transform rotate(-5deg)
80%
transform rotate(5deg)
0%
30%
100%
transform rotate(0)
@ -133,13 +140,38 @@ $iconSize = 121px
20%
transform scale(1.3)
filter brightness(1.5)
filter brightness(1.2)
100%
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