Biotrivia beginning

This commit is contained in:
Kaloian Venkov 2021-03-12 17:38:17 +02:00
parent 8de461b6c0
commit fa0b286911
16 changed files with 273 additions and 35 deletions

View File

@ -1,11 +1,12 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { MinigameBiotriviaComponent } from './minigame-biotrivia/minigame-biotrivia.component';
import { MinigameConveyorRecyclingComponent } from './minigame-conveyor-recycling/minigame-conveyor-recycling.component';
const routes: Routes = [
{ path: 'minigames/conveyor-belt', component: MinigameConveyorRecyclingComponent, data: { animation: 'conveyor-belt-mg' } },
{ path: 'minigames/biotrivia', component: MinigameConveyorRecyclingComponent, data: { animation: 'biotrinia-mg' } },
{ path: 'minigames/biotrivia', component: MinigameBiotriviaComponent, data: { animation: 'biotrinia-mg' } },
{ path: '', component: DashboardComponent, data: { animation: 'home' } },
];

View File

@ -1,4 +1,4 @@
<div class="container" #container>
<div class="container dialog" #container>
<div class="tags">
<div class="contents" *ngFor="let type of card.types" >
<div [class]="[type, 'icon']" *ngIf="type !== 'normal'"></div>

View File

@ -82,11 +82,6 @@
border-radius: 1em;
padding: 1em;
box-shadow: #0004 3px 3px 5px;
background-color: #f8f8f855;
backdrop-filter: blur(10px);
button {
margin: 0 auto;
display: block;

View File

@ -10,8 +10,9 @@
flex-wrap: wrap;
width: 100%;
gap: 2em;
padding: 1em 0;
padding: 1em;
box-sizing: border-box;
justify-content: center;
}
.card {
scroll-snap-align: start;

View File

@ -9,7 +9,8 @@
flex-wrap: wrap;
width: 100%;
gap: 2em;
padding: 1em 0;
justify-content: center;
padding: 1em;
scroll-snap-type: y mandatory;
box-sizing: border-box;
}

View File

@ -16,11 +16,22 @@ export interface Card {
name: string;
types: Array<"endangered" | "normal">;
}
export interface MultipleChoiseAnswer {
type: 'multiple-choise';
choises: string[];
correctChoise: string;
}
export interface Question {
category: string;
question: string;
photoUrlsAbove?: string[];
answer: MultipleChoiseAnswer;
}
export interface Saved<T> {
id: string;
el: T;
}
@Injectable({
providedIn: 'root'
})
@ -298,11 +309,111 @@ export class DbService {
},
},
];
private mock_questions: Saved<Question>[] = [
{
id: '0',
el: {
category: 'animals',
photoUrlsAbove: [ '/assets/images/questions/slon.jpg' ],
question: 'Защо бройката на слоновете в Африка намалява?',
answer: {
type: 'multiple-choise',
choises: [
'Убиван е от други животни',
'Липса на храна',
'Убивани са от бракониери',
'Замърсяване на въздуха'
],
correctChoise: 'Убивани са от бракониери',
}
}
},
{
id: '1',
el: {
category: 'animals',
photoUrlsAbove: [ '/assets/images/questions/carski orel.jpg' ],
question: 'Каква е главната причина за намаляването на бройките Царски орли?',
answer: {
type: 'multiple-choise',
choises: [
'Бракониери',
'Замърсяване',
'Отсичане на горите',
'Електрически стълбове'
],
correctChoise: 'Електрически стълбове',
}
}
},
{
id: '2',
el: {
category: 'animals',
photoUrlsAbove: [ '/assets/images/questions/carski orel.jpg' ],
question: 'Каква е главната причина за намаляването на бройките Царски орли?',
answer: {
type: 'multiple-choise',
choises: [
'Бракониери',
'Замърсяване',
'Отсичане на горите',
'Електрически стълбове'
],
correctChoise: 'Електрически стълбове',
}
}
},
{
id: '3',
el: {
category: 'animals',
photoUrlsAbove: [ '/assets/images/questions/zlatna zhaba.png' ],
question: 'Каква е причината за изчезването на Златната жаба?',
answer: {
type: 'multiple-choise',
choises: [
'Глобално затопляне',
'Замърсяване на реките',
'Отсичане на горите',
'Недостиг на храна'
],
correctChoise: 'Глобално затопляне',
}
}
},
{
id: '4',
el: {
category: 'animals',
photoUrlsAbove: [ '/assets/images/questions/shtigga.png' ],
question: 'Каква е причината за намаляването на бройките на Черният щъркел?',
answer: {
type: 'multiple-choise',
choises: [
'Замърсяването на блатата и езерата',
'Недостиг на храна',
'Глобално затопляне',
'Естествени врагове',
],
correctChoise: 'Замърсяването на блатата и езерата',
}
}
},
];
private getRandomEl<T>(array: T[]): T {
const index = Math.floor(Math.random() * array.length);
return array[index];
private getRandomEls<T>(array: T[], n: number): T[] {
const result: T[] = new Array(n);
let len = array.length;
const taken = new Array(len);
if (n > len)
throw new RangeError("getRandom: more elements taken than available");
while (n--) {
const x = Math.floor(Math.random() * len);
result[n] = array[x in taken ? taken[x] : x];
taken[x] = --len in taken ? taken[len] : len;
}
return result;
}
getAllMinigames(): Saved<Minigame>[] {
@ -325,5 +436,11 @@ export class DbService {
else return this.mock_card_types[index].el;
}
getRandomQuestions(n: number, category: string): Question[] {
return this.getRandomEls(this.mock_questions
.filter(v => v.el.category === category)
.map(v => v.el), n);
}
constructor() { }
}

View File

@ -1 +1,15 @@
<p>minigame-biotrivia works!</p>
<div class="container">
<div class="start-dialog dialog" *ngIf="stage === 'starting' || stage === 'starting-ongoing'" #startDialog>
<h4>Пробвай познанията си за екология</h4>
<p>
В тази викторина ще има 5 въпроса, които ще тестват вашите познания по екология.
Накрая, в зависимост от познатите отговори, ще получите по-рядка карта или
по-обикновена карта</p>
<button igxButton igxRipple (click)="startGame()">Продължи към играта</button>
<div class="separator"></div>
<button igxButton igxRipple routerLink="" >Върни се в началния екран</button>
</div>
<div class="question dialog" *ngIf="stage === 'ongoing' || stage === 'starting-ongoing'" #ongoingDialog>
<h4></h4>
</div>
</div>

View File

@ -0,0 +1,34 @@
.container {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
.start-dialog {
width: 600px;
max-width: 100%;
}
.dialog {
padding: 2em;
box-sizing: border-box;
border-radius: .5em;
button {
margin: 0 auto;
display: block;
}
h4 {
text-align: center;
margin: 0 2em;
margin-top: 0;
}
.separator {
height: .5em;
width: 100%;
}
p {
text-align: center;
}
}
}

View File

@ -1,4 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { Component, ElementRef, NgZone, OnInit, ViewChild, ViewChildren } from '@angular/core';
import { Observable, Subject } from 'rxjs';
@Component({
selector: 'app-minigame-biotrivia',
@ -6,10 +8,71 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./minigame-biotrivia.component.scss']
})
export class MinigameBiotriviaComponent implements OnInit {
@ViewChildren('startDialog') startingElementRef;
@ViewChildren('ongoingDialog') ongoingElementRef;
constructor() { }
guessedQuestions = 0;
stage: 'starting' | 'starting-ongoing' | 'ongoing' | 'ended' = 'starting';
constructor(
private zone: NgZone,
) { }
ngOnInit(): void {
}
animateElements(el1: HTMLElement, el2: HTMLElement): Observable<void> {
const a = new Subject<void>();
el1.style.position = 'absolute';
el1.animate([
{
transform: 'translateX(0)',
opacity: 1,
},
{
transform: 'translateX(-100vh)',
opacity: 0,
},
], {
duration: 200,
easing: 'ease-in',
}).onfinish = () => {
el1.style.opacity = '0';
};
el2.animate([
{
transform: 'translateX(100vh)',
opacity: 0,
},
{
transform: 'translateX(0)',
opacity: 1,
},
], {
duration: 200,
easing: 'ease-out',
}).onfinish = () => {
a.next();
};
return a;
}
startGame(): void {
if (this.stage !== 'starting') return;
console.log(this.ongoingElementRef);
const startingEl = this.startingElementRef.first.nativeElement as HTMLElement;
startingEl.style.position = 'absolute';
this.stage = 'starting-ongoing';
setTimeout(() => {
const ongoingEl = this.ongoingElementRef.first.nativeElement as HTMLElement;
// tslint:disable-next-line: deprecation
this.animateElements(startingEl, ongoingEl).subscribe(() => {
this.stage = 'ongoing';
});
}, 10);
}
}

View File

@ -1,8 +1,9 @@
<div class="container" #container>
<div class="container dialog" #container>
<div class="main">
<div class="contents" #frontSide *ngIf="!flipped">
<h6>{{minigame.name}}</h6>
<h6>{{minigame.name}} <span *ngIf="minigame.comingSoon">(не е готова)</span></h6>
</div>
<div class="contents" *ngIf="!minigame.comingSoon">
<p *ngIf="minigameUserdata.played">
Вече сте играли тази игра и {{hasMedal() ? 'имате' : 'нямате'}} {{getMedalType()}} медал
</p>
@ -10,5 +11,9 @@
Все още не сте играли тази игра
</p>
</div>
<button igxButton igxRipple (click)="play()">Играй {{minigameUserdata.played ? 'отново' : ''}}</button>
<p *ngIf="minigame.comingSoon">
Тази игра все още се разработва
</p>
</div>
<button [disabled]="minigame.comingSoon" igxButton igxRipple (click)="play()">Играй {{minigameUserdata.played ? 'отново' : ''}}</button>
</div>

View File

@ -49,11 +49,6 @@
border-radius: 1em;
padding: 1em;
box-shadow: #0004 3px 3px 5px;
background-color: #f8f8f855;
backdrop-filter: blur(10px);
button {
margin: 0 auto;
display: block;

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 KiB

View File

@ -6,6 +6,10 @@ html {
width: 100%;
height: 100%;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
box-sizing: border-box;
}
html {
background-image: url('/assets/images/Forest BG.png');
background-size: cover
}
@ -30,3 +34,11 @@ $my-color-palette: igx-palette($primary: $company-color,
.contents {
display: contents;
}
* {
box-sizing: border-box;
}
.dialog {
background-color: #f8f8f855;
backdrop-filter: blur(10px);
box-shadow: #0004 3px 3px 5px;
}