Phaser how to have an object accessible in multiple scenes - phaser-framework

I've made an inventory object for my game. Here is its code:
class player extends Phaser.GameObjects{
constructor(){
super();
this.stuff = [null,null,null,null,null,null,null,null,null,null];
}
collcet(item) {
this.space = 0;
while (this.space < 10){
if (this.items[this.space] == null){
this.items[this.space] == item;
break;
}
else {
this.space += 1;
}
}
}
has(item){
this.space = 0;
this.result = false
while (this.space < 10){
if (this.items[this.space] == item){
this.result = true;
break;
}
else {
this.space += 1;
}
}
return this.result;
}
takeOut(item){
this.space = 0;
while (this.space < 10){
if (this.items[this.space] == item){
this.items[this.space] == null;
break;
}
else {
this.space += 1;
}
}
}
}
I want to have a single inventory that is accessible in all scenes of my game, but I'm using switch statements to change scenes, which I faintly remember don't allow for data to be shared between scenes. Is there any way I can have this inventory work, or do I need to rethink the whole thing?
If it helps, I'm using Phaser 3 in VSCode, employing arcade physics.

Start or add your scenes first, then switch between them. When you start them, pass your game state:
export default class BootScene extends Phaser.Scene {
constructor() {
super({ key: "BootScene" });
}
preload() {
this.gameState = {
inventory: [ some stuff ],
}
}
create() {
const startScene = false;
this.scene.add("InventoryScene", InventoryScene, startScene, this.gameState);
this.scene.start("GameScene", this.gameState);
}
}
Now switch between your scenes:
export default class GameScene extends Phaser.Scene {
constructor() {
super({ key: "GameScene" });
}
init(gameState) {
this.gameState = gameState;
}
update() {
if player presses "i" {
this.scene.switch("InventoryScene");
}
}
The state you passed is available within the scene.
export default class InventoryScene extends Phaser.Scene {
constructor() {
super({ key: "InventoryScene" });
}
init(gameState) {
this.gameState = gameState;
}
update() {
const { some stuff } = this.gameState.inventory;
if player presses "esc" {
this.scene.switch("GameScene");
}
}

Related

How to log stacktrace on NestJS + GraphQL?

I'm trying out NestJS + GraphQL using Apollo underneath. When I set the Apollo 'debug' option to be true, I can see the stacktrace in the response but I cannot find a way to log this stacktrace in our application logs.
I would like to have it in the log to troubleshoot issues in production. Is there a way to do this?
Here's the ApolloServerPlugin I use
import { Plugin } from '#nestjs/apollo';
import { Logger } from '#nestjs/common';
import {
ApolloServerPlugin,
GraphQLRequestListener,
} from 'apollo-server-plugin-base';
import {
BaseContext,
GraphQLRequestContext,
GraphQLRequestContextWillSendResponse,
} from 'apollo-server-types';
import * as util from 'util';
#Plugin()
export class LoggingPlugin implements ApolloServerPlugin {
constructor(private readonly logger: Logger) {}
async requestDidStart(
requestContext: GraphQLRequestContext,
): Promise<GraphQLRequestListener> {
const thatLogger = this.logger;
if (requestContext.request.operationName !== 'IntrospectionQuery') {
thatLogger.log(
`request query: ${requestContext.request.query || 'undefined'}`,
);
}
return {
async willSendResponse(
requestContextWillSendResponse: GraphQLRequestContextWillSendResponse<BaseContext>,
): Promise<void> {
if (
requestContextWillSendResponse.request.operationName !==
'IntrospectionQuery'
) {
if (!requestContextWillSendResponse.errors) {
thatLogger.log(`response without any errors`);
} else {
const errors = requestContextWillSendResponse.errors.concat();
const responseErrors =
requestContextWillSendResponse.response.errors?.concat();
if (errors && responseErrors) {
for (let i = 0; i < errors.length; i++) {
const result = {
...responseErrors[i],
stack: errors[i].stack,
};
if (result.extensions) {
delete result.extensions.exception;
}
if (
result.extensions &&
result.extensions.code !== 'INTERNAL_SERVER_ERROR'
) {
thatLogger.warn(
`response with errors: ${util.inspect(result, {
depth: 4,
})}`,
);
} else {
thatLogger.error(
`response with errors: ${util.inspect(result, {
depth: 4,
})}`,
);
}
}
}
}
}
},
};
}
}
I was able to do this using ApolloServerPlugin.

I am trying to host a project I built on two separate repositories

I have a MEAN stack project that is built on two separate repositories. The backend is using Node.js and handles all API routing to MongoDB Atlas. If i wanted to host this on something like firebase, how would I go about that? I am not sure of any way to do this and haven't found similar scenarios such as this online.
This is an example of one of the components from the frontend.
The html file
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { FamilyService } from '../family.service';
import { IncomeService } from '../income.service';
#Component({
selector: 'app-income',
templateUrl: './income.component.html',
styleUrls: ['./income.component.scss']
})
export class IncomeComponent implements OnInit {
date: any;
family: any;
amount: any;
Incomes: any = [];
Families: any = [];
constructor(private router: Router, private familyService: FamilyService, private incomeService: IncomeService) {
this.date = new Date().toDateString();
this.family = ""
this.amount = ""
}
ngOnInit(): void {
this.getFamilies()
this.getIncomes()
}
createNewIncome(){
let request = {
family: this.family,
amount: this.amount,
Date: this.date
}
console.log(request.family);
this.incomeService.createIncome(request).subscribe((response: any) => {
this.getIncomes()
});
}
getFamilies(){
let familyInfo:any = []
this.familyService.getFamily().subscribe((res: any) => {
let arr = res
arr.forEach((family: any) => {
// console.log(element)
if(family.status == "active"){
familyInfo.push(family)
}
});
});
console.log(familyInfo);
this.Families = familyInfo
}
getIncomes(){
let incomeInfo:any = []
this.incomeService.getIncome().subscribe((res: any) => {
let arr = res
arr.forEach((element: any) => {
// console.log(element)
incomeInfo.push(element)
});
});
console.log(incomeInfo);
this.Incomes = incomeInfo
}
goToPage(PageName:string):void{
this.router.navigate([`${PageName}`]);
// else
// outterrormessage
}
addEntry():void{
console.log(this.date + " " + this.family + " " + this.amount)
let entry = {
Date: this.date,
family: this.family,
amount: this.amount
}
this.Incomes.push(entry)
console.log(this.Incomes)
}
deleteEntry(entry:any):void {
if(confirm("Are you sure you would like to delete this entry?")){
this.incomeService.deleteIncome(entry._id).subscribe((res: any) => {
this.getIncomes() // Once the record gets deleted we refetch
})
}
}
updateEntry(entry:any):void {
if(confirm("Are you sure you would like to update this entry?")){
this.incomeService.updateIncome(entry._id, entry).subscribe((res:any) => {
this.getIncomes() // After the record gets edited we refetch
})
}
}
toggleEditEntry(entry:any){
entry.isEditing = !entry.isEditing;
}
}
The service.ts file
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { FamilyService } from '../family.service';
import { IncomeService } from '../income.service';
#Component({
selector: 'app-income',
templateUrl: './income.component.html',
styleUrls: ['./income.component.scss']
})
export class IncomeComponent implements OnInit {
date: any;
family: any;
amount: any;
Incomes: any = [];
Families: any = [];
constructor(private router: Router, private familyService: FamilyService, private incomeService: IncomeService) {
this.date = new Date().toDateString();
this.family = ""
this.amount = ""
}
ngOnInit(): void {
this.getFamilies()
this.getIncomes()
}
createNewIncome(){
let request = {
family: this.family,
amount: this.amount,
Date: this.date
}
console.log(request.family);
this.incomeService.createIncome(request).subscribe((response: any) => {
this.getIncomes()
});
}
getFamilies(){
let familyInfo:any = []
this.familyService.getFamily().subscribe((res: any) => {
let arr = res
arr.forEach((family: any) => {
// console.log(element)
if(family.status == "active"){
familyInfo.push(family)
}
});
});
console.log(familyInfo);
this.Families = familyInfo
}
getIncomes(){
let incomeInfo:any = []
this.incomeService.getIncome().subscribe((res: any) => {
let arr = res
arr.forEach((element: any) => {
// console.log(element)
incomeInfo.push(element)
});
});
console.log(incomeInfo);
this.Incomes = incomeInfo
}
goToPage(PageName:string):void{
this.router.navigate([`${PageName}`]);
// else
// outterrormessage
}
addEntry():void{
console.log(this.date + " " + this.family + " " + this.amount)
let entry = {
Date: this.date,
family: this.family,
amount: this.amount
}
this.Incomes.push(entry)
console.log(this.Incomes)
}
deleteEntry(entry:any):void {
if(confirm("Are you sure you would like to delete this entry?")){
this.incomeService.deleteIncome(entry._id).subscribe((res: any) => {
this.getIncomes() // Once the record gets deleted we refetch
})
}
}
updateEntry(entry:any):void {
if(confirm("Are you sure you would like to update this entry?")){
this.incomeService.updateIncome(entry._id, entry).subscribe((res:any) => {
this.getIncomes() // After the record gets edited we refetch
})
}
}
toggleEditEntry(entry:any){
entry.isEditing = !entry.isEditing;
}
}
The web service
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class WebRequestService {
//Root URL wrapped in constant
readonly ROOT_URL;
//Returns http method observables
constructor(private http: HttpClient) {
this.ROOT_URL = `http://localhost:3000`;
}
//Getting one
get(uri: string) {
return this.http.get(`${this.ROOT_URL}/${uri}`);
}
//Creating one
post(uri: string, payload: Object) {
return this.http.post(`${this.ROOT_URL}/${uri}`, payload);
}
//Updating one
patch(uri: string, payload: Object) {
return this.http.patch(`${this.ROOT_URL}/${uri}`, payload);
}
//Deleting one
delete(uri: string) {
return this.http.delete(`${this.ROOT_URL}/${uri}`);
}
}
This is my first time working with Angular and a MEAN stack so I apologize for the poor programming practices here.If you need I can also upload the backend code: routes, models, and service files.

Angular Interval service not showing JSON data from Node backend on production

I have the following code, where I make a timer and an interval to two different services of a backend in node with oracledb, locally it works well for me but when deploying it in production sometimes the data is lost, as if some calls were blocked
#Component({
selector: "app-qr",
templateUrl: "./qr.component.html",
styleUrls: ["./qr.component.css"],
})
export class QrComponent implements OnDestroy {
loginDisplay = false;
sub: Subscription;
sub2: Subscription;
sub3: Subscription;
data: any;
dataEmpleado: any;
contador: number;
constructor(
private asistenciaService: AsistenciaService
) {
this.obtenerQR();
}
ngOnDestroy(): void {
this.sub.unsubscribe();
this.sub3.unsubscribe();
}
obtenerQR() {
this.sub = timer(0, 1000)
.pipe(switchMap(() => this.asistenciaService.obtenerQR()))
.subscribe((data) => {
if (data.nuevo === true) {
this.contador = 1;
}
this.contador = this.contador + 1;
this.data = data;
});
this.contador = this.contador + 1;
this.sub3 = interval(3000).subscribe((x) => {
this.asistenciaService.obtenerUltimoEmpleadoMarco().subscribe(
(data) => {
this.dataEmpleado = data;
}
);
});
}
}

Mediafilepicker video file selection(display video on the app)

I am using Mediafilepicker plugin to pick a video file from my device, but when I select the video it doesn't display on the app but once I press (pick a video) button for the second time its when the video shows
I searched for a similar problem but didn't find any
public pickvideo(){
let options: VideoPickerOptions = {
android: {
isCaptureMood: false,
isNeedCamera: true,
maxNumberFiles: 1,
isNeedFolderList: true,
maxDuration: 20,
},
};
let mediafilepicker = new Mediafilepicker();
mediafilepicker.openVideoPicker(options);
mediafilepicker.on("getFiles", res => {
let results = res.object.get('results');
this.videoSrc = results[0].file;
console.dir(results);
if (results) {
for (let i = 0; i < results.length; i++) {
let result = results[i];
console.dir(result);
let file = result.file;
console.log(file);
}
}
It doesn't show any errors
Use this code for pick a video from gallery and show in the app.
media-picker.component.ts:-
import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from "#angular/core";
import { Page } from "tns-core-modules/ui/page";
import * as app from 'tns-core-modules/application';
import { Mediafilepicker, VideoPickerOptions } from 'nativescript-mediafilepicker';
declare const AVCaptureSessionPreset1920x1080, AVCaptureSessionPresetHigh;
#Component({
selector: "media-picker",
moduleId: module.id,
templateUrl: "./media-picker.component.html",
styleUrls: ["./media-picker.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MideaPickerComponent implements OnInit {
public videoFileUrl: Array<string> = [];
constructor(public page: Page,
private ref: ChangeDetectorRef) {
// Use the constructor to inject services.
// Get reference to object we want to animate with code
}
ngOnInit(): void {
}
//Open video gallery list
public openVideoGallery() {
let allowedVideoQualities = [];
if (app.ios) {
allowedVideoQualities = [AVCaptureSessionPreset1920x1080, AVCaptureSessionPresetHigh];
}
let options: VideoPickerOptions = {
android: {
isCaptureMood: false,
isNeedCamera: true,
maxNumberFiles: 2,
isNeedFolderList: true,
maxDuration: 20,
},
ios: {
isCaptureMood: false
}
};
let mediafilepicker = new Mediafilepicker();
mediafilepicker.openVideoPicker(options);
mediafilepicker.on("getFiles", (res) => {
let results = res.object.get('results');
if (results) {
this.videoFileUrl = [];
for (let i = 0; i < results.length; i++) {
let result = results[i];
let file = result.file;
this.videoFileUrl.push(file);
if (result.file && app.ios && !options.ios.isCaptureMood) {
let fileName = file.replace(/^.*[\/]/, '');
setTimeout(() => {
mediafilepicker.copyPHVideoToAppDirectory(result.urlAsset, fileName).then(res => {
console.dir(res);
}).catch(e => {
console.dir(e);
});
}, 1000);
} else if (result.file && app.ios) {
// or we will get our own recorded video :)
console.log(file);
}
}
}
});
mediafilepicker.on("error", (res) => {
let msg = res.object.get('msg');
console.log(msg);
});
mediafilepicker.on("cancel", (res) => {
let msg = res.object.get('msg');
console.log(msg);
});
setInterval(() => {
// require view to be updated
this.ref.markForCheck();
}, 500);
}
}
media-picker.component.html:-
<StackLayout row="0">
<Button height="50" (tap)="openVideoGallery()" text="Open Video Gallery">
</Button>
</StackLayout>
<StackLayout row="1">
<VideoPlayer *ngFor="let video of videoFileUrl" src="{{video}}" autoplay="true" height="300"></VideoPlayer>
</StackLayout>

Record audio and save to file with Node and Angular2

I'm trying to record audio via the microphone in the browser and then save it to file server side using Node and a binary server. I am using this tutorial as a guide but am having trouble getting it to work with Angular2. Currently it appears to be saving some type of file to the server but it's not any type of playable audio. Here's all my code:
import { Component } from '#angular/core';
import { ContributorService } from './contributor.service';
import { CardDetailService } from './card-detail.service';
import { CardDetailComponent } from './card-detail.component';
import { Router, ActivatedRoute, Params } from '#angular/router';
import { Location } from '#angular/common';
declare let navigator: any;
declare let MediaRecorder: any;
declare let BinaryClient: any;
#Component({
selector: 'contributor',
template: `
<h1>Record Message</h1>
<button (click)='start()'>Start</button>
<button (click)='stop()'>Stop</button>
<button (click)='play()'>Play</button>
<a>{{hf}}</a>
<button class="go-back" (click)="goBack()">Done</button>
`
})
export class ContributorComponent {
private chunks: any[] = [];
private recorder;
private audio;
private counter = 1;
private Stream;
private recording = false;
constructor(
private contributorService: ContributorService,
private cardDetailService: CardDetailService,
private location: Location,
private route: ActivatedRoute,
private router: Router,
) {}
ngOnInit() {
let client = new BinaryClient('ws://localhost:9001');
client.on('open', function() {
let Stream = client.createStream();
});
let audio = {
tag: 'audio',
type: 'audio/ogg',
ext: '.ogg',
gUM: {audio: true}
};
let context = new AudioContext();
if (!navigator.getUserMedia) {
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
}
if (navigator.getUserMedia) {
navigator.getUserMedia({audio: true }, this.success, function(e) {
alert('Error capturing audio.');
});
} else {
alert('getUserMedia not supported in this browser.');
}
}
start() {
this.recording = true;
}
stop() {
this.recording = false;
this.Stream.end();
}
recorderProcess(e) {
let left = e.inputBuffer.getChannelData(0);
this.Stream.write(this.convertFloat32ToInt16(left));
}
success(e) {
let context = new AudioContext();
// the sample rate is in context.sampleRate
let audioInput = context.createMediaStreamSource(e);
let recorder = context.createScriptProcessor(2048, 1, 1);
this.recorder.onaudioprocess = function(e){
if (!this.recording) { return; };
console.log ('recording');
var left = e.inputBuffer.getChannelData(0);
this.Stream.write(this.convertoFloat32ToInt16(left));
};
audioInput.connect(this.recorder);
this.recorder.connect(context.destination);
}
convertFloat32ToInt16(buffer) {
let l = buffer.length;
let buf = new Int16Array(l);
while (l--) {
buf[l] = Math.min(1, buffer[l]) * 0x7FFF;
}
return buf.buffer;
}
goBack() {
this.location.back();
}
}
and here are the errors it throws:
contributor.component.ts:96Uncaught TypeError: Cannot read property 'recorder' of undefined(…)ContributorComponent.success # contributor.component.ts:96
core.umd.js:3004 EXCEPTION: Error in ./ContributorComponent class ContributorComponent - inline template:4:10 caused by: Cannot read property 'end' of undefinedErrorHandler.handleError

Resources