Related
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");
}
}
I'm trying to generate more than one thousand pdf files using surveyPDF.
The problem is that i can generate only 80 pdf files...
I'm passing an array with more than 1000 pdf to generate.
Code :
query.map(async items => {
const { generatePdf } = await import("~/lib/survey");
const filename = kebabCase(
`${campaign.title} - ${items.employee.fullName.toLowerCase()} -${moment().format("DD/MM/YYYY - HH:mm")} `
);
return generatePdf(campaign.template.body, items, filename, 210, 297);
});
The code which generate each pdfs :
import autoTable from "jspdf-autotable";
import { SurveyPDF, CommentBrick, CompositeBrick, PdfBrick, TextBrick } from "survey-pdf";
import { format } from "~/utils/date";
class AutoTableBrick extends PdfBrick {
constructor(question, controller, rect, options) {
super(question, controller, rect);
this.margins = {
top: controller.margins.top,
bottom: controller.margins.bot,
right: 30,
left: 30,
};
this.options = options;
}
renderInteractive() {
if (this.controller.doc.lastAutoTable && !this.options.isFirstQuestion) {
this.options.startY = this.yTop;
}
autoTable(this.controller.doc, {
head: [
[
{
content: this.question.title,
colSpan: 2,
styles: { fillColor: "#5b9bd5" },
},
],
],
margin: { ...this.margins },
styles: { fillColor: "#fff", lineWidth: 1, lineColor: "#5b9bd5", minCellWidth: 190 },
alternateRowStyles: { fillColor: "#bdd6ee" },
...this.options,
});
}
}
export async function generatePdf(json, data, filename, pdfWidth, pdfHeight) {
if (!json) {
return Promise.reject("Invalid json for pdf export");
}
for (const page of json.pages) {
page.readOnly = true;
}
const surveyPDF = new SurveyPDF(json, {
fontSize: 11,
format: [pdfWidth, pdfHeight],
commercial: true,
textFieldRenderAs: "multiLine",
});
surveyPDF.showQuestionNumbers = "off";
surveyPDF.storeOthersAsComment = false;
//TODO This does not work well with dynamic dropdown, bug declared
// surveyPDF.mode = "display";
surveyPDF.mergeData({ ...data, _: {} });
surveyPDF.onRenderQuestion.add(function(survey, options) {
const { bricks, question } = options;
if (question.getType() === "comment" && question.value && bricks.length > 0) {
for (const brick of bricks) {
if (brick.value) {
brick.value = question.value.replace(/\t/g, " ");
}
if (brick instanceof CompositeBrick) {
const { bricks } = brick;
for (const brick of bricks) {
if (brick instanceof CommentBrick) {
brick.value = question.value.replace(/\t/g, " ");
}
}
}
}
}
});
surveyPDF.onRenderQuestion.add(async function(survey, options) {
const {
point,
bricks,
question,
controller,
module: { SurveyHelper },
} = options;
if (question.getType() === "multipletext") {
const body = [];
let extraRows = 0;
let rows = question.getRows();
for (let i = 0; i < rows.length; i++) {
for (let j = 0; j < rows[i].length; j++) {
let { title, value, inputType } = rows[i][j];
if (inputType === "date") {
value = format(value);
}
if (typeof value === "string" && value.length > 0) {
const valueEstRows = value.match(/.{1,70}/g).length;
if (valueEstRows > 1) {
extraRows += valueEstRows;
}
}
body.push([title, value || "N/A"]);
}
}
//TODO Use SurveyHelper helperDoc do calculate the height of the auto table
const startY = point.yTop;
const height = 21.5 * (body.length + 1) + 8.5 * extraRows;
const isFirstQuestion = question.title === question.parent.questions[0].title;
options.bricks = [
new AutoTableBrick(question, controller, SurveyHelper.createRect(point, bricks[0].width, height), {
startY,
body,
isFirstQuestion,
}),
];
}
});
surveyPDF.onRenderQuestion.add(async function(survey, options) {
const {
point,
question,
controller,
module: { SurveyHelper },
} = options;
if (question.getType() === "text") {
//Draw question background
const { default: backImage } = await import("~/public/assets/images/block.png");
const backWidth = SurveyHelper.getPageAvailableWidth(controller);
const backHeight = SurveyHelper.pxToPt(100);
const imageBackBrick = SurveyHelper.createImageFlat(point, null, controller, backImage, backWidth, backHeight);
options.bricks = [imageBackBrick];
point.xLeft += controller.unitWidth;
point.yTop += controller.unitHeight;
const oldFontSize = controller.fontSize;
const titleBrick = await SurveyHelper.createTitleFlat(point, question, controller);
controller.fontSize = oldFontSize;
titleBrick.unfold()[0]["textColor"] = "#6a6772";
options.bricks.push(titleBrick);
//Draw text question text field border
let { default: textFieldImage } = await import("~/public/assets/images/input.png");
let textFieldPoint = SurveyHelper.createPoint(imageBackBrick);
textFieldPoint.xLeft += controller.unitWidth;
textFieldPoint.yTop -= controller.unitHeight * 3.3;
let textFieldWidth = imageBackBrick.width - controller.unitWidth * 2;
let textFieldHeight = controller.unitHeight * 2;
let imageTextFieldBrick = SurveyHelper.createImageFlat(
textFieldPoint,
null,
controller,
textFieldImage,
textFieldWidth,
textFieldHeight
);
options.bricks.push(imageTextFieldBrick);
textFieldPoint.xLeft += controller.unitWidth / 2;
textFieldPoint.yTop += controller.unitHeight / 2;
let textFieldValue = question.value || "";
if (textFieldValue.length > 90) {
textFieldValue = textFieldValue.substring(0, 95) + "...";
}
const textFieldBrick = await SurveyHelper.createBoldTextFlat(
textFieldPoint,
question,
controller,
textFieldValue
);
controller.fontSize = oldFontSize;
textFieldBrick.unfold()[0]["textColor"] = "#EFF8FF";
options.bricks.push(textFieldBrick);
}
});
surveyPDF.onRenderQuestion.add(async function(survey, options) {
const {
point,
question,
controller,
module: { SurveyHelper },
} = options;
if (question.getType() === "radiogroup" || question.getType() === "rating") {
options.bricks = [];
const oldFontSize = controller.fontSize;
const titleLocation = question.hasTitle ? question.getTitleLocation() : "hidden";
let fieldPoint;
if (["hidden", "matrix"].includes(titleLocation)) {
fieldPoint = SurveyHelper.clone(point);
} else {
const titleBrick = await SurveyHelper.createTitleFlat(point, question, controller);
titleBrick.xLeft += controller.unitWidth;
titleBrick.yTop += controller.unitHeight * 2;
controller.fontSize = oldFontSize;
titleBrick.unfold()[0]["textColor"] = "#6a6772";
options.bricks.push(titleBrick);
fieldPoint = SurveyHelper.createPoint(titleBrick);
fieldPoint.yTop += controller.unitHeight * 1.3;
}
//Draw checkbox question items field
const { default: itemEmptyImage } = await import("~/public/assets/images/unchecked.png");
const { default: itemFilledImage } = await import("~/public/assets/images/checked.png");
const itemSide = controller.unitWidth;
let imageItemBrick;
const choices = question.getType() === "rating" ? question.visibleRateValues : question.visibleChoices;
for (const choice of choices) {
const isItemSelected =
question.getType() === "rating" ? question.value === choice.value : choice === question.selectedItem;
imageItemBrick = SurveyHelper.createImageFlat(
fieldPoint,
null,
controller,
isItemSelected ? itemFilledImage : itemEmptyImage,
itemSide,
itemSide
);
options.bricks.push(imageItemBrick);
const textPoint = SurveyHelper.clone(fieldPoint);
textPoint.xLeft += itemSide + controller.unitWidth / 2;
textPoint.yTop += itemSide / 12;
const itemValue = choice.locText.renderedHtml;
const checkboxTextBrick = await SurveyHelper.createTextFlat(
textPoint,
question,
controller,
itemValue,
TextBrick
);
checkboxTextBrick.unfold()[0]["textColor"] = "#6a6772";
fieldPoint.yTop = imageItemBrick.yBot + SurveyHelper.GAP_BETWEEN_ROWS * controller.unitHeight;
options.bricks.push(checkboxTextBrick);
}
}
});
surveyPDF.onRenderFooter.add(function(survey, canvas) {
canvas.drawText({
text: canvas.pageNumber + "/" + canvas.countPages,
fontSize: 10,
horizontalAlign: "right",
margins: {
right: 12,
},
});
});
return await surveyPDF.raw(`./pdf/${filename}.pdf`);
}
The error :
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
I have already try to increase the node memory using $env:NODE_OPTIONS="--max-old-space-size=8192"
In the view whose code you see below I have a button that calls the searchView function. It displays an alert and in it we enter the number by which we are looking for an object and this object is returned by the getSong function. Up to this point everything is working fine. The problem I have encountered is that it now calls view and passes this found object, but the view does not refresh. I must have made some mistake that I can't locate or that I have forgotten. I would appreciate some help with this.
DetailView:
import CoreData
import SwiftUI
struct DetailView: View {
#State var song : Song
#State var isSelected: Bool
var body: some View {
VStack{
Text(song.content ?? "No content")
.padding()
Spacer()
}
.navigationBarTitle("\(song.number). \(song.title ?? "No title")", displayMode: .inline)
.toolbar {
ToolbarItemGroup(placement: .navigationBarTrailing) {
HStack{
Button(action: {
song.favorite.toggle()
isSelected=song.favorite
}) {
Image(systemName: "heart.fill")
.foregroundColor(isSelected ? .red : .blue)
}
Button(action: {
searchView()
}) {
Image(systemName: "magnifyingglass")
}
}
}
}
}
func searchView(){
let search = UIAlertController(title: "Go to the song", message: "Enter the number of the song you want to jump to.", preferredStyle: .alert)
search.addTextField {(number) in
number.placeholder = "Song number"
}
let go = UIAlertAction(title: "Go", style: .default) { (_) in
let songFound = PersistenceController.shared.getSong(number: (search.textFields![0].text)!)
DetailView(song: songFound!, isSelected: songFound!.favorite)
}
let cancel = UIAlertAction(title: "Cancel", style: .destructive) { (_) in
print("Cancel")
}
search.addAction(cancel)
search.addAction(go)
UIApplication.shared.windows.first?.rootViewController?.present(search, animated: true, completion: {
})
}
}
struct SongDetail_Previews: PreviewProvider {
static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
static var previews: some View {
let song = Song(context: moc)
song.number=0
song.title="Title"
song.content="Content"
song.author="Author"
song.favorite=false
return NavigationView {
DetailView(song: song, isSelected: song.favorite)
}
}
}
PersistenceController:
import CoreData
struct PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentContainer
init() {
container = NSPersistentContainer(name: "Model")
container.loadPersistentStores { (description, error) in
if let error = error {
fatalError("Error \(error.localizedDescription)")
}
}
}
func save(completion: #escaping (Error?) -> () = {_ in}) {
let context = container.viewContext
if context.hasChanges {
do {
try context.save()
completion(nil)
} catch {
completion(error)
}
}
}
func delete(_ object: NSManagedObject, completion: #escaping (Error?) -> () = {_ in}) {
let context = container.viewContext
context.delete(object)
save(completion: completion)
}
func getSong(number: String) -> Song? {
guard let songNumber = Int64(number) else { return nil }
let context = container.viewContext
let request = NSFetchRequest<Song>(entityName: "Song")
request.predicate = NSPredicate(format: "number == %ld", songNumber)
do {
return try context.fetch(request).first
} catch {
print(error)
return nil
}
}
}
I wanna cross domain tracking, 2 domains [google->Landing page(domain_1)->Website(Domain_2), I did follow some tutorials that set a variable on Google Tag Manager[Img bellow] to Google Analytics.
The issue is works just fine for links but my not to my Forms(Active Campaign Forms service).
The Decorate Form is set to true inside the variable but its not appending any code to the query when change domains.
My Code forms from embedded into my landpage from Optimaze Press
<style>
#_form_33_ { font-size:14px; line-height:1.6; font-family:arial, helvetica, sans-serif; margin:0; }
#_form_33_ * { outline:0; }
._form_hide { display:none; visibility:hidden; }
._form_show { display:block; visibility:visible; }
#_form_33_._form-top { top:0; }
#_form_33_._form-bottom { bottom:0; }
#_form_33_._form-left { left:0; }
#_form_33_._form-right { right:0; }
#_form_33_ input[type="text"],#_form_33_ input[type="date"],#_form_33_ textarea { padding:6px; height:auto; border:#979797 1px solid; border-radius:4px; color:#000 !important; font-size:14px; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; }
#_form_33_ textarea { resize:none; }
#_form_33_ ._submit { -webkit-appearance:none; cursor:pointer; font-family:arial, sans-serif; font-size:14px; text-align:center; background:#527a4b !important; border:0 !important; -moz-border-radius:4px !important; -webkit-border-radius:4px !important; border-radius:4px !important; color:#fff !important; padding:8px !important; }
#_form_33_ ._close-icon { cursor:pointer; background-image:url('https://d226aj4ao1t61q.cloudfront.net/esfkyjh1u_forms-close-dark.png'); background-repeat:no-repeat; background-size:14.2px 14.2px; position:absolute; display:block; top:11px; right:9px; overflow:hidden; width:16.2px; height:16.2px; }
#_form_33_ ._close-icon:before { position:relative; }
#_form_33_ ._form-body { margin-bottom:30px; }
#_form_33_ ._form-image-left { width:150px; float:left; }
#_form_33_ ._form-content-right { margin-left:164px; }
#_form_33_ ._form-branding { color:#fff; font-size:10px; clear:both; text-align:left; margin-top:30px; font-weight:100; }
#_form_33_ ._form-branding ._logo { display:block; width:130px; height:14px; margin-top:6px; background-image:url('https://d226aj4ao1t61q.cloudfront.net/hh9ujqgv5_aclogo_li.png'); background-size:130px auto; background-repeat:no-repeat; }
#_form_33_ ._form-label,#_form_33_ ._form_element ._form-label { font-weight:bold; margin-bottom:5px; display:block; }
#_form_33_._dark ._form-branding { color:#333; }
#_form_33_._dark ._form-branding ._logo { background-image:url('https://d226aj4ao1t61q.cloudfront.net/jftq2c8s_aclogo_dk.png'); }
#_form_33_ ._form_element { position:relative; margin-bottom:10px; font-size:0; max-width:100%; }
#_form_33_ ._form_element * { font-size:14px; }
#_form_33_ ._form_element._clear { clear:both; width:100%; float:none; }
#_form_33_ ._form_element._clear:after { clear:left; }
#_form_33_ ._form_element input[type="text"],#_form_33_ ._form_element input[type="date"],#_form_33_ ._form_element select,#_form_33_ ._form_element textarea:not(.g-recaptcha-response) { display:block; width:100%; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; }
#_form_33_ ._field-wrapper { position:relative; }
#_form_33_ ._inline-style { float:left; }
#_form_33_ ._inline-style input[type="text"] { width:150px; }
#_form_33_ ._inline-style:not(._clear) + ._inline-style:not(._clear) { margin-left:20px; }
#_form_33_ ._form_element img._form-image { max-width:100%; }
#_form_33_ ._clear-element { clear:left; }
#_form_33_ ._full_width { width:100%; }
#_form_33_ ._form_full_field { display:block; width:100%; margin-bottom:10px; }
#_form_33_ input[type="text"]._has_error,#_form_33_ textarea._has_error { border:#f37c7b 1px solid; }
#_form_33_ input[type="checkbox"]._has_error { outline:#f37c7b 1px solid; }
#_form_33_ ._error { display:block; position:absolute; font-size:14px; z-index:10000001; }
#_form_33_ ._error._above { padding-bottom:4px; bottom:39px; right:0; }
#_form_33_ ._error._below { padding-top:4px; top:100%; right:0; }
#_form_33_ ._error._above ._error-arrow { bottom:0; right:15px; border-left:5px solid transparent; border-right:5px solid transparent; border-top:5px solid #f37c7b; }
#_form_33_ ._error._below ._error-arrow { top:0; right:15px; border-left:5px solid transparent; border-right:5px solid transparent; border-bottom:5px solid #f37c7b; }
#_form_33_ ._error-inner { padding:8px 12px; background-color:#f37c7b; font-size:14px; font-family:arial, sans-serif; color:#fff; text-align:center; text-decoration:none; -webkit-border-radius:4px; -moz-border-radius:4px; border-radius:4px; }
#_form_33_ ._error-inner._form_error { margin-bottom:5px; text-align:left; }
#_form_33_ ._button-wrapper ._error-inner._form_error { position:static; }
#_form_33_ ._error-inner._no_arrow { margin-bottom:10px; }
#_form_33_ ._error-arrow { position:absolute; width:0; height:0; }
#_form_33_ ._error-html { margin-bottom:10px; }
.pika-single { z-index:10000001 !important; }
#_form_33_ input[type="text"].datetime_date { width:69%; display:inline; }
#_form_33_ select.datetime_time { width:29%; display:inline; height:32px; }
#media all and (min-width:320px) and (max-width:667px) { ::-webkit-scrollbar { display:none; }
#_form_33_ { margin:0; width:100%; min-width:100%; max-width:100%; box-sizing:border-box; }
#_form_33_ * { -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; font-size:1em; }
#_form_33_ ._form-content { margin:0; width:100%; }
#_form_33_ ._form-inner { display:block; min-width:100%; }
#_form_33_ ._form-title,#_form_33_ ._inline-style { margin-top:0; margin-right:0; margin-left:0; }
#_form_33_ ._form-title { font-size:1.2em; }
#_form_33_ ._form_element { margin:0 0 20px; padding:0; width:100%; }
#_form_33_ ._form-element,#_form_33_ ._inline-style,#_form_33_ input[type="text"],#_form_33_ label,#_form_33_ p,#_form_33_ textarea:not(.g-recaptcha-response) { float:none; display:block; width:100%; }
#_form_33_ ._row._checkbox-radio label { display:inline; }
#_form_33_ ._row,#_form_33_ p,#_form_33_ label { margin-bottom:0.7em; width:100%; }
#_form_33_ ._row input[type="checkbox"],#_form_33_ ._row input[type="radio"] { margin:0 !important; vertical-align:middle !important; }
#_form_33_ ._row input[type="checkbox"] + span label { display:inline; }
#_form_33_ ._row span label { margin:0 !important; width:initial !important; vertical-align:middle !important; }
#_form_33_ ._form-image { max-width:100%; height:auto !important; }
#_form_33_ input[type="text"] { padding-left:10px; padding-right:10px; font-size:16px; line-height:1.3em; -webkit-appearance:none; }
#_form_33_ input[type="radio"],#_form_33_ input[type="checkbox"] { display:inline-block; width:1.3em; height:1.3em; font-size:1em; margin:0 0.3em 0 0; vertical-align:baseline; }
#_form_33_ button[type="submit"] { padding:20px; font-size:1.5em; }
#_form_33_ ._inline-style { margin:20px 0 0 !important; }
}
#_form_33_ { position:relative; text-align:left; margin:25px auto 0; padding:20px; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; *zoom:1; background:transparent !important; border:0px solid #b0b0b0 !important; width:400px; -moz-border-radius:0px !important; -webkit-border-radius:0px !important; border-radius:0px !important; color:#fff !important; }
#_form_33_ ._form-title { font-size:22px; line-height:22px; font-weight:600; margin-bottom:0; }
#_form_33_:before,#_form_33_:after { content:" "; display:table; }
#_form_33_:after { clear:both; }
#_form_33_._inline-style { width:auto; display:inline-block; }
#_form_33_._inline-style input[type="text"],#_form_33_._inline-style input[type="date"] { padding:10px 12px; }
#_form_33_._inline-style button._inline-style { position:relative; top:27px; }
#_form_33_._inline-style p { margin:0; }
#_form_33_._inline-style ._button-wrapper { position:relative; margin:27px 12.5px 0 20px; }
#_form_33_ ._form-thank-you { position:relative; left:0; right:0; text-align:center; font-size:18px; }
#media all and (min-width:320px) and (max-width:667px) { #_form_33_._inline-form._inline-style ._inline-style._button-wrapper { margin-top:20px !important; margin-left:0 !important; }
}
</style>
<form method="POST" action="https://clickimoveis.activehosted.com/proc.php" id="_form_33_" class="_form _form_33 _inline-form _dark" novalidate>
<input type="hidden" name="u" value="33" />
<input type="hidden" name="f" value="33" />
<input type="hidden" name="s" />
<input type="hidden" name="c" value="0" />
<input type="hidden" name="m" value="0" />
<input type="hidden" name="act" value="sub" />
<input type="hidden" name="v" value="2" />
<div class="_form-content">
<div class="_form_element _x98738766 _full_width " >
<label class="_form-label">
Nome completo*
</label>
<div class="_field-wrapper">
<input type="text" name="fullname" placeholder="Digite seu nome" required/>
</div>
</div>
<div class="_form_element _x52697249 _full_width " >
<label class="_form-label">
E-mail*
</label>
<div class="_field-wrapper">
<input type="text" name="email" placeholder="Digite seu e-mail" required/>
</div>
</div>
<div class="_form_element _x23397806 _full_width " >
<label class="_form-label">
WhatsApp | Telefone*
</label>
<div class="_field-wrapper">
<input type="text" name="phone" placeholder="Digite seu telefone" required/>
</div>
</div>
<div class="_button-wrapper _full_width">
<button id="_form_33_submit" class="_submit" type="submit">
Quero olhar as OFERTAS EXCLUSIVAS !
</button>
</div>
<div class="_clear-element">
</div>
</div>
<div class="_form-thank-you" style="display:none;">
</div>
</form><script type="text/javascript">
window.cfields = [];
window._show_thank_you = function(id, message, trackcmp_url) {
var form = document.getElementById('_form_' + id + '_'), thank_you = form.querySelector('._form-thank-you');
form.querySelector('._form-content').style.display = 'none';
thank_you.innerHTML = message;
thank_you.style.display = 'block';
if (typeof(trackcmp_url) != 'undefined' && trackcmp_url) {
// Site tracking URL to use after inline form submission.
_load_script(trackcmp_url);
}
if (typeof window._form_callback !== 'undefined') window._form_callback(id);
};
window._show_error = function(id, message, html) {
var form = document.getElementById('_form_' + id + '_'), err = document.createElement('div'), button = form.querySelector('button'), old_error = form.querySelector('._form_error');
if (old_error) old_error.parentNode.removeChild(old_error);
err.innerHTML = message;
err.className = '_error-inner _form_error _no_arrow';
var wrapper = document.createElement('div');
wrapper.className = '_form-inner';
wrapper.appendChild(err);
button.parentNode.insertBefore(wrapper, button);
document.querySelector('[id^="_form"][id$="_submit"]').disabled = false;
if (html) {
var div = document.createElement('div');
div.className = '_error-html';
div.innerHTML = html;
err.appendChild(div);
}
};
window._load_script = function(url, callback) {
var head = document.querySelector('head'), script = document.createElement('script'), r = false;
script.type = 'text/javascript';
script.charset = 'utf-8';
script.src = url;
if (callback) {
script.onload = script.onreadystatechange = function() {
if (!r && (!this.readyState || this.readyState == 'complete')) {
r = true;
callback();
}
};
}
head.appendChild(script);
};
(function() {
if (window.location.search.search("excludeform") !== -1) return false;
var getCookie = function(name) {
var match = document.cookie.match(new RegExp('(^|; )' + name + '=([^;]+)'));
return match ? match[2] : null;
}
var setCookie = function(name, value) {
var now = new Date();
var time = now.getTime();
var expireTime = time + 1000 * 60 * 60 * 24 * 365;
now.setTime(expireTime);
document.cookie = name + '=' + value + '; expires=' + now + ';path=/';
}
var addEvent = function(element, event, func) {
if (element.addEventListener) {
element.addEventListener(event, func);
} else {
var oldFunc = element['on' + event];
element['on' + event] = function() {
oldFunc.apply(this, arguments);
func.apply(this, arguments);
};
}
}
var _removed = false;
var form_to_submit = document.getElementById('_form_33_');
var allInputs = form_to_submit.querySelectorAll('input, select, textarea'), tooltips = [], submitted = false;
var getUrlParam = function(name) {
var regexStr = '[\?&]' + name + '=([^&#]*)';
var results = new RegExp(regexStr, 'i').exec(window.location.href);
return results != undefined ? decodeURIComponent(results[1]) : false;
};
for (var i = 0; i < allInputs.length; i++) {
var regexStr = "field\\[(\\d+)\\]";
var results = new RegExp(regexStr).exec(allInputs[i].name);
if (results != undefined) {
allInputs[i].dataset.name = window.cfields[results[1]];
} else {
allInputs[i].dataset.name = allInputs[i].name;
}
var fieldVal = getUrlParam(allInputs[i].dataset.name);
if (fieldVal) {
if (allInputs[i].dataset.autofill === "false") {
continue;
}
if (allInputs[i].type == "radio" || allInputs[i].type == "checkbox") {
if (allInputs[i].value == fieldVal) {
allInputs[i].checked = true;
}
} else {
allInputs[i].value = fieldVal;
}
}
}
var remove_tooltips = function() {
for (var i = 0; i < tooltips.length; i++) {
tooltips[i].tip.parentNode.removeChild(tooltips[i].tip);
}
tooltips = [];
};
var remove_tooltip = function(elem) {
for (var i = 0; i < tooltips.length; i++) {
if (tooltips[i].elem === elem) {
tooltips[i].tip.parentNode.removeChild(tooltips[i].tip);
tooltips.splice(i, 1);
return;
}
}
};
var create_tooltip = function(elem, text) {
var tooltip = document.createElement('div'), arrow = document.createElement('div'), inner = document.createElement('div'), new_tooltip = {};
if (elem.type != 'radio' && elem.type != 'checkbox') {
tooltip.className = '_error';
arrow.className = '_error-arrow';
inner.className = '_error-inner';
inner.innerHTML = text;
tooltip.appendChild(arrow);
tooltip.appendChild(inner);
elem.parentNode.appendChild(tooltip);
} else {
tooltip.className = '_error-inner _no_arrow';
tooltip.innerHTML = text;
elem.parentNode.insertBefore(tooltip, elem);
new_tooltip.no_arrow = true;
}
new_tooltip.tip = tooltip;
new_tooltip.elem = elem;
tooltips.push(new_tooltip);
return new_tooltip;
};
var resize_tooltip = function(tooltip) {
var rect = tooltip.elem.getBoundingClientRect();
var doc = document.documentElement, scrollPosition = rect.top - ((window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0));
if (scrollPosition < 40) {
tooltip.tip.className = tooltip.tip.className.replace(/ ?(_above|_below) ?/g, '') + ' _below';
} else {
tooltip.tip.className = tooltip.tip.className.replace(/ ?(_above|_below) ?/g, '') + ' _above';
}
};
var resize_tooltips = function() {
if (_removed) return;
for (var i = 0; i < tooltips.length; i++) {
if (!tooltips[i].no_arrow) resize_tooltip(tooltips[i]);
}
};
var validate_field = function(elem, remove) {
var tooltip = null, value = elem.value, no_error = true;
remove ? remove_tooltip(elem) : false;
if (elem.type != 'checkbox') elem.className = elem.className.replace(/ ?_has_error ?/g, '');
if (elem.getAttribute('required') !== null) {
if (elem.type == 'radio' || (elem.type == 'checkbox' && /any/.test(elem.className))) {
var elems = form_to_submit.elements[elem.name];
if (!(elems instanceof NodeList || elems instanceof HTMLCollection) || elems.length <= 1) {
no_error = elem.checked;
}
else {
no_error = false;
for (var i = 0; i < elems.length; i++) {
if (elems[i].checked) no_error = true;
}
}
if (!no_error) {
tooltip = create_tooltip(elem, "Por favor, selecione uma opção.");
}
} else if (elem.type =='checkbox') {
var elems = form_to_submit.elements[elem.name], found = false, err = [];
no_error = true;
for (var i = 0; i < elems.length; i++) {
if (elems[i].getAttribute('required') === null) continue;
if (!found && elems[i] !== elem) return true;
found = true;
elems[i].className = elems[i].className.replace(/ ?_has_error ?/g, '');
if (!elems[i].checked) {
no_error = false;
elems[i].className = elems[i].className + ' _has_error';
err.push("Marcar %s é necessário".replace("%s", elems[i].value));
}
}
if (!no_error) {
tooltip = create_tooltip(elem, err.join('<br/>'));
}
} else if (elem.tagName == 'SELECT') {
var selected = true;
if (elem.multiple) {
selected = false;
for (var i = 0; i < elem.options.length; i++) {
if (elem.options[i].selected) {
selected = true;
break;
}
}
} else {
for (var i = 0; i < elem.options.length; i++) {
if (elem.options[i].selected && !elem.options[i].value) {
selected = false;
}
}
}
if (!selected) {
elem.className = elem.className + ' _has_error';
no_error = false;
tooltip = create_tooltip(elem, "Por favor, selecione uma opção.");
}
} else if (value === undefined || value === null || value === '') {
elem.className = elem.className + ' _has_error';
no_error = false;
tooltip = create_tooltip(elem, "Este campo é necessário.");
}
}
if (no_error && elem.name == 'email') {
if (!value.match(/^[\+_a-z0-9-'&=]+(\.[\+_a-z0-9-']+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/i)) {
elem.className = elem.className + ' _has_error';
no_error = false;
tooltip = create_tooltip(elem, "Digite um e-mail válido");
}
}
if (no_error && /date_field/.test(elem.className)) {
if (!value.match(/^\d\d\d\d-\d\d-\d\d$/)) {
elem.className = elem.className + ' _has_error';
no_error = false;
tooltip = create_tooltip(elem, "Digite uma data válida.");
}
}
tooltip ? resize_tooltip(tooltip) : false;
return no_error;
};
var needs_validate = function(el) {
if(el.getAttribute('required') !== null){
return true
}
if(el.name === 'email' && el.value !== ""){
return true
}
return false
};
var validate_form = function(e) {
var err = form_to_submit.querySelector('._form_error'), no_error = true;
if (!submitted) {
submitted = true;
for (var i = 0, len = allInputs.length; i < len; i++) {
var input = allInputs[i];
if (needs_validate(input)) {
if (input.type == 'text') {
addEvent(input, 'blur', function() {
this.value = this.value.trim();
validate_field(this, true);
});
addEvent(input, 'input', function() {
validate_field(this, true);
});
} else if (input.type == 'radio' || input.type == 'checkbox') {
(function(el) {
var radios = form_to_submit.elements[el.name];
for (var i = 0; i < radios.length; i++) {
addEvent(radios[i], 'click', function() {
validate_field(el, true);
});
}
})(input);
} else if (input.tagName == 'SELECT') {
addEvent(input, 'change', function() {
validate_field(this, true);
});
} else if (input.type == 'textarea'){
addEvent(input, 'input', function() {
validate_field(this, true);
});
}
}
}
}
remove_tooltips();
for (var i = 0, len = allInputs.length; i < len; i++) {
var elem = allInputs[i];
if (needs_validate(elem)) {
if (elem.tagName.toLowerCase() !== "select") {
elem.value = elem.value.trim();
}
validate_field(elem) ? true : no_error = false;
}
}
if (!no_error && e) {
e.preventDefault();
}
resize_tooltips();
return no_error;
};
addEvent(window, 'resize', resize_tooltips);
addEvent(window, 'scroll', resize_tooltips);
window._old_serialize = null;
if (typeof serialize !== 'undefined') window._old_serialize = window.serialize;
_load_script("//d3rxaij56vjege.cloudfront.net/form-serialize/0.3/serialize.min.js", function() {
window._form_serialize = window.serialize;
if (window._old_serialize) window.serialize = window._old_serialize;
});
var form_submit = function(e) {
e.preventDefault();
if (validate_form()) {
// use this trick to get the submit button & disable it using plain javascript
document.querySelector('#_form_33_submit').disabled = true;
var serialized = _form_serialize(document.getElementById('_form_33_'));
var err = form_to_submit.querySelector('._form_error');
err ? err.parentNode.removeChild(err) : false;
_load_script('https://clickimoveis.activehosted.com/proc.php?' + serialized + '&jsonp=true');
}
return false;
};
addEvent(form_to_submit, 'submit', form_submit);
})();
</script>
I'm fairly new to Phaser 3, and I just started dipping my feet in scenes. The problem here is that the game window won't display, and I can't figure out why.
Leaving my entire code here just in case there's a problem somewhere else. Sorry about the wall of text. Any help would be appreciated, even if it isn't a direct fix.
class scene1 extends Phaser.Scene{
constructor() {
super({ key: 'scene1' });
this.pause = false;
this.q = null;
this.player = null;
this.roundTxt = null;
this.handUp = true;
this.round = 1;
this.flash = true;
this.platforms = null;
this.hudStar = null;
this.starCountTxt = null;
this.bombs = null;
this.left = false;
this.lives = 3;
this.hudLives = null;
this.starCount = 0;
this.gameOver = false;
this.bCol = null;
this.pCol = null;
this.invincible = false;
this.invFlash = null;
this.tw = null;
this.slam = false;
this.bullets = null;
this.keySpace = null;
this.shot = false;
this.game = new Phaser.Game(config);
this.direction = 1;
this.bombs = null;
this.bullets = new Bullets(this);
this.cursors = this.input.keyboard.createCursorKeys();
//initialize stars
this.stars = this.physics.add.group({
key: 'star',
repeat: 9,
setXY: { x: 12, y: 0, stepX: 80 },
});
// Define spacebar
this.keySpace = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
this.window.bullets = this.bullets;
}
addBomb() {
var x = Phaser.Math.Between(0, 800);
var y = Phaser.Math.Between(30, 450);
this.bombs.children.iterate(function (child) {
x = Phaser.Math.Between(0, 800);
y = Phaser.Math.Between(30, 450);
if (child.active) {
child.enableBody(true, child.x, child.y, true, true);
} else {
child.enableBody(true, x, y, true, true);
}
child.setVelocityX(50 * Phaser.Math.Between(10, 2));
child.setVelocityY(50 * Phaser.Math.Between(10, 2));
});
x = Phaser.Math.Between(0, 800);
y = Phaser.Math.Between(30, 450);
scene1.bomb = this.bombs.create(x, y, 'bomb').setBounce(1).setCollideWorldBounds(true).setVelocityX(50 * Phaser.Math.Between(10, 2)).setVelocityY(50 * Phaser.Math.Between(10, 2));
}
preload () {
this.load.image('sky', 'assets/tut/sky.png');
this.load.image('ground', 'assets/tut/platform.png');
this.load.image('star', 'assets/tut/star.png');
this.load.image('bomb', 'assets/tut/bomb.png');
this.load.spritesheet('dude', 'assets/tut/dude.png', { frameWidth: 32, frameHeight: 48 });
this.load.image('life', 'assets/tut/dudeLife.png');
this.load.image('bullet', 'assets/bullet7.png');
}
//end preload
//create
create () {
//add sky background
this.add.image(400, 300, 'sky');
//add player
this.player = this.physics.add.sprite(100, 450, 'dude');
//player bounces
//set world bounds
this.player.setCollideWorldBounds(true);
//animations
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 3 }),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'turn',
frames: [ { key: 'dude', frame: 4 } ],
frameRate: 20
});
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('dude', { start: 5, end: 8 }),
frameRate: 10,
repeat: -1
});
//create group 'platforms'
this.platforms = this.physics.add.staticGroup();
//add ground platforms
this.platforms.create(400, 568, 'ground').setScale(2).refreshBody();
//add sky platforms
this.platforms.create(600, 400, 'ground');
this.platforms.create(50, 250, 'ground');
this.platforms.create(750, 220, 'ground');
//cursors
//add stars
this.stars.children.iterate(function(child) {
child.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));
child.setCollideWorldBounds(true);
});
//set bombs
this.bombs = this.physics.add.group();
this.addBomb();
//collision
this.pCol = this.physics.add.collider(this.player, this.platforms);
this.physics.add.collider(this.stars, this.platforms);
this.physics.add.collider(this.stars, this.bombs);
this.physics.add.collider(this.bombs, this.platforms);
this.bCol = this.physics.add.collider(this.player, this.bombs, hitBomb, null, this);
this.physics.add.overlap(this.player, this.stars, collectStar, null, this);
function collectStar(player, star) {
scene1.star.disableBody(true, true);
scene1.starCount++;
if (scene1.stars.countActive(true) === 0) {
scene1.flash = true;
scene1.round++;
scene1.bCol.active = false;
scene1.stars.children.iterate(function (child) {
child.enableBody(true, child.x, 0, true, true);
});
scene1.addBomb();
}
}
//function for player/bomb col
function hitBomb(player, bomb) {
if (scene1.slam) {
bomb.disableBody(true, true);
player.setVelocityY(-300);
} else {
if (scene1.invincible == false) {
scene1.bCol.active = false;
bomb.disableBody(true, true);
scene1.invincible = true;
scene1.lives--;
if (scene1.lives == 2) {
scene1.hudLives.three.destroy();
} else if (scene1.lives == 1) {
scene1.hudLives.two.destroy();
} else {
scene1.gameOver = true;
scene1.hudLives.one.destroy();
}
player.setAlpha(0);
scene1.add.tween({
targets: player,
alpha: 1,
duration: 100,
ease: 'Linear',
repeat: 5,
onComplete: function() {
scene1.invincible = false;
scene1.bCol.active = true;
}
});
}
}
}
// bullets = new Bullet(this);
this.physics.add.overlap(scene1.bullets, scene1.bombs, scene1.shootBomb, null, this );
//define pause button
this.q = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q);
/////////////////////////
/////////////////////////
/////////////////////////
//////////HUD////////////
/////////////////////////
/////////////////////////
scene1.starCountTxt = this.add.text(35, 10, scene1.starCount, { font: ' 20px sans-serif', fill: '#ffffff' });
//star hud img
scene1.hudStar = this.add.image(20, 20, 'star');
//adds lives on hud
scene1.hudLives = {
one: this.add.image(20, 90, 'life'),
two: this.add.image(30, 90, 'life'),
three: this.add.image(40, 90, 'life')
};
scene1.roundTxt = {
label: this.add.image(20, 55, 'bomb'),
num: this.add.text(35, 43, scene1.round, { font: '20px sans-serif', fill: '#ffffff'})
};
//end of create
} //this curly bracket
//end of create
update () {
scene1.roundTxt.num.setText(scene1.round);
if (scene1.bombs.countActive(true) == 0) {
scene1.addBomb();
scene1.flash = true;
scene1.round++;
}
if (scene1.flash) {
scene1.flash = false;
scene1.bCol.active = false;
scene1.bombs.children.iterate(function(child) {
child.setTint(0x00ff00);
setTimeout(function(){
child.setTint(0xffffff);
scene1.bCol.active = true;
}, 1000);
});
}
if (scene1.cursors.left.isDown) {
scene1.direction = -1;
}
else if (scene1.cursors.right.isDown) {
scene1.direction = 1;
}
scene1.starCountTxt.setText(scene1.starCount);
if (scene1.gameOver) {
this.physics.pause();
scene1.player.setTint(0xff0000);
scene1.player.anims.play('turn');
var die = this.add.tween({
targets: scene1.player,
scaleX: '-=0.5',
scaleY: '-=0.5',
angle: '-=360',
repeat: 1,
duration: 500,
onComplete: function() {
die.delete();
}
});
}
if (scene1.cursors.left.isDown) {
scene1.player.setVelocityX(-300);
scene1.left = true;
scene1.player.anims.play('left', true);
}
else if (scene1.cursors.right.isDown) {
scene1.player.setVelocityX(300);
scene1.left = false;
scene1.player.anims.play('right', true);
}
else {
scene1.player.setVelocityX(0);
scene1.player.anims.play('turn');
}
if (scene1.cursors.up.isDown && scene1.player.body.touching.down) {
scene1.player.setVelocityY(-400);
}
if (scene1.cursors.down.isDown && scene1.player.body.touching.down && scene1.player.y < 500) {
if (!scene1.slam) {
scene1.player.y += 5;
scene1.slam = true;
}
} else if (scene1.player.body.touching.down == false && scene1.cursors.down.isDown) {
if (!scene1.slam) {
scene1.player.setVelocityY(1000);
scene1.slam = true;
}
} else if (scene1.cursors.down.isDown == false) {
scene1.slam = false;
}
if (scene1.player.body.velocity.y < 0) {
scene1.pCol.active = false;
} else {
scene1.pCol.active = true;
}
if (scene1.keySpace.isDown) {
if (!scene1.shot && scene1.handUp) {
this.bullets.fireBullet(scene1.player.x, scene1.player.y+5);
console.log(this.bullets);
scene1.shot = true;
this.tweens.addCounter({
from: 50,
to: 200,
duration: 200,
onUpdate: function (tween)
{
var value = Math.floor(tween.getValue());
scene1.player.setTint(Phaser.Display.Color.GetColor(value, value, value));
}
});
this.time.delayedCall(300, function(){
scene1.shot = false;
scene1.player.setTint(0xffffff);
}, [], this);
}
scene1.handUp = false;
}
if (scene1.keySpace.isUp) {
scene1.handUp = true;
}
if (Phaser.Input.Keyboard.JustDown(scene1.q)) {
if (scene1.pause) {
this.physics.resume();
scene1.pause = false;
} else {
this.physics.pause();
scene1.pause = true;
}
}
//end of update
} //this curly bracket
//end of update
shootBomb(bullets, bombs) {
bombs.disableBody(true, true);
bullets.disableBody(true, true);
}
}
class Bullet extends Phaser.Physics.Arcade.Sprite {
constructor(scene1, x, y) {
super(scene1, x, y, 'bullet');
}
fire(x, y) {
this.body.reset(x, y);
this.setVelocityX(1000 * scene1.direction);
this.enableBody();
this.body.setAllowGravity(false);
this.setActive(true);
this.setVisible(true);
}
preUpdate(time, delta) {
super.preUpdate(time, delta);
// Reset the bullets when it reaches end of screen
if (this.x > 2600) {
this.setActive(false);
this.setVisible(false);
}
}
}
class Bullets extends Phaser.Physics.Arcade.Group {
constructor(scene) {
super(scene.physics.world, scene);
this.createMultiple({
frameQuantity: 20,
key: 'bullet',
active: false,
visible: false,
classType: Bullet
});
}
fireBullet(x, y) {
let bullet = this.getFirstDead(false);
if (bullet) {
bullet.fire(x, y);
}
}
}
var config = {
type: Phaser.GAME,
width: 800,
height: 600,
parent: 'gameDiv',
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: [scene1],
debug: true
};
When configuring the game you're asking it to load inside of an element with an id of gameDiv, by using parent on the game configuration.
var config = {
type: Phaser.GAME,
width: 800,
height: 600,
parent: 'gameDiv',
// ...
};
If the game isn't displaying at all, that suggests that it may not be able to find an element with the id of gameDiv.
Can you verify that an element (typically a div, so <div id="gameDiv"></div>) exists in your HTML file?