mirror of
https://github.com/Aviortheking/games.git
synced 2025-04-22 19:02:09 +00:00
Updated code
Signed-off-by: Avior <florian.bouillon@delta-wings.net>
This commit is contained in:
parent
f47ab40ffd
commit
cbfae26516
117
dzeio.next.config.js
Normal file
117
dzeio.next.config.js
Normal file
@ -0,0 +1,117 @@
|
||||
// V1.1.1 - Added futures blurry Placeholder and left optimizedLoading enabled
|
||||
// Updated to commit from 2021-05-18
|
||||
// https://github.com/vercel/next.js/commits/canary/packages/next/next-server/server/config-shared.ts
|
||||
/**
|
||||
* @type {import("next/dist/next-server/server/config-shared").NextConfig & import("next/dist/next-server/server/config-shared").defaultConfig}
|
||||
*/
|
||||
const nextConfig = {
|
||||
// Experimentals
|
||||
experimental: {
|
||||
plugins: true,
|
||||
profiling: process.env.NODE_ENV === 'developpment',
|
||||
sprFlushToDisk: true,
|
||||
workerThreads: true,
|
||||
|
||||
pageEnv: true,
|
||||
optimizeImages: true,
|
||||
optimizeCss: true,
|
||||
|
||||
scrollRestoration: true,
|
||||
scriptLoader: true,
|
||||
stats: process.env.NODE_ENV === 'developpment',
|
||||
externalDir: true,
|
||||
|
||||
serialWebpackBuild: true,
|
||||
|
||||
conformance: true,
|
||||
|
||||
turboMode: true,
|
||||
eslint: true,
|
||||
// Bugged
|
||||
// https://github.com/vercel/next.js/issues/18913
|
||||
// reactRoot: true,
|
||||
enableBlurryPlaceholder: true,
|
||||
disableOptimizedLoading: false,
|
||||
},
|
||||
|
||||
// Non experimental config
|
||||
// target: 'serverless',
|
||||
poweredByHeader: false,
|
||||
trailingSlash: false,
|
||||
optimizeFonts: true,
|
||||
reactStrictMode: true,
|
||||
|
||||
// Futures
|
||||
future: {
|
||||
webpack5: true,
|
||||
strictPostcssConfiguration: true,
|
||||
excludeDefaultMomentLocales: true
|
||||
},
|
||||
|
||||
// Headers and rewrites
|
||||
async headers() {
|
||||
// CSS no CSP, x-xss-protection
|
||||
const CSP = {
|
||||
key: 'Content-Security-Policy',
|
||||
value:
|
||||
// default-src is set to self because prefetch-src is not working propelly see: https://bugs.chromium.org/p/chromium/issues/detail?id=801561
|
||||
"default-src 'self'; " +
|
||||
"frame-ancestors 'none'; " +
|
||||
"form-action 'self'; " +
|
||||
"manifest-src 'self'; " +
|
||||
"prefetch-src 'self'; " +
|
||||
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://stats.dzeio.com; " +
|
||||
"style-src 'self' 'unsafe-inline'; " +
|
||||
"img-src data: 'self'; " +
|
||||
"font-src 'self'; " +
|
||||
"connect-src 'self' https://stats.dzeio.com; " +
|
||||
"base-uri 'self';"
|
||||
}
|
||||
const XXssProtection = {
|
||||
key: 'X-XSS-Protection',
|
||||
value: '1; mode=block'
|
||||
}
|
||||
// JS no x-xss-protection
|
||||
|
||||
const headers = [{
|
||||
key: 'X-Frame-Options',
|
||||
value: 'DENY'
|
||||
}, {
|
||||
key: 'X-Content-Type-Options',
|
||||
value: 'nosniff'
|
||||
}, {
|
||||
key: 'Referrer-Policy',
|
||||
value: 'strict-origin-when-cross-origin'
|
||||
}, {
|
||||
key: 'Permissions-Policy',
|
||||
value: 'geolocation=(), microphone=(), interest-cohort=()'
|
||||
}, {
|
||||
key: 'Strict-Transport-Security',
|
||||
value: 'max-age=63072000; includeSubDomains; preload'
|
||||
}, {
|
||||
key: 'X-Download-Options',
|
||||
value: 'noopen'
|
||||
}, {
|
||||
key: 'Expect-CT',
|
||||
value: 'max-age=86400, enforce'
|
||||
}]
|
||||
const excludedExtensions = ['js', 'css', 'json', 'ico', 'png']
|
||||
.map((ext) => `(?!\\.${ext}$)`).join('|')
|
||||
return [{
|
||||
source: `/:path*((?!^\\/_next\\/image)|${excludedExtensions})`,
|
||||
headers: [...headers, XXssProtection, CSP]
|
||||
}, {
|
||||
source: '/',
|
||||
headers: [...headers, XXssProtection, CSP]
|
||||
}, {
|
||||
// No CSP, XXssProtection
|
||||
source: `/:path*(\\.${excludedExtensions}$)`,
|
||||
headers: headers
|
||||
}, {
|
||||
// No CSP, XXssProtection
|
||||
source: '/_next/image',
|
||||
headers: headers
|
||||
}]
|
||||
},
|
||||
}
|
||||
module.exports = nextConfig
|
@ -1,10 +1,13 @@
|
||||
const stylus = require('@zeit/next-stylus')
|
||||
const css = require('@zeit/next-css')
|
||||
// Add support for Stylus/LESS
|
||||
const preCSS = require('next-pre-css')
|
||||
// Use Compose plugin for easier maintenance
|
||||
const withPlugins = require('next-compose-plugins')
|
||||
|
||||
const {PHASE_DEVELOPMENT_SERVER} = require('next/constants')
|
||||
const nextConfig = require('./dzeio.next.config')
|
||||
|
||||
module.exports = withPlugins([
|
||||
[stylus, {
|
||||
[preCSS, {
|
||||
cssModules: true,
|
||||
cssLoaderOptions: {
|
||||
localIdentName: "[hash:base64:6]",
|
||||
@ -14,9 +17,7 @@ module.exports = withPlugins([
|
||||
localIdentName: "[path][name]__[local]"
|
||||
}
|
||||
}
|
||||
}],
|
||||
[css, {
|
||||
cssModules: false
|
||||
}]
|
||||
]
|
||||
],
|
||||
nextConfig
|
||||
)
|
||||
|
19
package.json
19
package.json
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@dzeio/url-shortener",
|
||||
"name": "@avior/games",
|
||||
"version": "1.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@ -10,31 +10,32 @@
|
||||
"test": "jest --config jext.config.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dzeio/components": "^0.2.1",
|
||||
"@zeit/next-css": "^1.0.1",
|
||||
"@zeit/next-stylus": "^1.0.1",
|
||||
"@dzeio/components": "^0.10.1",
|
||||
"critters": "^0.0.10",
|
||||
"easy-sitemap": "^1.0.0",
|
||||
"next": "^10.0.3",
|
||||
"next-compose-plugins": "^2.2.0",
|
||||
"next-plausible": "^1.6.1",
|
||||
"next-pre-css": "^1.0.0",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-feather": "^2.0.9",
|
||||
"stylus": "^0.54.7",
|
||||
"stylus-loader": "^6.0.0",
|
||||
"typescript": "^4.1.3",
|
||||
"webpack": "^4.46.0"
|
||||
"webpack": "^5.37.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.8.7",
|
||||
"@types/favicons": "^6.2.0",
|
||||
"@types/node": "^14.0.0",
|
||||
"@types/node": "^15.6.0",
|
||||
"@types/react": "^17.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.14.1",
|
||||
"@typescript-eslint/parser": "^4.14.1",
|
||||
"babel-preset-react-app": "^10.0.0",
|
||||
"eslint": "^7.1.0",
|
||||
"eslint-config-next": "^10.2.2",
|
||||
"eslint-plugin-react": "^7.18.3",
|
||||
"favicons": "^6.2.0",
|
||||
"ts-node": "^9.1.1",
|
||||
"vercel": "^21.2.2"
|
||||
"vercel": "^22.0.1"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react'
|
||||
import App from 'next/app'
|
||||
|
||||
import PlausibleProvider from 'next-plausible'
|
||||
import '@dzeio/components/style.css'
|
||||
|
||||
export default class CApp extends App {
|
||||
@ -8,6 +9,14 @@ export default class CApp extends App {
|
||||
public render() {
|
||||
const { Component, pageProps } = this.props
|
||||
|
||||
return(<Component {...pageProps} />)
|
||||
return (
|
||||
<PlausibleProvider
|
||||
domain="games.avior.me"
|
||||
trackOutboundLinks
|
||||
integrity="sha384-Bwk7iNMK9H56PgZeINNhN5Mk42LZoNIXe6Ztx5lfALsrTkNWC9yh2J2UFO0xShAv"
|
||||
>
|
||||
<Component {...pageProps} />
|
||||
</PlausibleProvider>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Link, Text } from '@dzeio/components'
|
||||
import React from 'react'
|
||||
|
||||
import { Link, Text } from '@dzeio/components'
|
||||
|
||||
export default class Index extends React.Component {
|
||||
|
||||
public render = () => (
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { Button, Table, Text, Util } from '@dzeio/components'
|
||||
import React from 'react'
|
||||
import css from './pokemon-shuffle.styl'
|
||||
import { Button, Table, Text, Util, NotificationManager } from '@dzeio/components'
|
||||
import React, { MouseEvent as ReactMouseEvent } from 'react'
|
||||
import css from './pokemon-shuffle.module.styl'
|
||||
|
||||
interface Cell {
|
||||
id: number
|
||||
id2: number
|
||||
horizontalCombo?: true
|
||||
verticalCombo?: true
|
||||
justSpawned?: true
|
||||
@ -14,7 +15,7 @@ interface States {
|
||||
items: Array<Array<Cell | undefined>>
|
||||
loading?: true
|
||||
movingItem?: {x: number, y: number, cell: Cell}
|
||||
points: number
|
||||
damage: number
|
||||
turn: number
|
||||
combo: number
|
||||
comboMax: number
|
||||
@ -29,30 +30,35 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
|
||||
|
||||
public state: States = {
|
||||
items: [[]],
|
||||
points: 0,
|
||||
damage: 0,
|
||||
turn: 0,
|
||||
combo: 0,
|
||||
comboMax: 0,
|
||||
cursorPos: {x: 0, y: 0}
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
await this.start()
|
||||
}
|
||||
|
||||
public render = () => (
|
||||
<main>
|
||||
<ul>
|
||||
<li><Text>Tour: {this.state.turn}</Text></li>
|
||||
<li><Text>Combo: {this.state.combo}, Max: {this.state.comboMax}</Text></li>
|
||||
<li><Text>Points: {this.state.points}</Text></li>
|
||||
<li><Text>Points: {this.state.damage}</Text></li>
|
||||
</ul>
|
||||
<Table >
|
||||
<tbody className={`${css.table} ${this.state.loading ? css.loading : ''}`}>
|
||||
<tbody className={Util.buildClassName(css.table, [css.loading, this.state.loading])}>
|
||||
{this.state.items.map((row, y) => (
|
||||
<tr key={y}>
|
||||
{row.map((cell, x) => (
|
||||
<td
|
||||
key={cell?.isFalling ? n++ : x}
|
||||
key={cell?.id2 ?? x}
|
||||
onClick={this.onCellClick(x, y)}
|
||||
className={css.cellParent}
|
||||
>
|
||||
{/* <Text>{JSON.stringify(cell)}</Text> */}
|
||||
{cell && (
|
||||
<Text className={Util.buildClassName(
|
||||
css[`icon-${cell.id}`],
|
||||
@ -70,16 +76,11 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
|
||||
))}
|
||||
</tbody>
|
||||
</Table>
|
||||
<Button onClick={() => this.calculate()}>Calculate!</Button>
|
||||
<Button onClick={() => this.start()}>Start!</Button>
|
||||
{/* <Input block type="textarea" value={JSON.stringify(this.state.items)}/> */}
|
||||
<Button onClick={this.start}>Start!</Button>
|
||||
{this.state.movingItem && (
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
<div className={css.hoverItem} style={{
|
||||
left: this.state.cursorPos.x,
|
||||
top: this.state.cursorPos.y,
|
||||
transform: 'translate(-50%, -50%)',
|
||||
pointerEvents: 'none'
|
||||
top: this.state.cursorPos.y
|
||||
}}>
|
||||
<Text className={Util.buildClassName(css[`icon-${this.state.movingItem.cell?.id}`], css.cell)}>
|
||||
<div></div>
|
||||
@ -90,46 +91,52 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
|
||||
TODO list:
|
||||
</Text>
|
||||
<ul>
|
||||
<li><Text>Lancement Initial sans combo possible</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'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>
|
||||
</ul>
|
||||
<NotificationManager />
|
||||
</main>
|
||||
)
|
||||
|
||||
private mouveMove = (ev: MouseEvent) => {
|
||||
this.setState({cursorPos: {
|
||||
x: ev.pageX,
|
||||
y: ev.pageY
|
||||
x: ev.clientX,
|
||||
y: ev.clientY
|
||||
}})
|
||||
}
|
||||
|
||||
private start() {
|
||||
private start = async () => {
|
||||
if (this.state.loading) {return}
|
||||
this.setState({
|
||||
await this.asyncSetState({
|
||||
loading: true,
|
||||
// generate datas
|
||||
items: Array
|
||||
.from(Array(BOARD_SIZE))
|
||||
.map(
|
||||
() => Array.from(Array(BOARD_SIZE))
|
||||
.map(() => ({id: random(0, ITEM_COUNT)}))
|
||||
.map(() => ({id: random(0, ITEM_COUNT), id2: n++}))
|
||||
)
|
||||
}, () => this.calculate())
|
||||
})
|
||||
// Quickly calculate everythings to make it look like it was perfecly generated
|
||||
await this.calculate(true)
|
||||
this.setState({turn: 1, damage: 0, comboMax: 0, combo: 0})
|
||||
}
|
||||
|
||||
private onCellClick = (x: number, y: number) => async () => {
|
||||
// console.log(x, y)
|
||||
private onCellClick = (x: number, y: number) => async (ev: ReactMouseEvent) => {
|
||||
if (this.state.loading) {
|
||||
return window.alert('Cant play while Calculating')
|
||||
return NotificationManager.addNotification('Cant play while Calculating')
|
||||
}
|
||||
if (!this.state.movingItem) {
|
||||
const cell = this.state.items[y][x]
|
||||
if (!cell) {
|
||||
return window.alert('Cant move nothing')
|
||||
return NotificationManager.addNotification('Cant move nothing')
|
||||
}
|
||||
document.addEventListener('mousemove', this.mouveMove)
|
||||
this.setState({movingItem: {x,y,cell}})
|
||||
this.state.items[y][x] = undefined
|
||||
this.mouveMove(ev.nativeEvent)
|
||||
return
|
||||
} else {
|
||||
document.removeEventListener('mousemove', this.mouveMove)
|
||||
@ -150,102 +157,97 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
|
||||
(res) => this.setState(states as States, () => res())
|
||||
)
|
||||
|
||||
private async calculate() {
|
||||
/**
|
||||
* Check if items has combos
|
||||
* @returns if items were changed
|
||||
*/
|
||||
private async checkup(): Promise<boolean> {
|
||||
const items = this.state.items
|
||||
let checkupCount = 0
|
||||
let newPoints = 0
|
||||
for (let y = 0; y < items.length; y++) {
|
||||
const row = items[y]
|
||||
for (let x = 0; x < row.length; x++) {
|
||||
const cell = row[x]
|
||||
if (!cell) {continue}
|
||||
const id = cell.id
|
||||
// Checkup horizontal
|
||||
if (!cell.horizontalCombo && !(cell.isFalling || cell.justSpawned)) {
|
||||
let sameCount = 0
|
||||
while((x + ++sameCount) < items.length) {
|
||||
console.log(y + sameCount, x)
|
||||
const tmp = row[x + sameCount]
|
||||
if (!tmp || tmp.id !== id || tmp.isFalling || tmp.justSpawned) {break}
|
||||
}
|
||||
if (sameCount >= 3) {
|
||||
checkupCount += 1
|
||||
let len = 0
|
||||
for (let i = x; i < (x + sameCount); i++) {
|
||||
const tmp = items[y][i]
|
||||
if (!tmp) {continue}
|
||||
tmp.horizontalCombo = true
|
||||
len++
|
||||
}
|
||||
newPoints += calculateScore(len, this.state.combo)
|
||||
|
||||
}
|
||||
}
|
||||
// Checkup Vertical
|
||||
if (!cell.verticalCombo && !(cell.isFalling || cell.justSpawned)) {
|
||||
let sameCount = 0
|
||||
while((y + ++sameCount) < items.length) {
|
||||
// console.log(y + sameCount, x)
|
||||
const tmp = items[y + sameCount][x]
|
||||
if (!tmp || tmp.id !== id || tmp.isFalling || tmp.justSpawned) {break}
|
||||
}
|
||||
if (sameCount >= 3) {
|
||||
checkupCount += 1
|
||||
let len = 0
|
||||
for (let i = y; i < (y + sameCount); i++) {
|
||||
const tmp = items[i][x]
|
||||
if (!tmp) {continue}
|
||||
tmp.verticalCombo = true
|
||||
len++
|
||||
}
|
||||
newPoints += calculateScore(len, this.state.combo)
|
||||
// console.log(x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If combos were found
|
||||
if (checkupCount) {
|
||||
const combo = this.state.combo + checkupCount
|
||||
await this.asyncSetState({
|
||||
items,
|
||||
damage: this.state.damage + newPoints,
|
||||
combo,
|
||||
comboMax: Math.max(this.state.comboMax, combo)
|
||||
})
|
||||
}
|
||||
return !!checkupCount
|
||||
}
|
||||
|
||||
private async endTurn(state?: Partial<States>) {
|
||||
await this.asyncSetState({...state, loading: undefined, turn: this.state.turn + 1, combo: 0})
|
||||
}
|
||||
|
||||
private async calculate(initial = false) {
|
||||
// remove combos
|
||||
const items = this.state.items.map((r) => r.map((c) => {
|
||||
if (!c) {
|
||||
return c
|
||||
}
|
||||
c.horizontalCombo = undefined
|
||||
c.verticalCombo = undefined
|
||||
delete c.horizontalCombo
|
||||
delete c.verticalCombo
|
||||
return c
|
||||
}))
|
||||
|
||||
let newPoints = 0
|
||||
|
||||
let checkupCount = 0
|
||||
// Checkup horizontal
|
||||
for (let y = 0; y < items.length; y++) {
|
||||
const row = items[y]
|
||||
for (let x = 0; x < row.length; x++) {
|
||||
const cell = row[x]
|
||||
if (!cell || cell.horizontalCombo) {continue}
|
||||
const id = cell.id
|
||||
let sameCount = 0
|
||||
while((x + ++sameCount) < items.length) {
|
||||
console.log(y + sameCount, x)
|
||||
const tmp = row[x + sameCount]
|
||||
if (!tmp || tmp.id !== id) {break}
|
||||
}
|
||||
if (sameCount >= 3) {
|
||||
checkupCount += 1
|
||||
for (let i = x; i < (x + sameCount); i++) {
|
||||
const tmp = items[y][i]
|
||||
if (!tmp) {continue}
|
||||
tmp.horizontalCombo = true
|
||||
newPoints++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check vertical
|
||||
for (let y = 0; y < items.length; y++) {
|
||||
const row = items[y]
|
||||
for (let x = 0; x < row.length; x++) {
|
||||
const cell = row[x]
|
||||
if (!cell || cell.verticalCombo) {continue}
|
||||
const id = cell.id
|
||||
let sameCount = 0
|
||||
while((y + ++sameCount) < items.length) {
|
||||
// console.log(y + sameCount, x)
|
||||
const tmp = items[y + sameCount][x]
|
||||
if (!tmp || tmp.id !== id) {break}
|
||||
}
|
||||
// if ((y + sameCount) > items.length) {
|
||||
// sameCount++
|
||||
// }
|
||||
if (sameCount >= 3) {
|
||||
checkupCount += 1
|
||||
for (let i = y; i < (y + sameCount); i++) {
|
||||
const tmp = items[i][x]
|
||||
if (!tmp) {continue}
|
||||
tmp.verticalCombo = true
|
||||
|
||||
newPoints++
|
||||
}
|
||||
// console.log(x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (checkupCount) {
|
||||
await this.asyncSetState({
|
||||
items,
|
||||
points: this.state.points + newPoints,
|
||||
combo: this.state.combo+checkupCount,
|
||||
comboMax: Math.max(this.state.comboMax, this.state.combo+checkupCount)
|
||||
})
|
||||
await new Promise((res) => setTimeout(res, 500))
|
||||
}
|
||||
|
||||
// return
|
||||
|
||||
// Clear items
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
||||
for (let y = 0; y < items.length; y++) {
|
||||
const row = items[y]
|
||||
for (let x = 0; x < row.length; x++) {
|
||||
const cell = row[x]
|
||||
if (!cell || (!cell.horizontalCombo && !cell.verticalCombo)) {continue}
|
||||
items[y][x] = undefined
|
||||
}
|
||||
}
|
||||
|
||||
let itemHasFallen = false
|
||||
let needNewTurn = false
|
||||
let needContinue = false
|
||||
do {
|
||||
// Make items fall
|
||||
itemHasFallen = false
|
||||
needContinue = false
|
||||
for (let y = (items.length - 1); y >= 0; y--) {
|
||||
const row = items[y]
|
||||
for (let x = 0; x < row.length; x++) {
|
||||
@ -256,37 +258,107 @@ export default class PokemonShuffle extends React.Component<unknown, States> {
|
||||
}
|
||||
if (cell && y+1 < row.length && !items[y+1][x]) {
|
||||
cell.isFalling = true
|
||||
needNewTurn = true
|
||||
itemHasFallen = true
|
||||
needContinue = true
|
||||
// Move cell down
|
||||
items[y+1][x] = cell
|
||||
items[y][x] = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fill to top lane
|
||||
// Fill the top lane
|
||||
for (let x = 0; x < items[0].length; x++) {
|
||||
const cell = items[0][x]
|
||||
if (!cell) {
|
||||
itemHasFallen = true
|
||||
items[0][x] = {id: random(0, ITEM_COUNT), justSpawned: true}
|
||||
needContinue = true
|
||||
items[0][x] = {id: random(0, ITEM_COUNT), id2: n++, justSpawned: true}
|
||||
}
|
||||
}
|
||||
if (itemHasFallen) {
|
||||
await this.asyncSetState({items})
|
||||
await new Promise((res) => setTimeout(res, 300))
|
||||
}
|
||||
} while (itemHasFallen)
|
||||
|
||||
// If an item has fallen re calculate
|
||||
if (needNewTurn) {
|
||||
this.setState({items}, () => this.calculate())
|
||||
return
|
||||
}
|
||||
this.setState({items, loading: undefined, turn: this.state.turn+1, combo: 0})
|
||||
// Need to wait for the falling animation
|
||||
if (needContinue) {
|
||||
await this.asyncSetState({items})
|
||||
if (!initial) {
|
||||
await wait(300)
|
||||
}
|
||||
}
|
||||
|
||||
// Checkup if there is combos
|
||||
const checkup = await this.checkup()
|
||||
if (!checkup && !needContinue) {
|
||||
return await this.endTurn({items})
|
||||
}
|
||||
|
||||
// Clear items
|
||||
let hasCleared = false
|
||||
for (const row of items) {
|
||||
for (let x = 0; x < row.length; x++) {
|
||||
const cell = row[x]
|
||||
if (!cell || (!cell.horizontalCombo && !cell.verticalCombo)) {continue}
|
||||
row[x] = undefined
|
||||
hasCleared = true
|
||||
needContinue = true
|
||||
}
|
||||
}
|
||||
|
||||
if (hasCleared && !initial) {
|
||||
await wait(500)
|
||||
}
|
||||
|
||||
} while (needContinue)
|
||||
}
|
||||
}
|
||||
|
||||
function calculateScore(len: number, combo: number) {
|
||||
let score = len * 40 // currently the damage
|
||||
if (len > 3) {
|
||||
switch (len) {
|
||||
case 4:
|
||||
score *= 1.5
|
||||
break
|
||||
case 5:
|
||||
score *= 2
|
||||
break
|
||||
case 6:
|
||||
score *= 3
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
if (combo > 1) {
|
||||
if (combo >= 2 && combo <= 4) {
|
||||
score *= 1.1
|
||||
}
|
||||
if (combo >= 5 && combo <= 9) {
|
||||
score *= 1.1
|
||||
}
|
||||
if (combo >= 10 && combo <= 24) {
|
||||
score *= 1.2
|
||||
}
|
||||
if (combo >= 25 && combo <= 49) {
|
||||
score *= 1.3
|
||||
}
|
||||
if (combo >= 50 && combo <= 74) {
|
||||
score *= 1.4
|
||||
}
|
||||
if (combo >= 75 && combo <= 99) {
|
||||
score *= 1.5
|
||||
}
|
||||
if (combo >= 100 && combo <= 199) {
|
||||
score *= 2
|
||||
}
|
||||
if (combo >= 200) {
|
||||
score *= 2.5
|
||||
}
|
||||
}
|
||||
return score
|
||||
}
|
||||
|
||||
function random(min = 0, max = 100) {
|
||||
return Math.floor(Math.random() * (max - min) + min)
|
||||
}
|
||||
|
||||
function wait(time: number): Promise<void> {
|
||||
return new Promise((res) => setTimeout(() => res(), time))
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
$iconSize = 121px
|
||||
|
||||
.hoverItem
|
||||
position fixed
|
||||
transform translate(-50%, -50%)
|
||||
pointer-events none
|
||||
|
||||
.table
|
||||
position relative
|
||||
transition filter .5s ease-in-out
|
||||
@ -21,28 +26,9 @@ $iconSize = 121px
|
||||
animation idleAnimation ease-in-out 1s
|
||||
animation-iteration-count infinite
|
||||
transform-origin 50% 50%
|
||||
&.icon-0
|
||||
background-position (1*$iconSize) 0px
|
||||
&.icon-1
|
||||
background-position (2*$iconSize) 0px
|
||||
&.icon-2
|
||||
background-position (3*$iconSize) 0px
|
||||
&.icon-3
|
||||
background-position (4*$iconSize) 0px
|
||||
&.icon-4
|
||||
background-position (5*$iconSize) 0px
|
||||
&.icon-5
|
||||
background-position (6*$iconSize) 0px
|
||||
&.icon-6
|
||||
background-position (7*$iconSize) 0px
|
||||
&.icon-7
|
||||
background-position (8*$iconSize) 0px
|
||||
&.icon-8
|
||||
background-position (9*$iconSize) 0px
|
||||
&.icon-9
|
||||
background-position (10*$iconSize) 0px
|
||||
&.icon-10
|
||||
background-position (11*$iconSize) 0px
|
||||
for num in (0..30)
|
||||
&.icon-{num}
|
||||
background-position ((num + 1) * $iconSize) 0px
|
||||
|
||||
&.isFalling
|
||||
position absolute
|
||||
@ -94,7 +80,7 @@ $iconSize = 121px
|
||||
from
|
||||
top -117px // revoir précisément
|
||||
to
|
||||
top 3px
|
||||
top 0
|
||||
|
||||
@keyframes destroyCircleAnimation
|
||||
0%
|
Loading…
x
Reference in New Issue
Block a user