Signed-off-by: Avior <florian.bouillon@delta-wings.net>
This commit is contained in:
Florian Bouillon 2021-05-27 20:39:01 +02:00
parent 23cf942034
commit 7b70150b57
Signed by: Florian Bouillon
GPG Key ID: 50BD648F12C86AB6
3 changed files with 150 additions and 49 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

View File

@ -1,4 +1,4 @@
import { Button, Table, Text, Util, NotificationManager } from '@dzeio/components' import { Button, Table, Text, Util, NotificationManager, Col, Row } from '@dzeio/components'
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'
@ -20,9 +20,14 @@ interface States {
combo: number combo: number
comboMax: number comboMax: number
cursorPos: {x: number, y: number} cursorPos: {x: number, y: number}
boss: {
hp: number
id: number
}
} }
const ITEM_COUNT = 4 // up by 1 because of `1`
const ITEM_COUNT = 2 + 1
const BOARD_SIZE = 6 const BOARD_SIZE = 6
let n = BOARD_SIZE let n = BOARD_SIZE
@ -34,11 +39,18 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
turn: 0, turn: 0,
combo: 0, combo: 0,
comboMax: 0, comboMax: 0,
cursorPos: {x: 0, y: 0} cursorPos: {x: 0, y: 0},
boss: {
hp: 10e3,
id: 2
}
} }
public async componentDidMount() { public async componentDidMount() {
await this.start() await this.start()
this.setState({
comboMax: parseInt(window.localStorage.getItem('pokemon-shuffle/comboMax') ?? '0', 10)
})
} }
public render = () => ( public render = () => (
@ -48,7 +60,29 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
<li><Text>Combo: {this.state.combo}, Max: {this.state.comboMax}</Text></li> <li><Text>Combo: {this.state.combo}, Max: {this.state.comboMax}</Text></li>
<li><Text>Points: {this.state.damage}</Text></li> <li><Text>Points: {this.state.damage}</Text></li>
</ul> </ul>
<Table > <Row align="center" >
<Col>
<Row direction="column" justify="center" align="center" >
<Col nogrow>
<Text className={Util.buildClassName(
css[`icon-${this.state.boss.id}`],
css.cell,
css.noAnimation,
css.boss
)}>
</Text>
</Col>
<Col nogrow>
<div className={css.bossBar}>
<div>
<div style={{width: `${Math.max(0, 100 - (100 * this.state.damage / this.state.boss.hp))}%`}}></div>
</div>
</div>
</Col>
</Row>
</Col>
<Col>
<table style={{margin: 'auto'}} className={css.table}>
<tbody className={Util.buildClassName(css.table, [css.loading, this.state.loading])}> <tbody className={Util.buildClassName(css.table, [css.loading, this.state.loading])}>
{this.state.items.map((row, y) => ( {this.state.items.map((row, y) => (
<tr key={y}> <tr key={y}>
@ -67,7 +101,6 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
[css.justSpawned, cell.justSpawned], [css.justSpawned, cell.justSpawned],
[css.explode, cell.horizontalCombo || cell.verticalCombo] [css.explode, cell.horizontalCombo || cell.verticalCombo]
)}> )}>
<div></div>
</Text> </Text>
)} )}
</td> </td>
@ -75,7 +108,10 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
</tr> </tr>
))} ))}
</tbody> </tbody>
</Table> </table>
</Col>
</Row>
<Button onClick={this.start}>Start!</Button> <Button onClick={this.start}>Start!</Button>
{this.state.movingItem && ( {this.state.movingItem && (
<div className={css.hoverItem} style={{ <div className={css.hoverItem} style={{
@ -92,9 +128,10 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
</Text> </Text>
<ul> <ul>
<li><Text>Faire que les clear ce fasse de manière Async</Text></li> <li><Text>Faire que les clear ce fasse de manière Async</Text></li>
<li><Text>Meilleurs Animation de destruction</Text></li>
<li><Text>Annuler le mouvement si rien n&apos;est claim</Text></li>
<li><Text>Utiliser le système de damages de Pokémon Shuffle https://bulbapedia.bulbagarden.net/wiki/Pok%C3%A9mon_Shuffle#Damage</Text></li> <li><Text>Utiliser le système de damages de Pokémon Shuffle https://bulbapedia.bulbagarden.net/wiki/Pok%C3%A9mon_Shuffle#Damage</Text></li>
<li><Text>Mode VS (Voir si on fait en local et/ou en ligne avec le Websocket)</Text></li>
<li><Text>Système de classement en ligne (maybe avec un compte pour eviter lees hackers lol)</Text></li>
<li><Text>Combat de boss a la Pokémon Shuffle lol</Text></li>
</ul> </ul>
<NotificationManager /> <NotificationManager />
</main> </main>
@ -142,13 +179,29 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
document.removeEventListener('mousemove', this.mouveMove) document.removeEventListener('mousemove', this.mouveMove)
const items = this.state.items const items = this.state.items
const temp = items[y][x] const temp = items[y][x]
console.log(temp, this.state.movingItem)
items[y][x] = this.state.movingItem.cell items[y][x] = this.state.movingItem.cell
items[this.state.movingItem.y][this.state.movingItem.x] = temp const tmpX = this.state.movingItem.x
const tmpY = this.state.movingItem.y
if (temp) {
items[tmpY][tmpX] = temp
}
this.setState({ this.setState({
movingItem: undefined, movingItem: undefined,
loading: true, loading: true,
items items
}, () => this.calculate()) }, async () => {
const revert = !await this.calculate()
if (revert) {
const movingItem = items[y][x]
items[y][x] = temp
items[tmpY][tmpX] = movingItem
this.setState({
items,
turn: this.state.turn - 1
})
}
})
} }
} }
@ -161,7 +214,7 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
* Check if items has combos * Check if items has combos
* @returns if items were changed * @returns if items were changed
*/ */
private async checkup(): Promise<boolean> { private async checkup(initial: boolean): Promise<boolean> {
const items = this.state.items const items = this.state.items
let checkupCount = 0 let checkupCount = 0
let newPoints = 0 let newPoints = 0
@ -175,7 +228,7 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
if (!cell.horizontalCombo && !(cell.isFalling || cell.justSpawned)) { if (!cell.horizontalCombo && !(cell.isFalling || cell.justSpawned)) {
let sameCount = 0 let sameCount = 0
while((x + ++sameCount) < items.length) { while((x + ++sameCount) < items.length) {
console.log(y + sameCount, x) // console.log(y + sameCount, x)
const tmp = row[x + sameCount] const tmp = row[x + sameCount]
if (!tmp || tmp.id !== id || tmp.isFalling || tmp.justSpawned) {break} if (!tmp || tmp.id !== id || tmp.isFalling || tmp.justSpawned) {break}
} }
@ -219,11 +272,15 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
// If combos were found // If combos were found
if (checkupCount) { if (checkupCount) {
const combo = this.state.combo + checkupCount const combo = this.state.combo + checkupCount
const comboMax = Math.max(this.state.comboMax, combo)
if (comboMax === combo && !initial) {
window.localStorage.setItem('pokemon-shuffle/comboMax', comboMax.toString())
}
await this.asyncSetState({ await this.asyncSetState({
items, items,
damage: this.state.damage + newPoints, damage: this.state.damage + newPoints,
combo, combo,
comboMax: Math.max(this.state.comboMax, combo) comboMax
}) })
} }
return !!checkupCount return !!checkupCount
@ -245,6 +302,7 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
})) }))
let needContinue = false let needContinue = false
let hadTurn = false
do { do {
// Make items fall // Make items fall
needContinue = false needContinue = false
@ -284,9 +342,10 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
} }
// Checkup if there is combos // Checkup if there is combos
const checkup = await this.checkup() const checkup = await this.checkup(initial)
if (!checkup && !needContinue) { if (!checkup && !needContinue) {
return await this.endTurn({items}) await this.endTurn({items})
break
} }
// Clear items // Clear items
@ -304,13 +363,15 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
if (hasCleared && !initial) { if (hasCleared && !initial) {
await wait(500) await wait(500)
} }
hadTurn = true
} while (needContinue) } while (needContinue)
return hadTurn
} }
} }
function calculateScore(len: number, combo: number) { function calculateScore(len: number, combo: number) {
let score = len * 40 // currently the damage let score = (len - 2) * 40 // currently the damage
if (len > 3) { if (len > 3) {
switch (len) { switch (len) {
case 4: case 4:
@ -355,8 +416,13 @@ function calculateScore(len: number, combo: number) {
return score return score
} }
function random(min = 0, max = 100) { function random(min = 0, max = 100): number {
return Math.floor(Math.random() * (max - min) + min) const r = Math.floor(Math.random() * (max - min) + min)
// dont return 1 as it is the `?`
if (r === 1) {
return random(min, max)
}
return r
} }
function wait(time: number): Promise<void> { function wait(time: number): Promise<void> {

View File

@ -17,18 +17,33 @@ $iconSize = 121px
width $iconSize width $iconSize
padding 0 !important padding 0 !important
height $iconSize height $iconSize
box-shadow inset 0 0 8px 1px black
background-image url('/assets/pokemon-shuffle/cell-bg.png')
border-radius 16px
.table
background #7E6E5E
border-spacing 8px
border-radius 16px
border solid white 4px
.boss
// margin auto
transform scale(3)
margin ($iconSize)px auto
.cell .cell
width $iconSize width $iconSize
transition filter .5s ease-in-out transition filter .5s ease-in-out
height $iconSize height $iconSize
background-image url('/assets/pokemon-shuffle/icons.png') background-image url('/assets/pokemon-shuffle/icons.png')
&:not(.noAnimation)
animation idleAnimation ease-in-out 1s animation idleAnimation ease-in-out 1s
animation-iteration-count infinite animation-iteration-count infinite
transform-origin 50% 50% transform-origin 50% 50%
for num in (0..30) for num in (0..810)
&.icon-{num} &.icon-{num}
background-position ((num + 1) * $iconSize) 0px background-position right ((num % 30) * $iconSize) bottom (math(num / 30, 'trunc') * $iconSize + $iconSize)px
&.isFalling &.isFalling
position absolute position absolute
@ -58,10 +73,30 @@ $iconSize = 121px
animation-fill-mode forwards animation-fill-mode forwards
&.justSpawned &.justSpawned
animation spawnAnimation ease-in-out 0.5s animation spawnAnimation ease-in-out .3s
animation-iteration-count 1 animation-iteration-count 1
transform-origin 50% 50% transform-origin 50% 50%
.bossBar
width 300px
border 4px solid white
padding 3px
$height = 10px
height $height + @padding[0] * 2 + @border[0] * 2
background #ED869F
border-radius 16px
> div
background #7E7C7B
width 100%
border-radius 16px
height $height
> div
background linear-gradient(to bottom, #FFCAB1, #E7A09E)
border-radius 16px
height inherit
transition width .3s ease-in-out
@keyframes idleAnimation @keyframes idleAnimation
0% 0%
transform rotate(0) transform rotate(0)
@ -98,11 +133,11 @@ $iconSize = 121px
20% 20%
transform scale(1.3) transform scale(1.3)
filter brightness(1.7) filter brightness(1.5)
100% 100%
transform scale(0) transform scale(0)
filter brightness(1.5) filter brightness(1.2)