Vuex state not updating on mutation - javascript

In my Vue.js/Vuex based application I'm using this mutation to reset part of the Vuex state:
restartGame(state) {
state.gameRunning = true
state.camera = {
position: {
x: 0,
y: 10,
z: 0
},
moveForward: false,
moveBackward: false,
moveLeft: false,
moveRight: false,
velocity: {
x: 0,
z: 0
},
mouseMovement: {
x: 0,
y: 0
},
rotation: {
x: 0,
y: 0
}
}
}
This way, things work out fine, but writing out the whole camera state seems pretty verbose to me. So I extracted the initial camera state into a seperate file:
initialCameraState.js
export default {
position: {
x: 0,
y: 10,
z: 0
},
moveForward: false,
moveBackward: false,
moveLeft: false,
moveRight: false,
velocity: {
x: 0,
z: 0
},
mouseMovement: {
x: 0,
y: 0
},
rotation: {
x: 0,
y: 0
}
}
I've refactored the resetGame() mutation like this:
import initialCameraState from './initialCameraState'
restartGame(state) {
state.gameRunning = true
state.camera = initialCameraState
}
But somehow this doesn't work, the Vuex store does not get updated but seems to just stay the same. How can this be?
I'm also using initialCameraState.js to set (part of) the initial state of the Vuex store. My first thought was that when mutating the according part of the state, initialCameraState is also being mutated. That would explain resetGame() not showing any effects. So I tried using the object spread operator in both places where initialCameraState.js gets imported/used, but this didn't solve the issue.

I don't have all your code, but here's what I think may be happening. You are initing the game with the initial state which you have imported. During the game you update the state of the object by doing something like:
state.camera['position'] = {
x: 100,
y: 100,
z: 100
}
}
What actually happens is that your initial state has been updated because you have a reference to the object, not a copy of it, so when you try to reset the state it just remains the same, because you have inadvertently changed the initial state object.
To solve this simply wrap the initial state in a function (a factory function) so that the init state always gets returned:
export default function() {
return {
position: {
x: 0,
y: 10,
z: 0
},
moveForward: false,
moveBackward: false,
moveLeft: false,
moveRight: false,
velocity: {
x: 0,
z: 0
},
mouseMovement: {
x: 0,
y: 0
},
rotation: {
x: 0,
y: 0
}
}
};
Here's a JSFiddle showing what happens without a function (the positions remain the same): https://jsfiddle.net/9qg8ws0x/
And here one with the function (the positions are reset): https://jsfiddle.net/27xozazf/

export default {
initializeCamera () {
return {
position: {
x: 0,
y: 10,
z: 0
},
moveForward: false,
moveBackward: false,
moveLeft: false,
moveRight: false,
velocity: {
x: 0,
z: 0
},
mouseMovement: {
x: 0,
y: 0
},
rotation: {
x: 0,
y: 0
}
}
}
}
import initial from './initial'
restartGame(state) {
state.gameRunning = true
state.camera = initial.initializeCamera()
}

Related

Phaser groups moving each child independantly

so i have a phaser group
this.cows = this.physics.add.group({
key: "cow",
repeat: 2,
setXY: { x: 160, y: 1500, stepX: 32 },
});
this.cows.children.iterate(function (child) {
child.setSize(20, 10, true);
child.setBounceY(Phaser.Math.FloatBetween(0.2, 0.4));
});
I plan to update the movement of every child in the update function, so how would i make sure every child has a different amount of movement in a different direction?
Depending on your use case you could simply use, a property destination which the child wants to reach, and when it is reached, just set a new destination.
Here a short demo showcaing this:
(it uses Vector's, not everybody likes/understtands them, but they are concise)
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
debug: true
}
},
scene: {
create,
update
},
banner: false
};
function create () {
this.add.text(10,10, 'Random Movment')
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
let graphics = this.make.graphics();
graphics.fillStyle(0xffffff);
graphics.fillRect(0, 0, 10, 10);
graphics.generateTexture('cow', 10, 10);
this.cows = this.physics.add.group({
key: "cow",
repeat: 2,
setXY: { x: 50, y: 50, stepX: 32 },
});
this.cows.children.iterate(function (child) {
child.setSize(10, 10, true);
child.setBounceY(Phaser.Math.FloatBetween(0.2, 0.4));
child.speed = Phaser.Math.Between(30, 50);
child.destination = { x: child.x , y: child.y};
});
}
function update(){
this.cows.children.iterate(function (child) {
if(Phaser.Math.Distance.BetweenPoints(child.body.position, child.destination) <= 20){
//new destination
child.destination = { x:Phaser.Math.Between(50, 200), y:Phaser.Math.Between(50, 150)};
// Setup velocity
let vector = new Phaser.Math.Vector2(child.destination);
vector.subtract(child.body.position)
.setLength(child.speed);
child.setVelocity(vector.x, vector.y);
}
});
}
new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>

Bug report: Wrong position of the UIElement / ChartMarkerXY when first rendering a chart with animation disabled

I've tried to place an UIElement / ChartMarkerXY on a chart where the animations are disabled.
Unfortunately, the UIElement / ChartMarkerXY was not in the right position on the first render.
However, when we do an another render (eg: when you put the mouse on the chart for show the AutoCursor), it has been moved to the right position.
I noticed that when the animations are enabled, the first frame of the animation put the UIElement / ChartMarkerXY at the same position.
Currently, I have a workaround for prevent this: chart.engine.renderFrame(0,0)
Demonstration of the bug
You can find in the snippet an example that reproduce the bug:
const {
AxisPosition,
AxisTickStrategies,
emptyLine,
lightningChart,
Point,
UIElementBuilders,
emptyFill
} = lcjs;
const dataSeries = [
{ x: -5, y: 0 },
{ x: 2, y: -5 },
{ x: 5, y: 6 },
{ x: 8, y: 12 },
{ x: 12, y: -12 }
];
const chart = lightningChart().ChartXY({
container: 'chart',
});
chart.setAnimationsEnabled(false);
chart.addLineSeries().add(dataSeries);
chart.addUIElement(UIElementBuilders.TextBox, {
x: chart.getDefaultAxisX(),
y: chart.getDefaultAxisY()
})
.setText('My Text')
.setPosition({ x: 0, y: 0 });
.lcCanvas {
width: 500px;
height: 300px;
}
<script src="https://unpkg.com/#arction/lcjs#3.1.0/dist/lcjs.iife.js"></script>
<h2>Example of the bug</h2>
<div id="chart" class="lcCanvas"></div>
Bug reports should be sent to support#lightningchart.com instead of posting here.
-- Snekw
Bug report sent.
Currently, the workaround I found is chart.engine.renderFrame(0,0).
This will force the re-render of the chart, and put the marker at the right position.
Here, a snippet of how implement the workaround.
const {
AxisPosition,
AxisTickStrategies,
emptyLine,
lightningChart,
Point,
UIElementBuilders,
emptyFill
} = lcjs;
const dataSeries = [
{ x: -5, y: 0 },
{ x: 2, y: -5 },
{ x: 5, y: 6 },
{ x: 8, y: 12 },
{ x: 12, y: -12 }
];
const chart = lightningChart().ChartXY({
container: 'chart',
});
chart.setAnimationsEnabled(false);
chart.addLineSeries().add(dataSeries);
chart.addUIElement(UIElementBuilders.TextBox, {
x: chart.getDefaultAxisX(),
y: chart.getDefaultAxisY()
})
.setText('My Text')
.setPosition({ x: 0, y: 0 });
chart.engine.renderFrame(0, 0); // Workaround: Add this for force the re-render
.lcCanvas {
width: 500px;
height: 300px;
}
<script src="https://unpkg.com/#arction/lcjs#3.1.0/dist/lcjs.iife.js"></script>
<h2>Workaround</h2>
<div id="chart" class="lcCanvas"></div>

javascript prettier formats objects on several lines

I run Prettier in my VSC-editor and I've had a problem with the formatting of objects for a while now. The problem is that it will always format the objects on several lines, even when there is room for the entire object on one line.
Input
let map = {
0: { x: 0, y: -1 },
1: { x: 1, y: 0 },
2: { x: 0, y: 1 },
3: { x: -1, y: 0 }
};
Output
let map = {
0: {
x: 0,
y: -1
},
1: {
x: 1,
y: 0
},
2: {
x: 0,
y: 1
},
3: {
x: -1,
y: 0
}
};
It also does this with imports:
Input
import { Foo } from 'Bar';
Output
import {
Foo
} from 'Bar';
These are my current rules:
editor.formatOnSave": true,
"prettier.singleQuote": true,
"prettier.printWidth": 80,
"prettier.bracketSpacing": false,
"prettier.proseWrap": "always",
"prettier.trailingComma": "all"
Are there any ways to prevent this behavior, preferably permanently?

Change zoom level 3d scatterPlot (Plotly)

I have a 3d scatterplot of which i want to change its zoom level and pan around it programmatically. I have tried setting the range in the layout from the beggining but it does not change the actual zoom level, just the points in the range:
"layout":
{
margin: {
l: 0,
r: 0,
b: 0,
t: 0,
pad: 1
},
scene:{
xaxis: {range:[-13,13.5]},
yaxis: {range:[-15.5,13.5]},
zaxis: {range:[-14.5,13.5]},
}
},
Also i've tried invoking it with the relayout function, but it is also not working
var update = {
scene:{
xaxis: {range:[-13,13.5]},
yaxis: {range:[-15.5,13.5]},
zaxis: {range:[-14.5,13.5]},
},
};
Plotly.relayout(gd, update);
Finally i found the property to change the camera position:
var update = {
scene:{
camera: {
center: { x: 0, y: 0, z: 0 },
eye: { x: 2, y: 2, z: 0.1 },
up: { x: 0, y: 0, z: 1 }
}
},
};
Plotly.relayout(gd, update);

Matter JS - option list - Am I blind?

New to MatterJS.
In the example, theres is options to draw circle, rectangle, etc.
Those options are like using Sprite, FillStyle...
I see no where in the documentation the list of options and values related to that.
Anyone can help?
Thanks.
From reading the source code of matter.js I found the defaults for options. Doesn't explain what each does but at least here's a list of them:
var defaults = {
id: Common.nextId(),
type: 'body',
label: 'Body',
parts: [],
plugin: {},
angle: 0,
vertices: Vertices.fromPath('L 0 0 L 40 0 L 40 40 L 0 40'),
position: { x: 0, y: 0 },
force: { x: 0, y: 0 },
torque: 0,
positionImpulse: { x: 0, y: 0 },
constraintImpulse: { x: 0, y: 0, angle: 0 },
totalContacts: 0,
speed: 0,
angularSpeed: 0,
velocity: { x: 0, y: 0 },
angularVelocity: 0,
isSensor: false,
isStatic: false,
isSleeping: false,
motion: 0,
sleepThreshold: 60,
density: 0.001,
restitution: 0,
friction: 0.1,
frictionStatic: 0.5,
frictionAir: 0.01,
collisionFilter: {
category: 0x0001,
mask: 0xFFFFFFFF,
group: 0
},
slop: 0.05,
timeScale: 1,
render: {
visible: true,
opacity: 1,
sprite: {
xScale: 1,
yScale: 1,
xOffset: 0,
yOffset: 0
},
lineWidth: 0
}
};
As taras pointed out the object's properties are initialized from these options.
These options are body's properties, described in Matter.Body module: http://brm.io/matter-js/docs/classes/Body.html#properties
I think that in those examples, matter.js is handling the drawing of the shapes of the bodies itself through Render.bodies (inside matter.js file) and related functions.
In case anyone want to draw lines, circles or rectangles, they can access the canvas that matter.js uses, and draw them via lineTo, arc functions of canvas, I guess.

Categories