-
-
Ready to create an app?
-
Start with Ionic UI Components
+
+
+
Plants
+
Farmers
+
Boosters
+
Upgrades
+
Stats
+
+
diff --git a/src/app/home/home.page.scss b/src/app/home/home.page.scss
index 8993e7c..861b408 100644
--- a/src/app/home/home.page.scss
+++ b/src/app/home/home.page.scss
@@ -1,27 +1,81 @@
-#container {
- text-align: center;
+#game {
+ height: 100vh;
+ width: var(--game-width);
+ background: #edd6ff;
+ margin: auto;
+ position: relative;
+}
+
+#header {
+ display: block;
+ width: var(--game-width);
+ height: calc(100vh / 6);
+ background: #d7a1fa;
+ position: relative;
+ color: black;
+ font-weight: bold;
+}
+
+#profile-picture {
position: absolute;
+ top: 0;
left: 0;
- right: 0;
- top: 50%;
- transform: translateY(-50%);
+ height: calc((100vh / 6) - 4vh);
+ aspect-ratio: calc(54/64);
+
+ img {
+ height: calc((100vh / 6) - 4vh);
+ aspect-ratio: calc(54/64);
+ margin: 2vh;
+ }
}
-#container strong {
- font-size: 20px;
- line-height: 26px;
+#seeds {
+ position: absolute;
+ top: 3vh;
+ left: calc(var(--game-width) / 2);
+ transform: translate(-50%, 0);
}
-#container p {
- font-size: 16px;
- line-height: 22px;
-
- color: #8c8c8c;
-
- margin: 0;
+#seeds-per-second {
+ position: absolute;
+ top: 6vh;
+ left: calc(var(--game-width) / 2);
+ transform: translate(-50%, 0);
}
-#container a {
- text-decoration: none;
-}
\ No newline at end of file
+#fertilizer {
+ position: absolute;
+ top: 6vh;
+ right: 1vh;
+}
+
+#star-dust {
+ position: absolute;
+ top: 9vh;
+ right: 1vh;
+}
+
+#settings {
+ position: absolute;
+ top: 1vh;
+ right: 1vh;
+}
+
+#navigation {
+ position: relative;
+ height: 3vh;
+ background: #9961c2;
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+
+ div {
+ height: 3vh;
+ width: 100%;
+ line-height: 3.6vh;
+ text-align: center;
+ }
+}
+
+
diff --git a/src/app/home/home.page.ts b/src/app/home/home.page.ts
index 83522d5..569a0c9 100644
--- a/src/app/home/home.page.ts
+++ b/src/app/home/home.page.ts
@@ -1,12 +1,58 @@
-import { Component } from '@angular/core';
+import {ChangeDetectionStrategy, Component} from '@angular/core';
+import {PlayerService} from "../player.service";
+import {FormulasService} from "../formulas.service";
+import {UtilitiesService} from "../utilities.service";
+import {PlantDto} from "../plant.dto";
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
+ // changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HomePage {
- constructor() {}
+ constructor(
+ private playerService: PlayerService,
+ private formulasService: FormulasService
+ ) {
+ this.gameLoop();
+ }
+
+ getSeeds(): number {
+ return this.playerService.seeds;
+ }
+
+ getPlants(): PlantDto[] {
+ return this.playerService.plants;
+ }
+
+ onBuy(plant: PlantDto) {
+ const price = this.formulasService.getPrice(plant.basePrice, plant.growthRate, plant.level);
+ if (price <= this.playerService.seeds) {
+ plant.level += 1;
+ this.playerService.seeds -= price;
+ }
+ }
+
+ gameLoop() {
+
+ const currentTime = Date.now();
+ const dt = currentTime - this.playerService.lastTime;
+ this.playerService.lastTime = currentTime;
+
+ for(let plant of this.playerService.plants) {
+ if (plant.level > 0) {
+ plant.timePassed += dt;
+
+ while (plant.timePassed >= plant.timeToGrow) {
+ this.playerService.seeds += plant.reward * plant.level;
+ plant.timePassed -= plant.timeToGrow;
+ }
+ }
+ }
+ this.playerService.save();
+ requestAnimationFrame(() => this.gameLoop());
+ }
}
diff --git a/src/app/plant-container/plant-container.component.html b/src/app/plant-container/plant-container.component.html
new file mode 100644
index 0000000..1a7e665
--- /dev/null
+++ b/src/app/plant-container/plant-container.component.html
@@ -0,0 +1,26 @@
+
+
+

+
Lv. {{ plant.level }}
+
+
+ Upgrade to Lv. {{ plant.level + 1 }}
+ {{ getPrice() }} seeds
+
+
+ {{ plant.name }}
+
+
+ {{ getReward() }} seeds/plant
+
+
+
+ + {{ getRewardTotal() }} seeds
+
+
diff --git a/src/app/plant-container/plant-container.component.scss b/src/app/plant-container/plant-container.component.scss
new file mode 100644
index 0000000..6fae6c5
--- /dev/null
+++ b/src/app/plant-container/plant-container.component.scss
@@ -0,0 +1,78 @@
+.plant-container {
+ position: relative;
+ width: 100%;
+ height: calc(100vh / 8);
+ background: #005BBB;
+ margin-top: 1vh;
+}
+
+.plant-image {
+ position: absolute;
+ top: 1vh;
+ right: 1vh;
+ height: calc(100vh / 8 - 2vh);
+ width: calc(100vh / 8 - 2vh);
+
+ .plant-level {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 1.2em;
+ line-height: 1.6em;
+ text-align: center;
+ background: #0d0d0d66;
+ }
+}
+
+.plant-progress {
+ position: absolute;
+ bottom: 1vh;
+ left: 1vh;
+ width: calc(100% - 1vh - 100vh / 8);
+ height: 3vh;
+ border: 1px solid black;
+}
+
+.reward-total {
+ position: absolute;
+ bottom: 1vh;
+ right: calc(100vh / 8);
+ width: calc((100% - 1vh - 100vh / 8) / 3);
+ text-align: right;
+ padding-right: 1vh;
+ height: 3vh;
+ line-height: 180%;
+}
+
+.upgrade-button {
+ position: absolute;
+ top: 1vh;
+ left: 1vh;
+ text-align: center;
+ height: calc(100vh / 8 - 6vh);
+ line-height: calc((100vh / 8 - 6vh) / 2);
+ background: #FFD500;
+ width: 20vh;
+ color: black;
+ font-weight: bold;
+}
+
+.reward {
+ position: absolute;
+ top: calc(100vh / 16 - 2vh);
+ left: 22vh;
+ text-align: center;
+ height: calc(100vh / 16 - 3vh);
+ line-height: calc(100vh / 16 - 3vh);
+ width: calc(100% - 1vh - 100vh / 8 - 21vh);
+}
+.name {
+ position: absolute;
+ top: 1vh;
+ left: 22vh;
+ text-align: center;
+ height: calc(100vh / 16 - 3vh);
+ line-height: calc(100vh / 16 - 3vh);
+ width: calc(100% - 1vh - 100vh / 8 - 21vh);
+}
diff --git a/src/app/plant-container/plant-container.component.spec.ts b/src/app/plant-container/plant-container.component.spec.ts
new file mode 100644
index 0000000..580016b
--- /dev/null
+++ b/src/app/plant-container/plant-container.component.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { IonicModule } from '@ionic/angular';
+
+import { PlantContainerComponent } from './plant-container.component';
+
+describe('PlantContainerComponent', () => {
+ let component: PlantContainerComponent;
+ let fixture: ComponentFixture
;
+
+ beforeEach(waitForAsync(() => {
+ TestBed.configureTestingModule({
+ declarations: [ PlantContainerComponent ],
+ imports: [IonicModule.forRoot()]
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(PlantContainerComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ }));
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/plant-container/plant-container.component.ts b/src/app/plant-container/plant-container.component.ts
new file mode 100644
index 0000000..371e977
--- /dev/null
+++ b/src/app/plant-container/plant-container.component.ts
@@ -0,0 +1,53 @@
+import {ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {FormulasService} from "../formulas.service";
+import {UtilitiesService} from "../utilities.service";
+import {PlantDto} from "../plant.dto";
+
+@Component({
+ selector: 'app-plant-container',
+ templateUrl: './plant-container.component.html',
+ styleUrls: ['./plant-container.component.scss'],
+ // changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class PlantContainerComponent implements OnInit {
+
+ @Input('plant') plant: PlantDto | undefined;
+ @Output('onBuy') onBuy = new EventEmitter();
+
+ constructor(
+ private formulasService: FormulasService,
+ private utilitiesService: UtilitiesService
+ ) { }
+
+ ngOnInit() {}
+
+ buy() {
+ this.onBuy.emit(this.plant);
+ }
+
+ getPrice() {
+ if (!this.plant) return 0;
+ return this.formulasService.getPrice(this.plant.basePrice, this.plant.growthRate, this.plant.level);
+ }
+
+ getReward() {
+ if (!this.plant) return 0;
+ return this.plant.reward;
+ }
+
+ getRewardTotal() {
+ if (!this.plant) return 0;
+ return this.plant.level * this.plant.reward;
+ }
+
+ progress(): number {
+ if (!this.plant) return 0;
+ return this.plant.timePassed / this.plant.timeToGrow * 100;
+ }
+
+ timeLeft(): string {
+ if (!this.plant) return '';
+ return this.utilitiesService.convertToTime(this.plant.timeToGrow - this.plant.timePassed);
+ }
+
+}
diff --git a/src/app/plant.dto.ts b/src/app/plant.dto.ts
new file mode 100644
index 0000000..cf8bf7f
--- /dev/null
+++ b/src/app/plant.dto.ts
@@ -0,0 +1,9 @@
+export type PlantDto = {
+ name: string,
+ level: number,
+ basePrice: number,
+ growthRate: number,
+ timeToGrow: number,
+ timePassed: number,
+ reward: number,
+}
diff --git a/src/app/player.service.spec.ts b/src/app/player.service.spec.ts
new file mode 100644
index 0000000..5355445
--- /dev/null
+++ b/src/app/player.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { PlayerService } from './player.service';
+
+describe('PlayerService', () => {
+ let service: PlayerService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(PlayerService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/app/player.service.ts b/src/app/player.service.ts
new file mode 100644
index 0000000..aa9671d
--- /dev/null
+++ b/src/app/player.service.ts
@@ -0,0 +1,102 @@
+import { Injectable } from '@angular/core';
+import {PlantDto} from "./plant.dto";
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PlayerService {
+
+ public lastTime = Date.now();
+ public seeds: number = 0;
+ public plants: PlantDto[] = [
+ {
+ name: 'Plant 1',
+ level: 1,
+ basePrice: 4,
+ growthRate: 1.07,
+ timeToGrow: 600,
+ timePassed: 0,
+ reward: 1,
+ },
+ {
+ name: 'Plant 2',
+ level: 0,
+ basePrice: 60,
+ growthRate: 1.15,
+ timeToGrow: 3000,
+ timePassed: 0,
+ reward: 60,
+ },
+ {
+ name: 'Plant 3',
+ level: 0,
+ basePrice: 720,
+ growthRate: 1.14,
+ timeToGrow: 6000,
+ timePassed: 0,
+ reward: 540,
+ },
+ {
+ name: 'Plant 4',
+ level: 0,
+ basePrice: 8640,
+ growthRate: 1.13,
+ timeToGrow: 12000,
+ timePassed: 0,
+ reward: 4320,
+ },
+ {
+ name: 'Plant 5',
+ level: 0,
+ basePrice: 103680,
+ growthRate: 1.12,
+ timeToGrow: 24000,
+ timePassed: 0,
+ reward: 51840,
+ },
+ {
+ name: 'Plant 6',
+ level: 0,
+ basePrice: 51200,
+ growthRate: 1.11,
+ timeToGrow: 45000,
+ timePassed: 0,
+ reward: 102400,
+ },
+ {
+ name: 'Plant 7',
+ level: 0,
+ basePrice: 1000000,
+ growthRate: 1.106,
+ timeToGrow: 60000,
+ timePassed: 0,
+ reward: 204800,
+ },
+ {
+ name: 'Plant 8',
+ level: 0,
+ basePrice: 5000000,
+ growthRate: 1.10,
+ timeToGrow: 60000,
+ timePassed: 0,
+ reward: 614150,
+ }
+ ];
+ constructor() {
+ const data = localStorage.getItem('PlayerSave');
+ if (data) {
+ const parsed = JSON.parse(data);
+ this.plants = parsed.plants;
+ this.seeds = parsed.seeds;
+ this.lastTime = parsed.lastTime ? parsed.lastTime : Date.now();
+ }
+ }
+
+ save() {
+ localStorage.setItem('PlayerSave', JSON.stringify({
+ seeds: this.seeds,
+ plants: this.plants,
+ lastTime: this.lastTime
+ }));
+ }
+}
diff --git a/src/app/progress-bar/progress-bar.component.html b/src/app/progress-bar/progress-bar.component.html
new file mode 100644
index 0000000..262e002
--- /dev/null
+++ b/src/app/progress-bar/progress-bar.component.html
@@ -0,0 +1,4 @@
+
+
+
{{ progressBarText }}
+
diff --git a/src/app/progress-bar/progress-bar.component.scss b/src/app/progress-bar/progress-bar.component.scss
new file mode 100644
index 0000000..dddb247
--- /dev/null
+++ b/src/app/progress-bar/progress-bar.component.scss
@@ -0,0 +1,20 @@
+.progress-bar-container {
+ position: relative;
+ width: 100%;
+ height: 100%;
+
+ .progress-bar-progress {
+ position: absolute;
+ right: 0;
+ top: 0;
+ height: 100%;
+ }
+
+ .progress-bar-text {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ line-height: 180%;
+ }
+}
diff --git a/src/app/progress-bar/progress-bar.component.spec.ts b/src/app/progress-bar/progress-bar.component.spec.ts
new file mode 100644
index 0000000..96e97e1
--- /dev/null
+++ b/src/app/progress-bar/progress-bar.component.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { IonicModule } from '@ionic/angular';
+
+import { ProgressBarComponent } from './progress-bar.component';
+
+describe('ProgressBarComponent', () => {
+ let component: ProgressBarComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(waitForAsync(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ProgressBarComponent ],
+ imports: [IonicModule.forRoot()]
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(ProgressBarComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ }));
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/progress-bar/progress-bar.component.ts b/src/app/progress-bar/progress-bar.component.ts
new file mode 100644
index 0000000..8d5b4fe
--- /dev/null
+++ b/src/app/progress-bar/progress-bar.component.ts
@@ -0,0 +1,20 @@
+import {ChangeDetectionStrategy, Component, Input, OnInit} from '@angular/core';
+
+@Component({
+ selector: 'app-progress-bar',
+ templateUrl: './progress-bar.component.html',
+ styleUrls: ['./progress-bar.component.scss'],
+ // changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class ProgressBarComponent implements OnInit {
+
+ @Input('fill') fill: number = 0;
+ @Input('progressBarText') progressBarText: string = '';
+ @Input('backgroundColor') backgroundColor: string = '#1a1a1a';
+ @Input('fillColor') fillColor: string = '#2dd36f';
+
+ constructor() { }
+
+ ngOnInit() {}
+
+}
diff --git a/src/app/utilities.service.ts b/src/app/utilities.service.ts
new file mode 100644
index 0000000..170879c
--- /dev/null
+++ b/src/app/utilities.service.ts
@@ -0,0 +1,34 @@
+import { Injectable } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class UtilitiesService {
+
+ constructor() { }
+
+ convertToTime(num: number) {
+ num = Math.round(num / 1000);
+ const days = Math.floor(num / 60 / 60 / 24);
+ num -= days * 60 * 60 * 24;
+ const hours = Math.floor(num / 60 / 60);
+ num -= hours * 60 * 60;
+ const minutes = Math.floor(num / 60);
+ num -= minutes * 60;
+ const seconds = num;
+
+ if (days) {
+ return days + ' ' + (hours > 9 ? hours : '0' + hours) + ':' + (minutes > 9 ? minutes : '0' + minutes) + ':' + (seconds > 9 ? seconds : '0' + seconds);
+ }
+
+ if (hours) {
+ return (hours > 9 ? hours : '0' + hours) + ':' + (minutes > 9 ? minutes : '0' + minutes) + ':' + (seconds > 9 ? seconds : '0' + seconds);
+ }
+
+ if (minutes) {
+ return (minutes > 9 ? minutes : '0' + minutes) + ':' + (seconds > 9 ? seconds : '0' + seconds);
+ }
+
+ return seconds + ' sec';
+ }
+}
diff --git a/src/app/utils.service.spec.ts b/src/app/utils.service.spec.ts
new file mode 100644
index 0000000..d7950f3
--- /dev/null
+++ b/src/app/utils.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { UtilitiesService } from './utilities.service';
+
+describe('UtilsService', () => {
+ let service: UtilitiesService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(UtilitiesService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/assets/pfp-default.kra b/src/assets/pfp-default.kra
new file mode 100644
index 0000000..3a93bc5
Binary files /dev/null and b/src/assets/pfp-default.kra differ
diff --git a/src/assets/pfp-default.png b/src/assets/pfp-default.png
new file mode 100644
index 0000000..0339957
Binary files /dev/null and b/src/assets/pfp-default.png differ
diff --git a/src/assets/plant.png b/src/assets/plant.png
new file mode 100644
index 0000000..180a862
Binary files /dev/null and b/src/assets/plant.png differ
diff --git a/src/global.scss b/src/global.scss
index d854de8..e2775aa 100644
--- a/src/global.scss
+++ b/src/global.scss
@@ -24,3 +24,20 @@
@import "~@ionic/angular/css/text-alignment.css";
@import "~@ionic/angular/css/text-transformation.css";
@import "~@ionic/angular/css/flex-utils.css";
+
+@import url('https://fonts.googleapis.com/css2?family=Solitreo&display=swap');
+:root {
+ --game-width: calc(100vh / 16 * 9)
+}
+
+body {
+ overflow: hidden;
+}
+
+* {
+ font-family: 'Solitreo', cursive;
+ font-size: 2vh;
+ -webkit-user-select: none; /* Safari */
+ -ms-user-select: none; /* IE 10 and IE 11 */
+ user-select: none; /* Standard syntax */
+}
diff --git a/src/index.html b/src/index.html
index 3b0aae1..4c514c7 100644
--- a/src/index.html
+++ b/src/index.html
@@ -3,7 +3,7 @@
- Ionic App
+ Lily - Idle