Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/engine/rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,12 @@ function tick1tryAndScore(game: Game, multiplier = 1) {
game.state.tilesCleared += cleared.total;

// compute score for clearing tiles
const fw = game.activeFramework();
const overflow = cleared.total - DC2MAX;
const clearScore = game.state.level * game.state.conf.tileScoreMultiplier;
const overflowBonus = clearScore * overflow;
const fwBonus = cleared.breakdown.reduce((s: number, el) => {
if (el.fw === game.activeFramework()) {
if (el.fw === fw) {
s += el.total * 2;
}
return s;
Expand Down Expand Up @@ -165,6 +166,7 @@ function tick1tryAndScore(game: Game, multiplier = 1) {
cleared,
clearScore,
levelScore,
fw,
fwBonus,
overflowBonus,
score: game.state.score,
Expand Down
1 change: 1 addition & 0 deletions src/front-end/actions/game.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export function updateScoreData(levelData: {
fwBonus: number;
overflowBonus: number;
score: number;
fw: number;
}) {
return {
type: UPDATE_SCORE_DATA,
Expand Down
28 changes: 25 additions & 3 deletions src/front-end/angular/components/board.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,23 @@ import { board, emptyTile, flexGrowRow, tileByNumber } from '../../styles';
},
template: `
<h3 class="blue-black bg-angular-red f4 f2-m f1-l ma0 pt1 pt2-m pt3-l tc">LEVEL {{level}}</h3>
<div class="${board}">
<div class="${flexGrowRow}" *ngFor="let row of board; trackBy: trackCol">
<div class="${board} relative">
<score-hint-cloud
[lastOverflowBonus]="lastOverflowBonus"
[lastFwBonus]="lastFwBonus"
[lastFwBonusFw]="lastFwBonusFw"
[lastClearScore]="lastClearScore"
[lastLevelScore]="lastLevelScore"
[lastScoreUpdate]="lastScoreUpdate"
[firstAnimationBlock]="firstAnimationBlock"
[scoreDuration]="scoreDuration"
[width]="width"
[height]="height">
</score-hint-cloud>
<div class="${flexGrowRow}" *ngFor="let row of board; trackBy: trackCol;">
<tile [ngClass]="tile === 0 ? emptyTile : tileByNumber(tile)"
*ngFor="let tile of row; trackBy: trackRow" [value]="tile"></tile>
*ngFor="let tile of row; trackBy: trackRow;" [value]="tile">
</tile>
</div>
</div>
`,
Expand All @@ -22,7 +35,16 @@ export class Board {
@Input() board: number[][];
@Input() level: number;
@Input() width: number;
@Input() height: number;
@Input() isPaused: boolean;
@Input() lastOverflowBonus: number = 0;
@Input() lastFwBonus: number = 0;
@Input() lastFwBonusFw: number = 0;
@Input() lastClearScore: number = 0;
@Input() lastLevelScore: number = 0;
@Input() lastScoreUpdate: number = 0;
@Input() firstAnimationBlock: number = -1;
@Input() scoreDuration: number = 2000;

cols: number[][];
emptyTile: string = emptyTile;
Expand Down
2 changes: 2 additions & 0 deletions src/front-end/angular/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ export * from './next-pieces-block.component';
export * from './tile.component';
export * from './forms';
export * from './score.component';
export * from './score-hint.component';
export * from './score-hint-cloud.component';
66 changes: 66 additions & 0 deletions src/front-end/angular/components/score-hint-cloud.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Component, Input, HostBinding } from '@angular/core';

function xFromIndex(width: number, index: number) {
return ;
}


@Component({
selector: 'score-hint-cloud',
template: `
<score-hint
[text]="'Score'"
[startTime]="lastScoreUpdate"
[score]="lastClearScore"
[position]="position"
[duration]="scoreDuration"
[colour]="-1">
</score-hint>
<score-hint
[text]="'Bonus'"
[startTime]="lastScoreUpdate"
[delay]="1"
[score]="lastFwBonus"
[position]="position"
[duration]="scoreDuration"
[colour]="-1">
</score-hint>
<score-hint
[text]="'Extra Bonus'"
[startTime]="lastScoreUpdate"
[delay]="2"
[score]="lastFwBonusFw"
[position]="position"
[duration]="scoreDuration"
[colour]="-1">
</score-hint>
<score-hint
[text]="'Overflow Bonus'"
[startTime]="lastScoreUpdate"
[delay]="3"
[score]="lastOverflowBonus"
[position]="position"
[duration]="scoreDuration"
[colour]="-1">
</score-hint>
`,
})
export class ScoreHintCloud {
@Input() lastOverflowBonus: number = 0;
@Input() lastFwBonus: number = 0;
@Input() lastFwBonusFw: number = 0;
@Input() lastClearScore: number = 0;
@Input() lastLevelScore: number = 0;
@Input() lastScoreUpdate: number = 0;
@Input() scoreDuration: number = 2000;
@Input() firstAnimationBlock: number = -1;
@Input() width: number = 0;
@Input() height: number = 0;

get position() {
const x = 50;
const y = 50;

return { xPercent: x , yPercent: y };
}
}
64 changes: 64 additions & 0 deletions src/front-end/angular/components/score-hint.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Component, Input, HostBinding } from '@angular/core';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
import { tileColorByNumber } from '../../styles';

const jitterScale = 10;
@Component({
selector: 'score-hint',
host: {
class: 'dib absolute'
},
template: `
<div *ngIf="canShow()" [ngClass]="getClass">
<div class="mbn-50 mln-50 dib">
<span class="f6 o-50">{{ text }}</span>
<span class="f3">+{{ score }}</span>
</div>
</div>
`,
})
export class ScoreHint {
@Input() colour: 10 | 20 | 30 | -10;
@Input() text: string = '';
@Input() score: number;
@Input() duration: number;
@Input() startTime: number;
@Input() delay: number;
@Input() position: { xPercent: number, yPercent: number };
@HostBinding('style') hostStyle: SafeStyle = '';
jitterX: number;
jitterY: number;

ngOnInit() {
this.jitterX = Math.floor(Math.random() * jitterScale) - jitterScale/2;
this.jitterY = Math.floor(Math.random() * jitterScale) - jitterScale/2;
}

ngOnChanges() {
/* eh... */
this.hostStyle = this.sanitizer.bypassSecurityTrustStyle(
`left: ${this.position.xPercent +this.jitterX}%;
bottom: ${this.position.yPercent + this.jitterY}%;`);
}

canShow() {
if (this.score <= 0) {
return false;
}
if ((Date.now() - this.startTime > 0) && (Date.now() - this.startTime < this.duration)) {
return true;
}
return false;
}

get getClass() {
return tileColorByNumber(this.colour) + ` animated animate-slow ${this.getDelayClass(this.delay)} fadeOutUp f1 `;
}

getDelayClass(delay: number) {
if (delay < 1 && delay > 5 ) { return ''; }
return 'animate-delay-' + Math.floor(delay);
}

constructor(private sanitizer: DomSanitizer) {}
}
4 changes: 3 additions & 1 deletion src/front-end/angular/components/tile.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import { tileByNumber } from '../../styles';
width: 100%;
}
</style>
<div [ngClass]="value === 0 ? emptyTile : tileByNumber(value)"></div>`,
<div [ngClass]="value === 0 ? emptyTile : tileByNumber(value)">
<ng-content></ng-content>
</div>`,
})
export class Tile {
@Input() value: number;
Expand Down
28 changes: 28 additions & 0 deletions src/front-end/angular/containers/game.container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ import { Resizer } from '../../aspect-resizer';
[board]="(board$ | async)"
[level]="level$ | async"
[width]="boardWidth$ | async"
[height]="boardHeight$ | async"
[lastOverflowBonus]="lastOverflowBonus$ | async"
[lastFwBonus]="lastFwBonus$ | async"
[lastFwBonusFw]="lastFwBonusFw$ | async"
[lastClearScore]="lastClearScore$ | async"
[lastLevelScore]="lastLevelScore$ | async"
[lastScoreUpdate]="lastScoreUpdate$ | async"
[scoreDuration]="scoreAnimationDelay$ | async"
[firstAnimationBlock]="firstAnimationBlock$ | async"
></board>
<div class="w-third">
<score [score]="score$ | async"></score>
Expand Down Expand Up @@ -65,7 +74,26 @@ export class Game implements AfterViewInit, OnInit, OnDestroy {
score$;
@select(s => s.game.level)
level$;
@select(s => s.game.lastClearScore)
lastClearScore$;
@select(s => s.game.lastLevelScore)
lastLevelScore$;
@select(s => s.game.lastFwBonus)
lastFwBonus$;
@select(s => s.game.lastFwBonusFw)
lastFwBonusFw$;
@select(s => s.game.lastOverflowBonus)
lastOverflowBonus$;
@select(s => s.game.lastScoreUpdate)
lastScoreUpdate$;
@select(s => s.game.scoreAnimationDelay)
scoreAnimationDelay$;
@select(s => s.game.firstAnimationBlock)
firstAnimationBlock$;
@select(s => s.game.config.width)
boardWidth$: number;
@select(s => s.game.config.height)
boardHeight$: number;
deRegister: Function[] = [];
pause: Function;
done: Function;
Expand Down
55 changes: 49 additions & 6 deletions src/front-end/reducers/game.reducer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Block } from '../../interfaces';
import { Block, TypedArray } from '../../interfaces';

import { GameConfigOptions } from '../../interfaces';

Expand Down Expand Up @@ -38,15 +38,21 @@ export interface IGameState {
y: number;
direction: 'row' | 'column';
};
firstAnimationBlock: number;
isPaused: boolean;
isStopped: boolean;
lastEvent: { keyCode: number };
level: number;
levelProgress: number;
preview: Block[];
score: number;
scoreAnimationDelay: number;
lastAnimationBlock: number;
lastLevelScore: number;
lastClearScore: number;
lastScoreUpdate: number;
lastFwBonus: number;
lastOverflowBonus: number;
trimCols: number;
trimRows: number;
}
Expand All @@ -58,19 +64,51 @@ const INIT: IGameState = deepFreeze({
debug: true,
}),
currentGameViewportDimensions: { x: 0, y: 0, direction: 'row' as 'row' },
firstAnimationBlock: -1,
isPaused: false,
isStopped: false,
lastAnimationBlock: -1,
lastEvent: { keyCode: 0 },
lastLevelScore: 0,
lastClearScore: 0,
lastScoreUpdate: 0,
lastFwBonus: 0,
lastOverflowBonus: 0,
level: 0,
levelProgress: 0,
preview: [],
score: 0,
scoreAnimationDelay: 2000,
trimCols: 2,
trimRows: 0,
});

function getIndex(buffer: TypedArray, type: 'indexOf' | 'lastIndexOf') {
let index = buffer[type](11);
if (index < 0) {
index = buffer[type](21);
if (index < 0) {
index = buffer[type](31);
}
}
return index;
}

function getAnimationBlocks(buffer: TypedArray) {
const indexStart = getIndex(buffer, 'indexOf');
if (indexStart < 0) {
return {
firstAnimationBlock: -1,
lastAnimationBlock: -1,
};
}
const indexEnd = getIndex(buffer, 'lastIndexOf');
return {
firstAnimationBlock: indexStart,
lastAnimationBlock: indexEnd,
};
}

export function game(state = INIT, { payload, type }) {
const bMergeProp: (prop: string) => any = partial(mergeProp, state, payload);

Expand All @@ -94,7 +132,10 @@ export function game(state = INIT, { payload, type }) {
return bMergeProp('activePiece');

case UPDATE_BUFFER:
return bMergeProp('buffer');
return {
...bMergeProp('buffer'),
...getAnimationBlocks(payload),
};

case UPDATE_PREVIEW:
return bMergeProp('preview');
Expand All @@ -114,10 +155,12 @@ export function game(state = INIT, { payload, type }) {
case UPDATE_SCORE_DATA:
return {
...state,
lastLevelScore: payload.levelScore,
lastClearScore: payload.clearScore,
lastOverflowBonus: payload.overflowBonus,
lastFwBonus: payload.fwBonus,
lastLevelScore: payload.levelScore || 0,
lastClearScore: payload.clearScore || 0,
lastOverflowBonus: payload.overflowBonus || 0,
lastFwBonus: payload.fwBonus || 0,
lastFwBonusFw: payload.fw || 0,
lastScoreUpdate: Date.now(),
};

default:
Expand Down
Loading