a strange behavior in Phaser with javascript - javascript

firstly
I am not beginner at game development at all - but beginner in web game development specially
I started with Phaser as it looks good and optimized for mobile games
anyway ..
I have a strange behavior with my game - I put a rectangle and trying to move it (when I debugged the X axis already changes correctly , but I can't see the rectangle move!!)
my codes
var game = new Phaser.Game(window.innerWidth,window.innerHeight,Phaser.AUTO);
var colors = ["#FF0000" , "#00FF00" , "#0000FF" , "#FFFF00" , "#00FFFF" , "#FFFF00"];
var lst;
var hlprs = [];
var gameState = {
preload: function () {
this.game.stage.backgroundColor = "#FFFFFF";
},
create: function () {
for (var i = 0 ; i < 8 ; i++)
{
hlprs[i] = new Phaser.Rectangle((i*200),0,100,20);
hlprs[2*i + 1] = new Phaser.Rectangle((i*200),window.innerHeight - 20,100,20);
game.debug.geom(hlprs[i] , colors[Math.floor((Math.random() * 6))]);
game.debug.geom(hlprs[2*i + 1] , colors[Math.floor((Math.random() * 6))]);
}
},
update: function ()
{
moving();// it calls moving function and X axis is changes but (the rectangle does not move !!!)
}
};
function moving()
{
for (var i = 0 ; i < 8 ; i++)
{
hlprs[i].offset(-1,0);
hlprs[2*i + 1].offset(-1,0);
}
}
game.state.add('GameState' , gameState);
game.state.start('GameState');

Without testing it, I'd guess that what happens is the following: you create a bunch of shapes and do a single call to game.debug.geom() for each of the shapes. In the meantime the shapes do start moving, but since you never call game.debug.geom() again, you never see anything moving.
If you intend to use methods from game.debug, they should usually go inside the render() method of your state (which will be called once for every frame).
Note that the debug methods are to be used, well, for debugging. The proper way of displaying a shape is by making a sprite or an image (in which case you won't have to update anything manually since Phaser will handle it).

Since the update() function calls moving() you might want to have your game.debug commands within moving
function moving()
{
for (var i = 0 ; i < 8 ; i++)
{
hlprs[i].offset(-1,0);
hlprs[2*i + 1].offset(-1,0);
// update here
game.debug.geom(hlprs[i] , colors[Math.floor((Math.random() * 6))]);
game.debug.geom(hlprs[2*i + 1] , colors[Math.floor((Math.random() * 6))]);
}
}
Here's a demo: https://jsfiddle.net/user2314737/J5fUE/253/

Related

Trying to add bulelts to javascript game ( to the spacebar)

I am almost done my game, I just need to add bullets that fire when you press space
I do have some code so far that I used from a tutorial, however it points towards the mouse. I know that I have to move it into the key-handler, but I don't know how.
I also don't know how to get rid of the wade part, I know it comes from a .json file but I want not to
Heres the code:
var nextFireTime = lastFireTime + 1 / fireRate;
var time = wade.getAppTime();
if (wade.isMouseDown() && time >= nextFireTime)
{
lastFireTime = time;
// create bullet...
}
wade.setMainLoopCallback(function()
{
// code to execute several times per second
}, 'fire');
if (wade.isMouseDown())
{
var spacemanPosition = spacemanImage.getPosition();
var spacemanSize = spacemanImage.getSize();
var sprite = new Sprite('images/alien.png');
var bullet = new SceneObject(sprite, 0, shipPosition.x, shipPosition.y - shipSize.y / 2);
wade.addSceneObject(bullet);
bullet.moveTo(shipPosition.x, -500, 600);
}
bullet.onMoveComplete = function()
{
wade.removeSceneObject(this);
};
var lastFireTime = 0;
var fireRate = 5;
To use the spacebar instead of a mousepress you have to change
wade.isMouseDown()
to
wade.isKeyDown('space')

Detecting Collision With Object in Loop

Is there a way to detect collision with an object created using a while loop?
I'm repeating an image across the screen using a while loop:
this.spikeX = 0;
while (this.spikeX < this.world._width) {
this.spike = this.add.sprite(this.spikeX, 0, 'spikes');
this.physics.arcade.enable(this.spike);
this.gameObjects.push(this.spike);
this.spikeX += (this.spike.width * 0.75);
}
I have a collision function:
collision: function(obj1, obj2) {
if (obj1.body.x < obj2.body.x + obj2.body.width &&
obj1.body.x + obj1.body.width > obj2.body.x &&
obj1.body.y < obj2.body.y + obj2.body.height &&
obj1.body.height + obj1.body.y > obj2.body.y) {
return true;
}
},
if(this.collision(this.player, this.spike)) {
console.log('spike');
}
When I call this function in the update function it doesn't detect collision but works when I just create a single spike outside the while loop.
That's probably because you have only one this.spike.
If you have multiple sprites, you need to put them into a group, and create them like this:
spike_group = game.add.group();
spike = spikes.create(spikeX, 0, 'spikes');
Then you check collision for each spike inside spike_group and a player.
And, why don't you use arcade collision like this:
// inside update function
physics.arcade.collide(player, spike_group , overlap_spikes, this);
// out of update function
function overlap_spikes()
{
console.log("touch spike");
}
Note: These examples does not use 'this' keyword.

How to add a Cesium3DTileset to a scene but disable picking events (allowPicking)

Using Cesium 1.37.
I'm adding two sets of 3D-Tiles to a scene with this code :
viewer.scene.primitives.add(new Cesium.Cesium3DTileset({url : 'data/3DTiles/example_1'}));
viewer.scene.primitives.add(new Cesium.Cesium3DTileset({url : 'data/3DTiles/example_2'}));
This works as expected, the 3D-Tiles are properly displayed.
Now I implemented the code in the "3D Tiles Feature Picking" Sandcastle example (/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html) enabling feature highlight based on mouse events.
This too works as expected.
My problem : I want to disable picking events for the second 3D-Tiles set.
In the Cesium documentation I see a constructor option "allowPicking". Sadly this only seems to be a property for Primitive object, not Cesium3DTileset.
Did I miss something ?
I used two nested 3D tilesets, one of them is visualized with transparency. Also i noticed this problem, but couldn't find any direct solution. I used drillPick function in cesiumjs to get all tileset feature candidates from picked position and then filtered features with requested tileset.
var scene = viewer.scene;
if (!scene.pickPositionSupported) {
console.log('This browser does not support pickPosition.');
}
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (result) {
var pickedObjects = viewer.scene.drillPick(result.position);
if (pickedObjects.length >= 1) {
for (var j = 0; j < pickedObjects.length; j++) {
//Code below removes picked features from array which are not belongs to tileset1.
if (pickedObjects[j].tileset !== tileset1) {
pickedObjects.splice(j, 1);
}
}
var feature = pickedObjects[0];
if (feature instanceof Cesium.Cesium3DTileFeature) {
var propertyNames = feature.getPropertyNames();
var length = propertyNames.length;
for (var i = 0; i < length; ++i) {
var propertyName = propertyNames[i];
console.log(propertyName + ': ' + feature.getProperty(propertyName));
}
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

Three.js Event Listener in scene renderer

This will be a "strange" question, because my code works. I just want to check if it can be tweaked because I dont have programming experience.
I wrote a script that gets a stream of kinect joints and plots them on a three js scene on an coordinates system with a webgl renderer.
At first I create a set of spheres, based on Stemkoski's examples and then add the event listener for the json skeleton that arrives in the update function, so I can update the spheres coordinates and have it moving.
The only problem that this creates is that now I cannot rotate the coordinates system with my mouse (while I could when I was testing it with static spheres or with pulsing spheres, as in Stemkoski's example).
So the first question is how can I correct this problem.
The second, more complex question is this : Is this a correct practice? I may not be a developer but I have learned that when my gut says this is awkward or bad practice, it probably is.. Any help and suggestions, appreciated.
Oh, and I have implemented this for only one skeleton in the scene. I will try to make it for more skeletons but I ll wait for your input here in case this all could be simpler and better written.
Here's the relevant code, the initialization of the sphere/joints and the update function:
WholeSkeleton = new THREE.Object3D();
particleAttributes = { startSize: [], startPosition: [] };
var totalParticles = 20; //=num.skeleton.joints //add later variable number
var radiusRange = 50;
for (var i = 0; i < totalParticles; i++) { // INITIALIZE THE SKELETON JOINTS POSITION
var sphereMaterial = new THREE.MeshLambertMaterial({ color: 'rgb(255,0,0)' });
var jointSphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
//initialize positions
jointSphere.position.set(0, 0, 0);
WholeSkeleton.add(jointSphere);
// add variable qualities to arrays, if they need to be accessed later
particleAttributes.startPosition.push(jointSphere.position.clone());
}
scene.add(WholeSkeleton);
}
function animate() {
requestAnimationFrame(animate);
render();
update();
}
function update() {
document.addEventListener("skeletonEvent", function (e) {
jsonObject = e.detail.SkeletonSourceData;
// for (var i = 0; i < jsonObject.Skeletons.length; i++) {
for (var j = 0; j < jsonObject.Skeletons[0].Joints.length; j++) { //only for skeleton 0.
var incoming=jsonObject.Skeletons[0].Joints[j];
var joint = WholeSkeleton.children[j];
joint.position.x = (particleAttributes.startPosition[j].x + incoming.Position.X)*30;
joint.position.y = (particleAttributes.startPosition[j].y + incoming.Position.Y)*30;
joint.position.z = (particleAttributes.startPosition[j].z + incoming.Position.Z)*10;
}
// }
});
}
--

Set background color in a smooth way

I've got the following JS code:
// utility function to convert r,g,b to html color
function RGB2HTML(red, green, blue) {
var decColor =0x1000000+ blue + 0x100 * green + 0x10000 *red ;
return '#'+decColor.toString(16).substr(1);
}
// recursive utility function to animate color
// elNames an array of Ids (these are mainly TDs)
// curCnt is current animation step
// totSteps is total steps
function pulseBGMany(elNames, curCnt, totSteps) {
for(var i=0; i < elNames.length; ++i) {
var curEl = document.getElementById(elNames[i]);
var curColor = RGB2HTML(255, 255*(curCnt/totSteps), 255*(curCnt/totSteps));
curEl.style.backgroundColor = curColor;
}
if(curCnt < totSteps) {
setTimeout( function(){ pulseBGMany(elNames, curCnt+1, totSteps); }, 40);
}
}
// eventually in another piece of code, it all gets triggered
...
// schedule ui update here!
// use a closure
(function(names){ setTimeout( function(){ pulseBGMany(names, 0, 25); }, 40)})(diffRes);
...
The code above works, but unfortunately the animation is very chopped and I'm not able to see a smooth gradient from red to white; it seems like all major browsers are losing frames (tested on Firefox and Chromium on Ubuntu).
The array of TDs varies from 1 to even 80 elements, but the effect is always the same.
What am I doing wrong?
As requested, JSFiddle link: http://jsfiddle.net/PsvCP/2/ (You have to set No wrap in body)
Thanks,
Ema
Try doubling the amount of steps, 25fps is somewhat choppy.
Doubling the steps should put you at 50fps which should be fine.
Also make the elmntlist a array of dom elements and not a array of element id's,
Dom lookups are really slow and probaply causing most of your problems.
Think I've gotten around it. Apparently the setTimeout API is particularly slow in both Chrom(ium) and Firefox. Scheduling all the gradient function calls in advance is much more efficient for current browsers and does the trick:
// non-recursive utility function to animate color
function pulseBGMany(elNames, curCnt, totSteps) {
var curColor = RGB2HTML(255, 255*(curCnt/totSteps), 255*(curCnt/totSteps));
for(var i=0; i < elNames.length; ++i) {
elNames[i].style.backgroundColor = curColor;
}
}
...
// schedule ui update here!
// use a closure
var numFade = 15;
for(var i=0; i < numFade; ++i) {
(function(names, iter, tot){ setTimeout( function(){ pulseBGMany(names, iter+1, numFade); }, 50*iter)})(diffRes, i, numFade);
}
...
and as expected this works a lot faster.

Categories