Related
I'm using Matter.js for some graphics and want this rectangle
let title = Bodies.rectangle(w / 2.4, height / 1.8, 300, 100, {
isStatic: true,
})
to get isStatic: false and fall when it's hit by some circles that are raining down on it. I've done some extensive Googling, but haven't really found anything else but this:
Events.on(engine, 'collisionStart', function (event) {
event.pairs.forEach(function (obj) {
console.log(
'BodyA is static: ' + obj.bodyA.isStatic + '. BodyB is static: ' + obj.bodyB.isStatic
)
})
})
This gives me all the collisions happening, but I haven't figured out how to set isStatic: false when something hits. Appreciate your help!
You can call Matter.Body.setStatic(body, false) on the body in question to make it active.
Here's an example:
const engine = Matter.Engine.create();
const render = Matter.Render.create({
element: document.body,
engine,
options: {width: 400, height: 400, wireframes: false},
});
const fallingBody = Matter.Bodies.rectangle(
200, 0, 20, 20, {
frictionAir: 0.1,
density: 0.8,
render: {fillStyle: "red"},
},
);
const wall = Matter.Bodies.rectangle(
200, 150, 400, 20, {
frictionAir: 0.05,
isStatic: true,
render: {fillStyle: "green"}
},
);
Matter.Composite.add(engine.world, [fallingBody, wall]);
Matter.Events.on(engine, "collisionStart", event => {
if (
wall.isStatic &&
event.pairs.some(e => Object.values(e).includes(wall))
) {
Matter.Body.setStatic(wall, false);
}
});
Matter.Render.run(render);
Matter.Runner.run(Matter.Runner.create(), engine);
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
I have particles that I emit when clicking and moving my mouse over a certain object. However I noticed that while the particles start out as little, they become more and more the more often I click and move my mouse,until the stream of particles is far too dense.
This only seems to happen when I click down multiple times (thus triggering the pointerdown event multiple times), not when I click once and keep moving.
How can I stop this?
function pet(start, scene, pointer = null)
{
if(start){
scene.input.on('pointermove', function(){
if (scene.input.activePointer.isDown && gameState.chara.getBounds().contains(scene.input.activePointer.x, scene.input.activePointer.y)){
gameState.sparkle.emitParticle(1,scene.input.activePointer.x, scene.input.activePointer.y); // !!!! Here is where I emit my particles
}
});
} else {
gameState.sparkle.stop(); // !!!! Here I stop my particles
}
}
const gameState = {
gameWidth: 800,
gameHeight: 800,
menu: {},
textStyle: {
fontFamily: "'Comic Sans MS'",
fill: "#fff",
align: "center",
boundsAlignH: "left",
boundsAlignV: "top"
},
};
function preload()
{
this.load.baseURL = 'assets/';
// Chara
this.load.atlas('chara', 'chara.png', 'chara.json');
// Particle
this.load.image('sparkle', 'sparkle.png'); // Here I load my particle image
}
function create()
{
// Scene
let scene = this;
// Chara
this.anims.create({
key: "wag",
frameRate: 12,
frames: this.anims.generateFrameNames("chara", {
prefix: 'idle_000',
start: 0,
end: 5}),
repeat: 0,
});
this.anims.create({
key: "happy",
frameRate: 12,
frames: this.anims.generateFrameNames("chara", {
prefix: 'happy_000',
start: 0,
end: 5}),
repeat: -1
});
gameState.chara = this.add.sprite(400, 400, "chara", "idle_0000");
gameState.chara.setInteractive({cursor: "pointer"});
// !!!! Here I set up my Particle Emitter !!!!
gameState.sparkle = this.add.particles('sparkle').createEmitter({
x: gameState.height/2,
y: gameState.width/2,
scale: { min: 0.1, max: 0.5 },
speed: { min: -100, max: 100 },
quantity: 0.1,
frequency: 1,
lifespan: 1000,
gravityY: 100,
on: false,
});
gameState.chara.on('pointerdown', function(){ pet(true, scene) });
gameState.chara.on('pointerout', function(){ pet(false, scene, 'default') });
gameState.chara.on('pointerup', function(){ pet(false, scene, 'pointer') });
}
function update()
{
}
// Configs
var config = {
backgroundColor: "0xf0f0f0",
scale: {
width: gameState.gameWidth,
height: gameState.gameHeight,
autoCenter: Phaser.Scale.CENTER_BOTH
},
scene: {
preload, create, update
}
};
var game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
The problem is, that you are adding a new scene.input.on('pointermove',...) event-handler in the pet function, on each click.
I would only change the code abit (look below), this should prevent generating too many particles and too many event-handlers (too many event-handlers could harm performance, so be careful, when adding them).
Here is how I would modify the Code:
(I stripped out and added some stuff to make the demo, easier to understand and shorter. And also that the snippet can be executed, without errors/warnings)
The main changes are marked and explained in the code, with comments
function pet(start, scene, pointer = null)
{
if(start){
// Update: remove Event listener add click state
gameState.mouseDown = true
} else {
// Update: add click state
gameState.mouseDown = false;
gameState.sparkle.stop();
}
}
const gameState = {
gameWidth: 400,
gameHeight: 200,
// Update: add click state
mouseDown: false
};
function create()
{
// Scene
let scene = this;
// Just could for Demo START
var graphics = this.add.graphics();
graphics.fillStyle(0xff0000);
graphics.fillRect(2,2,10,10);
graphics.generateTexture('particle', 20, 20);
graphics.clear();
graphics.fillStyle(0xffffff);
graphics.fillRect(0,0,40,40);
graphics.generateTexture('player', 40, 40);
graphics.destroy();
// Just Code for Demo END
gameState.chara = this.add.sprite(200, 100, "player");
gameState.chara.setInteractive({cursor: "pointer"});
gameState.sparkle = this.add.particles('particle').createEmitter({
scale: { min: 0.1, max: 0.5 },
speed: { min: -100, max: 100 },
quantity: 0.1,
frequency: 1,
lifespan: 1000,
gravityY: 100,
on: false,
});
gameState.chara.on('pointerdown', function(){ pet(true, scene) });
gameState.chara.on('pointerout', function(){ pet(false, scene, 'default') });
gameState.chara.on('pointerup', function(){ pet(false, scene, 'pointer') });
// Update: add new single Event Listener
gameState.chara.on('pointermove', function(pointer){
if(gameState.mouseDown){
gameState.sparkle.emitParticle(1,pointer.x, pointer.y);
}
});
}
// Configs
var config = {
width: gameState.gameWidth,
height: gameState.gameHeight,
scene: { create }
};
var game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
html2pdf is printing a pdf but the write is choppy between pages how to solve?
this my code javascript if you need to html i can comment it,
any one have an idea ? please help me!
<script>
window.onload = function () {
document.getElementById("download")
.addEventListener("click", () => {
const invoice = this.document.getElementById("invoice");
console.log(invoice);
console.log(window);
var opt = {
margin: 1,
filename: 'myfile.pdf',
image: { type: 'png', quality: 0.98 },
html2canvas: { scale: 2 },
jsPDF: { unit: 'pt', format: 'a4', orientation: 'landscape'}
// p\init : pt unit: 'in', format: 'letter', orientation: 'landscape'
};
html2pdf().from(invoice).set(opt).save();
})
}
</script>
that is screenshot from pdf for more clarification
https://i.stack.imgur.com/eSdId.png
i'm using just javascript in scout framework, to get pdf from dinamic html site, my index.js:
function buttonHtml2Pdf() {
button = '<input type= "button" value="Stampa html2Pdf" id="html2pdf" class="menu-item menu-button unfocusable menubar-item left-of-button";" />';
$(button).insertBefore($("div[data-classid='DettaglioArticoliButton_org.eclipse.scout.apps.crm.client.crm.ContoClienteForm_InnerFormField_org.eclipse.scout.apps.crm.client.crm.MainClienteForm']"));
$("#html2pdf").click("click", function() {
var $elementoDaConvertire = $("div[data-classid='DettaglioOrdineBox_org.eclipse.scout.apps.crm.client.crm.ContoClienteForm_InnerFormField_org.eclipse.scout.apps.crm.client.crm.MainClienteForm']").html();
var elemClass = $("div[data-classid='org.eclipse.scout.apps.crm.client.crm.ContoClienteForm$MainBox$DettaglioArticoliBox$DettArticoliField$Table_DettArticoliField_org.eclipse.scout.apps.crm.client.crm.ContoClienteForm_InnerFormField_org.eclipse.scout.apps.crm.client.crm.MainClienteForm']").html();
var opt = {
margin: 1,
filename: 'Dettaglio_Ordini.pdf',
image: {
type: 'jpeg',
quality: 0.98
},
html2canvas: {
scale: 2,
letterRendering: true,
imageTimeout: 0,
width: 850,
height: 1200,
scrollX: 0,
scrollY: 20
},
jsPDF: {
unit: 'in',
format: 'a4',
orientation: 'portrait',
putOnlyUsedFonts: true,
floatPrecision: 'smart'
}
};
var worker = html2pdf();
worker = html2pdf().set(opt).from($elementoDaConvertire).toContainer().then(() => {
const doc = $('.html2pdf__container');
doc.find('.menubar').remove();
doc.find('.unfocusable').remove();
//doc.find($("div[data-classid='DeliveryNameOrderField_org.eclipse.scout.apps.crm.client.crm.ContoClienteForm_InnerFormField_org.eclipse.scout.apps.crm.client.crm.MainClienteForm']").html()).remove();
doc.find('.field has-inner-alignment halign-left valign-top white-space-nowrap').hide();
})
.toPdf().get('pdf')
.then(function(pdf) {
pdf.addPage();
}).set(opt).from(elemClass).toContainer().toCanvas().then(() => {
var doc2 = $('.html2pdf__container');
doc2.find('table-header-item-text').remove();
}).toPdf().save().catch(function(error) {});
});
}
As you see i must to take de "data-classid" generated from scout framework, i can't modify the id and also taht doesn't listen my $(".class") call with jquery. what can i do to hide some elements?
doc.find().hide()/remove() just work for 2 class: menubar and unfocusable, if i add other class, that is not taken.
If this library is not the solution what else can i do?
I'm working on a game in Phaser 3 and I need to use some sort of scrollable panel, so I chose to use Rex UI (if you know any alternatives, please tell me. At first I wanted to use phaser-list-view from npm but it's only in phaser 2). It seems like these plugins do not have much documentation. The docs are on this site: Notes of Phaser 3.
So I have my game configuration and I'm loading like this (oversimplified):
import UIPlugin from '../plugins/ui-plugin.js';
const config = {
// ...
plugins: {
scene: [{
key: 'rexUI',
plugin: UIPlugin,
mapping: 'rexUI'
}]
}
// ...
};
const game = new Phaser.Game(config);
And in a scene I try to use it:
export default class MyScene extends Phaser.Scene {
create() {
this.rexUI.add.scrollablePanel({
x: 0, y: 0,
width: innerWidth,
height: innerHeight/2,
scrollMode: 'horizontal',
panel: {
child: this.add.container().setSize(2 * innerWidth, innerHeight/2)
.add(this.itemImage(1))
.add(this.itemImage(2))
// ...
// (I'm actually using for-loop and save this container in a
// separate variable, but I'm over simplifying this snippet)
mask: false
},
slider: {
track: this.add.graphics({x: 0, y: innerHeight/2 + 10})
.fillRect(0, 0, innerWidth, 30).fillStyle(SOME_LIGHT_COLOR)
.setInteractive(
new Phaser.Geom.Rectangle(0, 0, innerWidth, 30),
Phaser.Geom.Rectangle.Contains
),
thumb: this.add.graphics({x: 0, y: innerWidth/2 + 10})
.fillRect(0, 0, 50, 30).fillStyle(SOME_DARK_COLOR)
.setInteractive(
new Phaser.Geom.Rectangle(0, 0, 50, 30),
Phaser.Geom.Rectangle.Contains
)
}
}).layout()
}
itemImage(n) {
return this.add.image((innerHeight/2 + 30) * (n-1), 0, 'item' + n)
.setDisplaySize(innerHeight/2, innerHeight/2)
}
}
There are many problems. Firstly with the above code I get the error:
Uncaught TypeError: this.child.getAllChildren is not a function
at e.Xo [as resetChildPosition] (<anonymous>:1:205731)
at e.layout (<anonymous>:1:206243)
at e.layout (<anonymous>:1:126859)
at e.layout (<anonymous>:1:126859)
at e.value (<anonymous>:1:172299)
at MyScene.create (MyScene.js:117)
at initialize.create (phaser.min.js:1)
at initialize.loadComplete (phaser.min.js:1)
at initialize.h.emit (phaser.min.js:1)
at initialize.loadComplete (phaser.min.js:1)
The error goes away if I just remove .layout(). But however, the thumb on the scroller is not anywhere in the scene and I can't even scroll the container.
The docs don't say what exacly should go in panel.child, scrolller.track and scroller.thumb
Can someone help me out of this?
try this, just call createTable():
me.createTable({
x: 390,
y: 410,
width: 350,
height: 220,
rank: [{"score":1520,"userID":1,"userName":"Augustus Nico"},{"score":360,"userID":"_2hzxb91byxw","userName":"lipão"},{"score":250,"userID":3,"userName":"Sarão"},{"score":200,"userID":5,"userName":"Bruna Santini"},{"score":160,"userID":4,"userName":"Paulo Junior"},{"score":100,"userID":2,"userName":"Vilasboas"}]
});
const COLOR_PRIMARY = 0x4e342e;
const COLOR_LIGHT = 0x7b5e57;
const COLOR_DARK = 0x260e04;
const COLOR_WHITE = 0xffffff;
export const createTable = ({ x, y, width, height, rank }) => {
var scrollablePanel = this.rexUI.add
.scrollablePanel({
x: x,
y: y,
width: width,
height: height,
scrollMode: 0,
background: this.rexUI.add.roundRectangle(0, 0, 2, 2, 10, COLOR_WHITE),
panel: {
child: createGrid(this, rank),
mask: {
mask: true,
padding: 1
}
},
slider: {
track: this.rexUI.add.roundRectangle(0, 0, 20, 10, 10, COLOR_LIGHT),
thumb: this.rexUI.add.roundRectangle(0, 0, 0, 0, 13, COLOR_DARK)
},
space: {
left: 10,
right: 10,
top: 10,
bottom: 10,
panel: 10,
header: 10,
footer: 10
}
})
.layout();
};
const createGrid = (scene, rank) => {
var sizer = scene.rexUI.add.gridSizer({
column: 2,
row: rank.length,
columnProportions: 1
});
rank.forEach((player, index) => {
sizer.add(
scene.createItem(scene, 0, index, player.userName), // child
0, // columnIndex
index, // rowIndex
"center", // align
0, // paddingConfig
true // expand
);
sizer.add(
scene.createItem(scene, 1, index, player.score), // child
1, // columnIndex
index, // rowIndex
"center", // align
0, // paddingConfig
true // expand
);
});
return sizer;
};
const createItem = (scene, colIdx, rowIdx, text) => {
var item = scene.rexUI.add
.label({
background: scene.rexUI.add
.roundRectangle(0, 0, 0, 0, 0, undefined)
.setStrokeStyle(2, COLOR_DARK, 1),
text: scene.add.text(0, 0, text, {
fontSize: 18,
fill: "#000"
}),
space: {
left: 10,
right: 10,
top: 10,
bottom: 10,
icon: 10
}
})
.setDepth(3);
var press = scene.rexUI.add.press(item).on("pressstart", function() {
console.log(`press ${text}`);
});
return item;
};