forked from vergnet/application-amicale
Improve Game files to match linter
This commit is contained in:
parent
569e659779
commit
cbe3777957
16 changed files with 1750 additions and 1610 deletions
|
@ -1,13 +1,13 @@
|
|||
// @flow
|
||||
|
||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||
import type {CustomThemeType} from '../../../managers/ThemeManager';
|
||||
|
||||
export type Coordinates = {
|
||||
x: number,
|
||||
y: number,
|
||||
}
|
||||
export type CoordinatesType = {
|
||||
x: number,
|
||||
y: number,
|
||||
};
|
||||
|
||||
type Shape = Array<Array<number>>;
|
||||
export type ShapeType = Array<Array<number>>;
|
||||
|
||||
/**
|
||||
* Abstract class used to represent a BaseShape.
|
||||
|
@ -15,96 +15,98 @@ type Shape = Array<Array<number>>;
|
|||
* and in methods to implement
|
||||
*/
|
||||
export default class BaseShape {
|
||||
#currentShape: ShapeType;
|
||||
|
||||
#currentShape: Shape;
|
||||
#rotation: number;
|
||||
position: Coordinates;
|
||||
theme: CustomTheme;
|
||||
#rotation: number;
|
||||
|
||||
/**
|
||||
* Prevent instantiation if classname is BaseShape to force class to be abstract
|
||||
*/
|
||||
constructor(theme: CustomTheme) {
|
||||
if (this.constructor === BaseShape)
|
||||
throw new Error("Abstract class can't be instantiated");
|
||||
this.theme = theme;
|
||||
this.#rotation = 0;
|
||||
this.position = {x: 0, y: 0};
|
||||
this.#currentShape = this.getShapes()[this.#rotation];
|
||||
}
|
||||
position: CoordinatesType;
|
||||
|
||||
/**
|
||||
* Gets this shape's color.
|
||||
* Must be implemented by child class
|
||||
*/
|
||||
getColor(): string {
|
||||
throw new Error("Method 'getColor()' must be implemented");
|
||||
}
|
||||
theme: CustomThemeType;
|
||||
|
||||
/**
|
||||
* Gets this object's all possible shapes as an array.
|
||||
* Must be implemented by child class.
|
||||
*
|
||||
* Used by tests to read private fields
|
||||
*/
|
||||
getShapes(): Array<Shape> {
|
||||
throw new Error("Method 'getShapes()' must be implemented");
|
||||
}
|
||||
/**
|
||||
* Prevent instantiation if classname is BaseShape to force class to be abstract
|
||||
*/
|
||||
constructor(theme: CustomThemeType) {
|
||||
if (this.constructor === BaseShape)
|
||||
throw new Error("Abstract class can't be instantiated");
|
||||
this.theme = theme;
|
||||
this.#rotation = 0;
|
||||
this.position = {x: 0, y: 0};
|
||||
this.#currentShape = this.getShapes()[this.#rotation];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this object's current shape.
|
||||
*/
|
||||
getCurrentShape(): Shape {
|
||||
return this.#currentShape;
|
||||
}
|
||||
/**
|
||||
* Gets this shape's color.
|
||||
* Must be implemented by child class
|
||||
*/
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
getColor(): string {
|
||||
throw new Error("Method 'getColor()' must be implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this object's coordinates.
|
||||
* This will return an array of coordinates representing the positions of the cells used by this object.
|
||||
*
|
||||
* @param isAbsolute Should we take into account the current position of the object?
|
||||
* @return {Array<Coordinates>} This object cells coordinates
|
||||
*/
|
||||
getCellsCoordinates(isAbsolute: boolean): Array<Coordinates> {
|
||||
let coordinates = [];
|
||||
for (let row = 0; row < this.#currentShape.length; row++) {
|
||||
for (let col = 0; col < this.#currentShape[row].length; col++) {
|
||||
if (this.#currentShape[row][col] === 1)
|
||||
if (isAbsolute)
|
||||
coordinates.push({x: this.position.x + col, y: this.position.y + row});
|
||||
else
|
||||
coordinates.push({x: col, y: row});
|
||||
}
|
||||
/**
|
||||
* Gets this object's all possible shapes as an array.
|
||||
* Must be implemented by child class.
|
||||
*
|
||||
* Used by tests to read private fields
|
||||
*/
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
getShapes(): Array<ShapeType> {
|
||||
throw new Error("Method 'getShapes()' must be implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this object's current shape.
|
||||
*/
|
||||
getCurrentShape(): ShapeType {
|
||||
return this.#currentShape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this object's coordinates.
|
||||
* This will return an array of coordinates representing the positions of the cells used by this object.
|
||||
*
|
||||
* @param isAbsolute Should we take into account the current position of the object?
|
||||
* @return {Array<CoordinatesType>} This object cells coordinates
|
||||
*/
|
||||
getCellsCoordinates(isAbsolute: boolean): Array<CoordinatesType> {
|
||||
const coordinates = [];
|
||||
for (let row = 0; row < this.#currentShape.length; row += 1) {
|
||||
for (let col = 0; col < this.#currentShape[row].length; col += 1) {
|
||||
if (this.#currentShape[row][col] === 1) {
|
||||
if (isAbsolute) {
|
||||
coordinates.push({
|
||||
x: this.position.x + col,
|
||||
y: this.position.y + row,
|
||||
});
|
||||
} else coordinates.push({x: col, y: row});
|
||||
}
|
||||
return coordinates;
|
||||
}
|
||||
}
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate this object
|
||||
*
|
||||
* @param isForward Should we rotate clockwise?
|
||||
*/
|
||||
rotate(isForward: boolean) {
|
||||
if (isForward)
|
||||
this.#rotation++;
|
||||
else
|
||||
this.#rotation--;
|
||||
if (this.#rotation > 3)
|
||||
this.#rotation = 0;
|
||||
else if (this.#rotation < 0)
|
||||
this.#rotation = 3;
|
||||
this.#currentShape = this.getShapes()[this.#rotation];
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this object
|
||||
*
|
||||
* @param x Position X offset to add
|
||||
* @param y Position Y offset to add
|
||||
*/
|
||||
move(x: number, y: number) {
|
||||
this.position.x += x;
|
||||
this.position.y += y;
|
||||
}
|
||||
/**
|
||||
* Rotate this object
|
||||
*
|
||||
* @param isForward Should we rotate clockwise?
|
||||
*/
|
||||
rotate(isForward: boolean) {
|
||||
if (isForward) this.#rotation += 1;
|
||||
else this.#rotation -= 1;
|
||||
if (this.#rotation > 3) this.#rotation = 0;
|
||||
else if (this.#rotation < 0) this.#rotation = 3;
|
||||
this.#currentShape = this.getShapes()[this.#rotation];
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this object
|
||||
*
|
||||
* @param x Position X offset to add
|
||||
* @param y Position Y offset to add
|
||||
*/
|
||||
move(x: number, y: number) {
|
||||
this.position.x += x;
|
||||
this.position.y += y;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,45 +1,46 @@
|
|||
// @flow
|
||||
|
||||
import BaseShape from "./BaseShape";
|
||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||
import BaseShape from './BaseShape';
|
||||
import type {CustomThemeType} from '../../../managers/ThemeManager';
|
||||
import type {ShapeType} from './BaseShape';
|
||||
|
||||
export default class ShapeI extends BaseShape {
|
||||
constructor(theme: CustomThemeType) {
|
||||
super(theme);
|
||||
this.position.x = 3;
|
||||
}
|
||||
|
||||
constructor(theme: CustomTheme) {
|
||||
super(theme);
|
||||
this.position.x = 3;
|
||||
}
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisI;
|
||||
}
|
||||
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisI;
|
||||
}
|
||||
|
||||
getShapes() {
|
||||
return [
|
||||
[
|
||||
[0, 0, 0, 0],
|
||||
[1, 1, 1, 1],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 1, 0],
|
||||
],
|
||||
[
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[1, 1, 1, 1],
|
||||
[0, 0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 1, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
],
|
||||
];
|
||||
}
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
getShapes(): Array<ShapeType> {
|
||||
return [
|
||||
[
|
||||
[0, 0, 0, 0],
|
||||
[1, 1, 1, 1],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 1, 0],
|
||||
],
|
||||
[
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[1, 1, 1, 1],
|
||||
[0, 0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 1, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,42 @@
|
|||
// @flow
|
||||
|
||||
import BaseShape from "./BaseShape";
|
||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||
import BaseShape from './BaseShape';
|
||||
import type {CustomThemeType} from '../../../managers/ThemeManager';
|
||||
import type {ShapeType} from './BaseShape';
|
||||
|
||||
export default class ShapeJ extends BaseShape {
|
||||
constructor(theme: CustomThemeType) {
|
||||
super(theme);
|
||||
this.position.x = 3;
|
||||
}
|
||||
|
||||
constructor(theme: CustomTheme) {
|
||||
super(theme);
|
||||
this.position.x = 3;
|
||||
}
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisJ;
|
||||
}
|
||||
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisJ;
|
||||
}
|
||||
|
||||
getShapes() {
|
||||
return [
|
||||
[
|
||||
[1, 0, 0],
|
||||
[1, 1, 1],
|
||||
[0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 1, 1],
|
||||
[0, 1, 0],
|
||||
[0, 1, 0],
|
||||
],
|
||||
[
|
||||
[0, 0, 0],
|
||||
[1, 1, 1],
|
||||
[0, 0, 1],
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[0, 1, 0],
|
||||
[1, 1, 0],
|
||||
],
|
||||
];
|
||||
}
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
getShapes(): Array<ShapeType> {
|
||||
return [
|
||||
[
|
||||
[1, 0, 0],
|
||||
[1, 1, 1],
|
||||
[0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 1, 1],
|
||||
[0, 1, 0],
|
||||
[0, 1, 0],
|
||||
],
|
||||
[
|
||||
[0, 0, 0],
|
||||
[1, 1, 1],
|
||||
[0, 0, 1],
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[0, 1, 0],
|
||||
[1, 1, 0],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,42 @@
|
|||
// @flow
|
||||
|
||||
import BaseShape from "./BaseShape";
|
||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||
import BaseShape from './BaseShape';
|
||||
import type {CustomThemeType} from '../../../managers/ThemeManager';
|
||||
import type {ShapeType} from './BaseShape';
|
||||
|
||||
export default class ShapeL extends BaseShape {
|
||||
constructor(theme: CustomThemeType) {
|
||||
super(theme);
|
||||
this.position.x = 3;
|
||||
}
|
||||
|
||||
constructor(theme: CustomTheme) {
|
||||
super(theme);
|
||||
this.position.x = 3;
|
||||
}
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisL;
|
||||
}
|
||||
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisL;
|
||||
}
|
||||
|
||||
getShapes() {
|
||||
return [
|
||||
[
|
||||
[0, 0, 1],
|
||||
[1, 1, 1],
|
||||
[0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[0, 1, 0],
|
||||
[0, 1, 1],
|
||||
],
|
||||
[
|
||||
[0, 0, 0],
|
||||
[1, 1, 1],
|
||||
[1, 0, 0],
|
||||
],
|
||||
[
|
||||
[1, 1, 0],
|
||||
[0, 1, 0],
|
||||
[0, 1, 0],
|
||||
],
|
||||
];
|
||||
}
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
getShapes(): Array<ShapeType> {
|
||||
return [
|
||||
[
|
||||
[0, 0, 1],
|
||||
[1, 1, 1],
|
||||
[0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[0, 1, 0],
|
||||
[0, 1, 1],
|
||||
],
|
||||
[
|
||||
[0, 0, 0],
|
||||
[1, 1, 1],
|
||||
[1, 0, 0],
|
||||
],
|
||||
[
|
||||
[1, 1, 0],
|
||||
[0, 1, 0],
|
||||
[0, 1, 0],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +1,38 @@
|
|||
// @flow
|
||||
|
||||
import BaseShape from "./BaseShape";
|
||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||
import BaseShape from './BaseShape';
|
||||
import type {CustomThemeType} from '../../../managers/ThemeManager';
|
||||
import type {ShapeType} from './BaseShape';
|
||||
|
||||
export default class ShapeO extends BaseShape {
|
||||
constructor(theme: CustomThemeType) {
|
||||
super(theme);
|
||||
this.position.x = 4;
|
||||
}
|
||||
|
||||
constructor(theme: CustomTheme) {
|
||||
super(theme);
|
||||
this.position.x = 4;
|
||||
}
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisO;
|
||||
}
|
||||
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisO;
|
||||
}
|
||||
|
||||
getShapes() {
|
||||
return [
|
||||
[
|
||||
[1, 1],
|
||||
[1, 1],
|
||||
],
|
||||
[
|
||||
[1, 1],
|
||||
[1, 1],
|
||||
],
|
||||
[
|
||||
[1, 1],
|
||||
[1, 1],
|
||||
],
|
||||
[
|
||||
[1, 1],
|
||||
[1, 1],
|
||||
],
|
||||
];
|
||||
}
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
getShapes(): Array<ShapeType> {
|
||||
return [
|
||||
[
|
||||
[1, 1],
|
||||
[1, 1],
|
||||
],
|
||||
[
|
||||
[1, 1],
|
||||
[1, 1],
|
||||
],
|
||||
[
|
||||
[1, 1],
|
||||
[1, 1],
|
||||
],
|
||||
[
|
||||
[1, 1],
|
||||
[1, 1],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,42 @@
|
|||
// @flow
|
||||
|
||||
import BaseShape from "./BaseShape";
|
||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||
import BaseShape from './BaseShape';
|
||||
import type {CustomThemeType} from '../../../managers/ThemeManager';
|
||||
import type {ShapeType} from './BaseShape';
|
||||
|
||||
export default class ShapeS extends BaseShape {
|
||||
constructor(theme: CustomThemeType) {
|
||||
super(theme);
|
||||
this.position.x = 3;
|
||||
}
|
||||
|
||||
constructor(theme: CustomTheme) {
|
||||
super(theme);
|
||||
this.position.x = 3;
|
||||
}
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisS;
|
||||
}
|
||||
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisS;
|
||||
}
|
||||
|
||||
getShapes() {
|
||||
return [
|
||||
[
|
||||
[0, 1, 1],
|
||||
[1, 1, 0],
|
||||
[0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[0, 1, 1],
|
||||
[0, 0, 1],
|
||||
],
|
||||
[
|
||||
[0, 0, 0],
|
||||
[0, 1, 1],
|
||||
[1, 1, 0],
|
||||
],
|
||||
[
|
||||
[1, 0, 0],
|
||||
[1, 1, 0],
|
||||
[0, 1, 0],
|
||||
],
|
||||
];
|
||||
}
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
getShapes(): Array<ShapeType> {
|
||||
return [
|
||||
[
|
||||
[0, 1, 1],
|
||||
[1, 1, 0],
|
||||
[0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[0, 1, 1],
|
||||
[0, 0, 1],
|
||||
],
|
||||
[
|
||||
[0, 0, 0],
|
||||
[0, 1, 1],
|
||||
[1, 1, 0],
|
||||
],
|
||||
[
|
||||
[1, 0, 0],
|
||||
[1, 1, 0],
|
||||
[0, 1, 0],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,42 @@
|
|||
// @flow
|
||||
|
||||
import BaseShape from "./BaseShape";
|
||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||
import BaseShape from './BaseShape';
|
||||
import type {CustomThemeType} from '../../../managers/ThemeManager';
|
||||
import type {ShapeType} from './BaseShape';
|
||||
|
||||
export default class ShapeT extends BaseShape {
|
||||
constructor(theme: CustomThemeType) {
|
||||
super(theme);
|
||||
this.position.x = 3;
|
||||
}
|
||||
|
||||
constructor(theme: CustomTheme) {
|
||||
super(theme);
|
||||
this.position.x = 3;
|
||||
}
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisT;
|
||||
}
|
||||
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisT;
|
||||
}
|
||||
|
||||
getShapes() {
|
||||
return [
|
||||
[
|
||||
[0, 1, 0],
|
||||
[1, 1, 1],
|
||||
[0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[0, 1, 1],
|
||||
[0, 1, 0],
|
||||
],
|
||||
[
|
||||
[0, 0, 0],
|
||||
[1, 1, 1],
|
||||
[0, 1, 0],
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[1, 1, 0],
|
||||
[0, 1, 0],
|
||||
],
|
||||
];
|
||||
}
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
getShapes(): Array<ShapeType> {
|
||||
return [
|
||||
[
|
||||
[0, 1, 0],
|
||||
[1, 1, 1],
|
||||
[0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[0, 1, 1],
|
||||
[0, 1, 0],
|
||||
],
|
||||
[
|
||||
[0, 0, 0],
|
||||
[1, 1, 1],
|
||||
[0, 1, 0],
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[1, 1, 0],
|
||||
[0, 1, 0],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,42 @@
|
|||
// @flow
|
||||
|
||||
import BaseShape from "./BaseShape";
|
||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||
import BaseShape from './BaseShape';
|
||||
import type {CustomThemeType} from '../../../managers/ThemeManager';
|
||||
import type {ShapeType} from './BaseShape';
|
||||
|
||||
export default class ShapeZ extends BaseShape {
|
||||
constructor(theme: CustomThemeType) {
|
||||
super(theme);
|
||||
this.position.x = 3;
|
||||
}
|
||||
|
||||
constructor(theme: CustomTheme) {
|
||||
super(theme);
|
||||
this.position.x = 3;
|
||||
}
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisZ;
|
||||
}
|
||||
|
||||
getColor(): string {
|
||||
return this.theme.colors.tetrisZ;
|
||||
}
|
||||
|
||||
getShapes() {
|
||||
return [
|
||||
[
|
||||
[1, 1, 0],
|
||||
[0, 1, 1],
|
||||
[0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 0, 1],
|
||||
[0, 1, 1],
|
||||
[0, 1, 0],
|
||||
],
|
||||
[
|
||||
[0, 0, 0],
|
||||
[1, 1, 0],
|
||||
[0, 1, 1],
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[1, 1, 0],
|
||||
[1, 0, 0],
|
||||
],
|
||||
];
|
||||
}
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
getShapes(): Array<ShapeType> {
|
||||
return [
|
||||
[
|
||||
[1, 1, 0],
|
||||
[0, 1, 1],
|
||||
[0, 0, 0],
|
||||
],
|
||||
[
|
||||
[0, 0, 1],
|
||||
[0, 1, 1],
|
||||
[0, 1, 0],
|
||||
],
|
||||
[
|
||||
[0, 0, 0],
|
||||
[1, 1, 0],
|
||||
[0, 1, 1],
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[1, 1, 0],
|
||||
[1, 0, 0],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,34 +3,30 @@
|
|||
import * as React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {withTheme} from 'react-native-paper';
|
||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||
|
||||
export type Cell = {color: string, isEmpty: boolean, key: string};
|
||||
|
||||
type Props = {
|
||||
cell: Cell,
|
||||
theme: CustomTheme,
|
||||
}
|
||||
|
||||
class CellComponent extends React.PureComponent<Props> {
|
||||
|
||||
render() {
|
||||
const item = this.props.cell;
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: item.isEmpty ? 'transparent' : item.color,
|
||||
borderColor: 'transparent',
|
||||
borderRadius: 4,
|
||||
borderWidth: 1,
|
||||
aspectRatio: 1,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
export type CellType = {color: string, isEmpty: boolean, key: string};
|
||||
|
||||
type PropsType = {
|
||||
cell: CellType,
|
||||
};
|
||||
|
||||
class CellComponent extends React.PureComponent<PropsType> {
|
||||
render(): React.Node {
|
||||
const {props} = this;
|
||||
const item = props.cell;
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: item.isEmpty ? 'transparent' : item.color,
|
||||
borderColor: 'transparent',
|
||||
borderRadius: 4,
|
||||
borderWidth: 1,
|
||||
aspectRatio: 1,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withTheme(CellComponent);
|
||||
|
|
|
@ -3,56 +3,55 @@
|
|||
import * as React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {withTheme} from 'react-native-paper';
|
||||
import type {Cell} from "./CellComponent";
|
||||
import CellComponent from "./CellComponent";
|
||||
import type {ViewStyle} from "react-native/Libraries/StyleSheet/StyleSheet";
|
||||
import type {ViewStyle} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
||||
import type {CellType} from './CellComponent';
|
||||
import CellComponent from './CellComponent';
|
||||
|
||||
export type Grid = Array<Array<CellComponent>>;
|
||||
export type GridType = Array<Array<CellComponent>>;
|
||||
|
||||
type Props = {
|
||||
grid: Array<Array<Object>>,
|
||||
height: number,
|
||||
width: number,
|
||||
style: ViewStyle,
|
||||
}
|
||||
type PropsType = {
|
||||
grid: Array<Array<CellType>>,
|
||||
height: number,
|
||||
width: number,
|
||||
style: ViewStyle,
|
||||
};
|
||||
|
||||
class GridComponent extends React.Component<Props> {
|
||||
class GridComponent extends React.Component<PropsType> {
|
||||
getRow(rowNumber: number): React.Node {
|
||||
const {grid} = this.props;
|
||||
return (
|
||||
<View style={{flexDirection: 'row'}} key={rowNumber.toString()}>
|
||||
{grid[rowNumber].map(this.getCellRender)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
getRow(rowNumber: number) {
|
||||
let cells = this.props.grid[rowNumber].map(this.getCellRender);
|
||||
return (
|
||||
<View
|
||||
style={{flexDirection: 'row',}}
|
||||
key={rowNumber.toString()}
|
||||
>
|
||||
{cells}
|
||||
</View>
|
||||
);
|
||||
getCellRender = (item: CellType): React.Node => {
|
||||
return <CellComponent cell={item} key={item.key} />;
|
||||
};
|
||||
|
||||
getGrid(): React.Node {
|
||||
const {height} = this.props;
|
||||
const rows = [];
|
||||
for (let i = 0; i < height; i += 1) {
|
||||
rows.push(this.getRow(i));
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
getCellRender = (item: Cell) => {
|
||||
return <CellComponent cell={item} key={item.key}/>;
|
||||
};
|
||||
|
||||
getGrid() {
|
||||
let rows = [];
|
||||
for (let i = 0; i < this.props.height; i++) {
|
||||
rows.push(this.getRow(i));
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={{
|
||||
aspectRatio: this.props.width / this.props.height,
|
||||
borderRadius: 4,
|
||||
...this.props.style
|
||||
}}>
|
||||
{this.getGrid()}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
render(): React.Node {
|
||||
const {style, width, height} = this.props;
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
aspectRatio: width / height,
|
||||
borderRadius: 4,
|
||||
...style,
|
||||
}}>
|
||||
{this.getGrid()}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withTheme(GridComponent);
|
||||
|
|
|
@ -3,51 +3,48 @@
|
|||
import * as React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {withTheme} from 'react-native-paper';
|
||||
import type {Grid} from "./GridComponent";
|
||||
import GridComponent from "./GridComponent";
|
||||
import type {ViewStyle} from "react-native/Libraries/StyleSheet/StyleSheet";
|
||||
import type {ViewStyle} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
||||
import type {GridType} from './GridComponent';
|
||||
import GridComponent from './GridComponent';
|
||||
|
||||
type Props = {
|
||||
items: Array<Grid>,
|
||||
style: ViewStyle
|
||||
}
|
||||
type PropsType = {
|
||||
items: Array<GridType>,
|
||||
style: ViewStyle,
|
||||
};
|
||||
|
||||
class Preview extends React.PureComponent<Props> {
|
||||
class Preview extends React.PureComponent<PropsType> {
|
||||
getGrids(): React.Node {
|
||||
const {items} = this.props;
|
||||
const grids = [];
|
||||
items.forEach((item: GridType, index: number) => {
|
||||
grids.push(Preview.getGridRender(item, index));
|
||||
});
|
||||
return grids;
|
||||
}
|
||||
|
||||
getGrids() {
|
||||
let grids = [];
|
||||
for (let i = 0; i < this.props.items.length; i++) {
|
||||
grids.push(this.getGridRender(this.props.items[i], i));
|
||||
}
|
||||
return grids;
|
||||
static getGridRender(item: GridType, index: number): React.Node {
|
||||
return (
|
||||
<GridComponent
|
||||
width={item[0].length}
|
||||
height={item.length}
|
||||
grid={item}
|
||||
style={{
|
||||
marginRight: 5,
|
||||
marginLeft: 5,
|
||||
marginBottom: 5,
|
||||
}}
|
||||
key={index.toString()}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
const {style, items} = this.props;
|
||||
if (items.length > 0) {
|
||||
return <View style={style}>{this.getGrids()}</View>;
|
||||
}
|
||||
|
||||
getGridRender(item: Grid, index: number) {
|
||||
return <GridComponent
|
||||
width={item[0].length}
|
||||
height={item.length}
|
||||
grid={item}
|
||||
style={{
|
||||
marginRight: 5,
|
||||
marginLeft: 5,
|
||||
marginBottom: 5,
|
||||
}}
|
||||
key={index.toString()}
|
||||
/>;
|
||||
};
|
||||
|
||||
render() {
|
||||
if (this.props.items.length > 0) {
|
||||
return (
|
||||
<View style={this.props.style}>
|
||||
{this.getGrids()}
|
||||
</View>
|
||||
);
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export default withTheme(Preview);
|
||||
|
|
|
@ -1,243 +1,318 @@
|
|||
// @flow
|
||||
|
||||
import Piece from "./Piece";
|
||||
import ScoreManager from "./ScoreManager";
|
||||
import GridManager from "./GridManager";
|
||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||
import Piece from './Piece';
|
||||
import ScoreManager from './ScoreManager';
|
||||
import GridManager from './GridManager';
|
||||
import type {CustomThemeType} from '../../../managers/ThemeManager';
|
||||
import type {GridType} from '../components/GridComponent';
|
||||
|
||||
export type TickCallbackType = (
|
||||
score: number,
|
||||
level: number,
|
||||
grid: GridType,
|
||||
) => void;
|
||||
|
||||
export type ClockCallbackType = (time: number) => void;
|
||||
|
||||
export type EndCallbackType = (
|
||||
time: number,
|
||||
score: number,
|
||||
isRestart: boolean,
|
||||
) => void;
|
||||
|
||||
export type MovementCallbackType = (grid: GridType, score?: number) => void;
|
||||
|
||||
export default class GameLogic {
|
||||
static levelTicks = [1000, 800, 600, 400, 300, 200, 150, 100];
|
||||
|
||||
static levelTicks = [
|
||||
1000,
|
||||
800,
|
||||
600,
|
||||
400,
|
||||
300,
|
||||
200,
|
||||
150,
|
||||
100,
|
||||
];
|
||||
scoreManager: ScoreManager;
|
||||
|
||||
#scoreManager: ScoreManager;
|
||||
#gridManager: GridManager;
|
||||
gridManager: GridManager;
|
||||
|
||||
#height: number;
|
||||
#width: number;
|
||||
height: number;
|
||||
|
||||
#gameRunning: boolean;
|
||||
#gamePaused: boolean;
|
||||
#gameTime: number;
|
||||
width: number;
|
||||
|
||||
#currentObject: Piece;
|
||||
gameRunning: boolean;
|
||||
|
||||
#gameTick: number;
|
||||
#gameTickInterval: IntervalID;
|
||||
#gameTimeInterval: IntervalID;
|
||||
gamePaused: boolean;
|
||||
|
||||
#pressInInterval: TimeoutID;
|
||||
#isPressedIn: boolean;
|
||||
#autoRepeatActivationDelay: number;
|
||||
#autoRepeatDelay: number;
|
||||
gameTime: number;
|
||||
|
||||
#nextPieces: Array<Piece>;
|
||||
#nextPiecesCount: number;
|
||||
currentObject: Piece;
|
||||
|
||||
#onTick: Function;
|
||||
#onClock: Function;
|
||||
endCallback: Function;
|
||||
gameTick: number;
|
||||
|
||||
#theme: CustomTheme;
|
||||
gameTickInterval: IntervalID;
|
||||
|
||||
constructor(height: number, width: number, theme: CustomTheme) {
|
||||
this.#height = height;
|
||||
this.#width = width;
|
||||
this.#gameRunning = false;
|
||||
this.#gamePaused = false;
|
||||
this.#theme = theme;
|
||||
this.#autoRepeatActivationDelay = 300;
|
||||
this.#autoRepeatDelay = 50;
|
||||
this.#nextPieces = [];
|
||||
this.#nextPiecesCount = 3;
|
||||
this.#scoreManager = new ScoreManager();
|
||||
this.#gridManager = new GridManager(this.getWidth(), this.getHeight(), this.#theme);
|
||||
}
|
||||
gameTimeInterval: IntervalID;
|
||||
|
||||
getHeight(): number {
|
||||
return this.#height;
|
||||
}
|
||||
pressInInterval: TimeoutID;
|
||||
|
||||
getWidth(): number {
|
||||
return this.#width;
|
||||
}
|
||||
isPressedIn: boolean;
|
||||
|
||||
getCurrentGrid() {
|
||||
return this.#gridManager.getCurrentGrid();
|
||||
}
|
||||
autoRepeatActivationDelay: number;
|
||||
|
||||
isGameRunning(): boolean {
|
||||
return this.#gameRunning;
|
||||
}
|
||||
autoRepeatDelay: number;
|
||||
|
||||
isGamePaused(): boolean {
|
||||
return this.#gamePaused;
|
||||
}
|
||||
nextPieces: Array<Piece>;
|
||||
|
||||
onFreeze() {
|
||||
this.#gridManager.freezeTetromino(this.#currentObject, this.#scoreManager);
|
||||
this.createTetromino();
|
||||
}
|
||||
nextPiecesCount: number;
|
||||
|
||||
setNewGameTick(level: number) {
|
||||
if (level >= GameLogic.levelTicks.length)
|
||||
return;
|
||||
this.#gameTick = GameLogic.levelTicks[level];
|
||||
clearInterval(this.#gameTickInterval);
|
||||
this.#gameTickInterval = setInterval(this.#onTick, this.#gameTick);
|
||||
}
|
||||
tickCallback: TickCallbackType;
|
||||
|
||||
onTick(callback: Function) {
|
||||
this.#currentObject.tryMove(0, 1,
|
||||
this.#gridManager.getCurrentGrid(), this.getWidth(), this.getHeight(),
|
||||
() => this.onFreeze());
|
||||
clockCallback: ClockCallbackType;
|
||||
|
||||
endCallback: EndCallbackType;
|
||||
|
||||
theme: CustomThemeType;
|
||||
|
||||
constructor(height: number, width: number, theme: CustomThemeType) {
|
||||
this.height = height;
|
||||
this.width = width;
|
||||
this.gameRunning = false;
|
||||
this.gamePaused = false;
|
||||
this.theme = theme;
|
||||
this.autoRepeatActivationDelay = 300;
|
||||
this.autoRepeatDelay = 50;
|
||||
this.nextPieces = [];
|
||||
this.nextPiecesCount = 3;
|
||||
this.scoreManager = new ScoreManager();
|
||||
this.gridManager = new GridManager(
|
||||
this.getWidth(),
|
||||
this.getHeight(),
|
||||
this.theme,
|
||||
);
|
||||
}
|
||||
|
||||
getHeight(): number {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
getWidth(): number {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
getCurrentGrid(): GridType {
|
||||
return this.gridManager.getCurrentGrid();
|
||||
}
|
||||
|
||||
isGamePaused(): boolean {
|
||||
return this.gamePaused;
|
||||
}
|
||||
|
||||
onFreeze = () => {
|
||||
this.gridManager.freezeTetromino(this.currentObject, this.scoreManager);
|
||||
this.createTetromino();
|
||||
};
|
||||
|
||||
setNewGameTick(level: number) {
|
||||
if (level >= GameLogic.levelTicks.length) return;
|
||||
this.gameTick = GameLogic.levelTicks[level];
|
||||
this.stopTick();
|
||||
this.startTick();
|
||||
}
|
||||
|
||||
startClock() {
|
||||
this.gameTimeInterval = setInterval(() => {
|
||||
this.onClock(this.clockCallback);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
startTick() {
|
||||
this.gameTickInterval = setInterval(() => {
|
||||
this.onTick(this.tickCallback);
|
||||
}, this.gameTick);
|
||||
}
|
||||
|
||||
stopClock() {
|
||||
clearInterval(this.gameTimeInterval);
|
||||
}
|
||||
|
||||
stopTick() {
|
||||
clearInterval(this.gameTickInterval);
|
||||
}
|
||||
|
||||
stopGameTime() {
|
||||
this.stopClock();
|
||||
this.stopTick();
|
||||
}
|
||||
|
||||
startGameTime() {
|
||||
this.startClock();
|
||||
this.startTick();
|
||||
}
|
||||
|
||||
onTick(callback: TickCallbackType) {
|
||||
this.currentObject.tryMove(
|
||||
0,
|
||||
1,
|
||||
this.gridManager.getCurrentGrid(),
|
||||
this.getWidth(),
|
||||
this.getHeight(),
|
||||
this.onFreeze,
|
||||
);
|
||||
callback(
|
||||
this.scoreManager.getScore(),
|
||||
this.scoreManager.getLevel(),
|
||||
this.gridManager.getCurrentGrid(),
|
||||
);
|
||||
if (this.scoreManager.canLevelUp())
|
||||
this.setNewGameTick(this.scoreManager.getLevel());
|
||||
}
|
||||
|
||||
onClock(callback: ClockCallbackType) {
|
||||
this.gameTime += 1;
|
||||
callback(this.gameTime);
|
||||
}
|
||||
|
||||
canUseInput(): boolean {
|
||||
return this.gameRunning && !this.gamePaused;
|
||||
}
|
||||
|
||||
rightPressed(callback: MovementCallbackType) {
|
||||
this.isPressedIn = true;
|
||||
this.movePressedRepeat(true, callback, 1, 0);
|
||||
}
|
||||
|
||||
leftPressedIn(callback: MovementCallbackType) {
|
||||
this.isPressedIn = true;
|
||||
this.movePressedRepeat(true, callback, -1, 0);
|
||||
}
|
||||
|
||||
downPressedIn(callback: MovementCallbackType) {
|
||||
this.isPressedIn = true;
|
||||
this.movePressedRepeat(true, callback, 0, 1);
|
||||
}
|
||||
|
||||
movePressedRepeat(
|
||||
isInitial: boolean,
|
||||
callback: MovementCallbackType,
|
||||
x: number,
|
||||
y: number,
|
||||
) {
|
||||
if (!this.canUseInput() || !this.isPressedIn) return;
|
||||
const moved = this.currentObject.tryMove(
|
||||
x,
|
||||
y,
|
||||
this.gridManager.getCurrentGrid(),
|
||||
this.getWidth(),
|
||||
this.getHeight(),
|
||||
this.onFreeze,
|
||||
);
|
||||
if (moved) {
|
||||
if (y === 1) {
|
||||
this.scoreManager.incrementScore();
|
||||
callback(
|
||||
this.#scoreManager.getScore(),
|
||||
this.#scoreManager.getLevel(),
|
||||
this.#gridManager.getCurrentGrid());
|
||||
if (this.#scoreManager.canLevelUp())
|
||||
this.setNewGameTick(this.#scoreManager.getLevel());
|
||||
}
|
||||
|
||||
onClock(callback: Function) {
|
||||
this.#gameTime++;
|
||||
callback(this.#gameTime);
|
||||
}
|
||||
|
||||
canUseInput() {
|
||||
return this.#gameRunning && !this.#gamePaused
|
||||
}
|
||||
|
||||
rightPressed(callback: Function) {
|
||||
this.#isPressedIn = true;
|
||||
this.movePressedRepeat(true, callback, 1, 0);
|
||||
}
|
||||
|
||||
leftPressedIn(callback: Function) {
|
||||
this.#isPressedIn = true;
|
||||
this.movePressedRepeat(true, callback, -1, 0);
|
||||
}
|
||||
|
||||
downPressedIn(callback: Function) {
|
||||
this.#isPressedIn = true;
|
||||
this.movePressedRepeat(true, callback, 0, 1);
|
||||
}
|
||||
|
||||
movePressedRepeat(isInitial: boolean, callback: Function, x: number, y: number) {
|
||||
if (!this.canUseInput() || !this.#isPressedIn)
|
||||
return;
|
||||
const moved = this.#currentObject.tryMove(x, y,
|
||||
this.#gridManager.getCurrentGrid(), this.getWidth(), this.getHeight(),
|
||||
() => this.onFreeze());
|
||||
if (moved) {
|
||||
if (y === 1) {
|
||||
this.#scoreManager.incrementScore();
|
||||
callback(this.#gridManager.getCurrentGrid(), this.#scoreManager.getScore());
|
||||
} else
|
||||
callback(this.#gridManager.getCurrentGrid());
|
||||
}
|
||||
this.#pressInInterval = setTimeout(() =>
|
||||
this.movePressedRepeat(false, callback, x, y),
|
||||
isInitial ? this.#autoRepeatActivationDelay : this.#autoRepeatDelay
|
||||
this.gridManager.getCurrentGrid(),
|
||||
this.scoreManager.getScore(),
|
||||
);
|
||||
} else callback(this.gridManager.getCurrentGrid());
|
||||
}
|
||||
this.pressInInterval = setTimeout(
|
||||
() => {
|
||||
this.movePressedRepeat(false, callback, x, y);
|
||||
},
|
||||
isInitial ? this.autoRepeatActivationDelay : this.autoRepeatDelay,
|
||||
);
|
||||
}
|
||||
|
||||
pressedOut() {
|
||||
this.#isPressedIn = false;
|
||||
clearTimeout(this.#pressInInterval);
|
||||
pressedOut() {
|
||||
this.isPressedIn = false;
|
||||
clearTimeout(this.pressInInterval);
|
||||
}
|
||||
|
||||
rotatePressed(callback: MovementCallbackType) {
|
||||
if (!this.canUseInput()) return;
|
||||
|
||||
if (
|
||||
this.currentObject.tryRotate(
|
||||
this.gridManager.getCurrentGrid(),
|
||||
this.getWidth(),
|
||||
this.getHeight(),
|
||||
)
|
||||
)
|
||||
callback(this.gridManager.getCurrentGrid());
|
||||
}
|
||||
|
||||
getNextPiecesPreviews(): Array<GridType> {
|
||||
const finalArray = [];
|
||||
for (let i = 0; i < this.nextPieces.length; i += 1) {
|
||||
const gridSize = this.nextPieces[i].getCurrentShape().getCurrentShape()[0]
|
||||
.length;
|
||||
finalArray.push(this.gridManager.getEmptyGrid(gridSize, gridSize));
|
||||
this.nextPieces[i].toGrid(finalArray[i], true);
|
||||
}
|
||||
return finalArray;
|
||||
}
|
||||
|
||||
rotatePressed(callback: Function) {
|
||||
if (!this.canUseInput())
|
||||
return;
|
||||
recoverNextPiece() {
|
||||
this.currentObject = this.nextPieces.shift();
|
||||
this.generateNextPieces();
|
||||
}
|
||||
|
||||
if (this.#currentObject.tryRotate(this.#gridManager.getCurrentGrid(), this.getWidth(), this.getHeight()))
|
||||
callback(this.#gridManager.getCurrentGrid());
|
||||
generateNextPieces() {
|
||||
while (this.nextPieces.length < this.nextPiecesCount) {
|
||||
this.nextPieces.push(new Piece(this.theme));
|
||||
}
|
||||
}
|
||||
|
||||
getNextPiecesPreviews() {
|
||||
let finalArray = [];
|
||||
for (let i = 0; i < this.#nextPieces.length; i++) {
|
||||
const gridSize = this.#nextPieces[i].getCurrentShape().getCurrentShape()[0].length;
|
||||
finalArray.push(this.#gridManager.getEmptyGrid(gridSize, gridSize));
|
||||
this.#nextPieces[i].toGrid(finalArray[i], true);
|
||||
}
|
||||
createTetromino() {
|
||||
this.pressedOut();
|
||||
this.recoverNextPiece();
|
||||
if (
|
||||
!this.currentObject.isPositionValid(
|
||||
this.gridManager.getCurrentGrid(),
|
||||
this.getWidth(),
|
||||
this.getHeight(),
|
||||
)
|
||||
)
|
||||
this.endGame(false);
|
||||
}
|
||||
|
||||
return finalArray;
|
||||
}
|
||||
togglePause() {
|
||||
if (!this.gameRunning) return;
|
||||
this.gamePaused = !this.gamePaused;
|
||||
if (this.gamePaused) this.stopGameTime();
|
||||
else this.startGameTime();
|
||||
}
|
||||
|
||||
recoverNextPiece() {
|
||||
this.#currentObject = this.#nextPieces.shift();
|
||||
this.generateNextPieces();
|
||||
}
|
||||
endGame(isRestart: boolean) {
|
||||
this.gameRunning = false;
|
||||
this.gamePaused = false;
|
||||
this.stopGameTime();
|
||||
this.endCallback(this.gameTime, this.scoreManager.getScore(), isRestart);
|
||||
}
|
||||
|
||||
generateNextPieces() {
|
||||
while (this.#nextPieces.length < this.#nextPiecesCount) {
|
||||
this.#nextPieces.push(new Piece(this.#theme));
|
||||
}
|
||||
}
|
||||
|
||||
createTetromino() {
|
||||
this.pressedOut();
|
||||
this.recoverNextPiece();
|
||||
if (!this.#currentObject.isPositionValid(this.#gridManager.getCurrentGrid(), this.getWidth(), this.getHeight()))
|
||||
this.endGame(false);
|
||||
}
|
||||
|
||||
togglePause() {
|
||||
if (!this.#gameRunning)
|
||||
return;
|
||||
this.#gamePaused = !this.#gamePaused;
|
||||
if (this.#gamePaused) {
|
||||
clearInterval(this.#gameTickInterval);
|
||||
clearInterval(this.#gameTimeInterval);
|
||||
} else {
|
||||
this.#gameTickInterval = setInterval(this.#onTick, this.#gameTick);
|
||||
this.#gameTimeInterval = setInterval(this.#onClock, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
stopGame() {
|
||||
this.#gameRunning = false;
|
||||
this.#gamePaused = false;
|
||||
clearInterval(this.#gameTickInterval);
|
||||
clearInterval(this.#gameTimeInterval);
|
||||
}
|
||||
|
||||
endGame(isRestart: boolean) {
|
||||
this.stopGame();
|
||||
this.endCallback(this.#gameTime, this.#scoreManager.getScore(), isRestart);
|
||||
}
|
||||
|
||||
startGame(tickCallback: Function, clockCallback: Function, endCallback: Function) {
|
||||
if (this.#gameRunning)
|
||||
this.endGame(true);
|
||||
this.#gameRunning = true;
|
||||
this.#gamePaused = false;
|
||||
this.#gameTime = 0;
|