How to collide with custom sprite bounds in Phaser - javascript

I have a file pickle.png with a custom hitbox in a pickle.json file like this which I created using PhysicsEditor.
{
"pickle": [
{
"density": 2, "friction": 0, "bounce": 0,
"filter": { "categoryBits": 1, "maskBits": 65535 },
"shape": [ 468, 156 , 399, 214 , 365, 222 , 387, 98 , 414, 100 , 443, 113 , 467, 131 ]
} ,
// etc
]
}
In my preload function I put this:
this.game.load.physics("pickle_physics", "pickle.json");
and in the create function:
game.physics.startSystem(Phaser.Physics.P2JS);
this.pickle = game.add.sprite(400, 300, '/pickle.png');
game.physics.p2.enable(this.pickle, true);
this.pickle.body.loadPolygon('pickle_physics', 'pickle');
// this is a separate sprite with default bounds
this.foo = mt.create('foo1');
game.physics.p2.enable(this.foo, true);
if I inspect foo and pickle in the browser console they are both the same kind of sprite object.
Now I want to make them collide, so I add this to the update function:
this.game.physics.arcade.collide(
this.foo, this.pickle, function(foo, pickle) {
}, null, this
)
The net result of all of this is what you can see in the following gif (note, cylindrical object is a kool-aid soaked pickle):
They are not colliding at all, and the pickle looks terrible. I don't want to see the rectangle around it, or the vertices.
I see there's an example here but I'm having trouble making sense of it.
edit great news, I've made a bit of progress with the help of the collision-groups example.
// collision setup for non-rectanular sprites
game.physics.p2.setImpactEvents(true);
game.physics.p2.restitution = 0.8;
foo.body = new Phaser.Physics.P2.Body(game, foo, 0, 0)
var foo_collision = game.physics.p2.createCollisionGroup();
var pickle_collision = game.physics.p2.createCollisionGroup();
game.physics.p2.updateBoundsCollisionGroup();
this.foo.body.setCollisionGroup(foo_collision);
this.foo.body.collides([foo_collision, pickle_collision]);
this.pickle.body.setCollisionGroup(pickle_collision);
this.pickle.body.collides(foo_collision, function(pickle, foo) {
console.log('hit')
}, this);
At first I had an error with this because foo.body didn't respond to setCollisionGroup. foo.body was constructed using Arcade physics, so I needed to replace it with a Phaser.Physics.P2.Body instance. The result of this is I have collisions, but not in the custom bounds:

I had to change the following lines
game.physics.p2.enable(this.pickle, true);
game.physics.p2.enable(this.foo, true);
and make it false instead of true . The true means it's debug mode, and will show all those ugly borders and vertices. This is covered in the following tutorial, which was very useful in all this: https://www.codeandweb.com/physicseditor/tutorials/phaser-p2-physics-example-tutorial.
Second, before this.pickle.body.loadPolygon('pickle_physics', 'pickle'); I needed to add this.pickle.body.clearShapes(); to remove the outer rectangle bounds.
The result is this:

Related

What format polygon does D3plus largest rectangle require?

I found an interesting demo of how to find the largest rectangle in an irregular shaped polygon here using D3plus.
I'm trying to recreate this for a polygon I'm working on but currently the code is not working. It seems to runs endlessly. The code I'm using is as follows:
d3.csv("data/polyPoints.csv", function(error, polyPoints) {
if (error) return console.error(error);
// coerce string values to numbers
polyPoints.forEach(function(d) {
d3.keys(d).forEach(function(k) {
d[k] = +d[k]
})
});
// settings for geom.largestRect
var rectOptions = {
angle: 0,
maxAspectRatio: 5,
nTries: 1
};
console.log(rectOptions);
console.log(polyPoints);
var lRect = d3plus.geom.largestRect(polyPoints, rectOptions);
console.log(lRect);
});
I suspect my polygon is not in the correct format.
Update
I'm making progress. My original polygon object was taken from a csv and created an array of arrays of key value pairs (e.g. {"x": 0 "y": 1},{"x": 2, "y": 1}....)
I converted this to an array of arrays (e.g. [[1,0],[2,0]....])
Now the code is running but the output is defining rectangles that cross the boundary of the original polygon.
For anyone working with this. The largestRect docs are https://d3plus.org/docs/#largestRect and can be run with the following code.
const d3p = require('d3plus');
const polygon = [[x,y],[x,y],[x,y]...]
const rectOptions = {
maxAspectRatio: 5,
nTries: 20
};
let lRect = d3p.largestRect(rdp, rectOptions);
The algorithm used is an approximation and random points inside the polygon are chosen to do calculations from. Because of this the edges of the box won't always be touching the edge but should be "close enough".
The options.tolerance value might affect this as well but I haven't played around with it much. This is a pretty old question but hopefully it helps someone.

update choropleth by string (not by fillKey prop)

I read the guide->updating after initial drawing part at https://github.com/markmarkoh/datamaps but updating doesn't work using string values (it works fine using fillKey property instead). I read this closed issue too: markmarkoh/datamaps#118 but nothing.
This is my code:
v
ar map = new Datamap({
element: document.getElementById('world'),
geographyConfig: {
dataUrl: 'world-topo-min.json',
borderColor: 'black'
},
scope: 'countries',
fills: {
defaultFill: 'rgb(255,255,255)',
someKey: '#08306b'
},
data: {
'108': {fillKey: 'someKey'}
},
setProjection: function(element) {
var projection = d3.geo.mercator()
.center([30, 34.4444])
.scale(170)
.translate([element.offsetWidth / 2 , element.offsetHeight/2]);
var path = d3.geo.path().projection(projection);
return {path: path, projection: projection};
}
});map.updateChoropleth({'57': {fillKey:'someKey'},'116': '#08306b'});
Country identificated by id=57 is ok, country 116 doesn't change
I pull data from a PHP-array like this:
myarray=[[57,32],[116,12]]
Country 57 has value 32, country 116 has value 12 and so on.
I ignore myarray right now because I want to solve updatechoropleth issue first
Obviously, I'm going to create a linear scale to put right colors into countries path but this is another thing.
Help me please
Thank you guys!

Error 1105: Target of Assignment must be a Reference Value

Flash says the code is on my second line, but I've done some reading and it says this error is mainly due to me trying to assign a value to a value, and I've looked back over my code, and I can't seem to find any instance of this.
Here is my code:
this.mc=new MovieClip();
addChild(mc)=("myButton1", this.DisplayOBjectContainer.numChildren());
myButton1.createEmptyMovieClip("buttonBkg", myButton1.getNextHighestDepth());
myButton1.buttonBkg.lineStyle(0, 0x820F26, 60, true, "none", "square", "round");
myButton1.buttonBkg.lineTo(120, 0);
myButton1.buttonBkg.lineTo(120, 30);
myButton1.buttonBkg.lineTo(0, 30);
myButton1.buttonBkg.lineTo(0, 0);
Thanks!
Check what you are trying to in these lines:
addChild(mc)=("myButton1", this.DisplayOBjectContainer.numChildren());
myButton1.createEmptyMovieClip("buttonBkg", myButton1.getNextHighestDepth());
To create an empty MovieClip, you can just create a new display object w/o linking it to a clip in the library like this:
addChild(mc);
var myButton1:MovieClip = new MovieClip(); // creates an empty MovieClip
addChildAt(myButton1, numChildren); // adds the MovieClip at a defined level (on this case, the numChildren added on stage
Your code is very confusing. You mix AS2 methods (createEmptyMovieClip, getNextHighestDepth) with AS3 methods (addChild). Here is what you are trying to do:
const MC:Sprite = new Sprite(); // Sprite container
this.addChild(MC);
const MYBUTTON1:Sprite = new Sprite(); // button in container
MC.addChild(MYBUTTON1);
const BUTTONBKG:Shape = new Shape(); // background in button
MYBUTTON1.addChild(BUTTONBKG);
const BTG:* = BUTTONBKG.graphics;
BTG.beginFill(0x86B1FB);
BTG.lineStyle(0, 0x820F26, 0.6, true, "none", "square", "round");
BTG.lineTo(120, 0);
BTG.lineTo(120, 30);
BTG.lineTo(0, 30);
BTG.lineTo(0, 0);
MYBUTTON1.addEventListener(MouseEvent.CLICK, pressButton);
function pressButton(e:MouseEvent):void {
trace('I click on you');
}
Notes : the alpha value in AS3 is between 0 and 1. If you want your button to be clickable, you should use beginfill method.

CreateJs EaselJS spritesheet frames not working

So I have spritesheet i have almost looked everywhere nor i can find good tutorial neither i can get this thing to work .Can some one point it out for me that what's wrong here.?Coz none error is generated nor is anythign getting showed on the canvas .
var result = queue.getResult("avatar1");
var data=
{
images: [ result],
// The 5th value is the image index per the list defined in "images" (defaults to 0).
frames: [
// x, y, width, height, imageIndex, regX, regY
//head_south":{"x":120,"h":20,"y":138,"w":15}
[120,138,15,20],
[64,0,15,20,2],
],
animations: {
show: { frames: [0,1], next: true, frequency: 1 }
}
};
var sp = new createjs.SpriteSheet(data);
createjs.Ticker.setFPS(60);
var sprite_anim = new createjs.BitmapAnimation(sp,"show");
sprite_anim.x=100;
sprite_anim.y=100;
stage.addChild(this.sprite_anim);
sprite_anim.play("show");
sprite_anim.gotoAndPlay('show');
Do you update the stage with the ticker ? :
createjs.Ticker.addEventListener("tick", function(event) {
stage.update(event);
});
4 arguments [120,138,15,20], 5 arguments [64,0,15,20,2]
Arguments that are allowed are either 4 or 7.So changed back to 4.That was why it was generating error of" createjs type error '.
Thank everyone for your conern .Closing this question.

Openlayers - LayerRedraw() / Feature rotation / Linestring coords

TLDR: I have an Openlayers map with a layer called 'track' I want to remove track and add track back in. Or figure out how to plot a triangle based off one set of coords & a heading(see below).
I have an image 'imageFeature' on a layer that rotates on load to the direction being set. I want it to update this rotation that is set in 'styleMap' on a layer called 'tracking'.
I set the var 'stylemap' to apply the external image & rotation.
The 'imageFeature' is added to the layer at the coords specified.
'imageFeature' is removed.
'imageFeature' is added again in its new location. Rotation is not applied..
As the 'styleMap' applies to the layer I think that I have to remove the layer and add it again rather than just the 'imageFeature'
Layer:
var tracking = new OpenLayers.Layer.GML("Tracking", "coordinates.json", {
format: OpenLayers.Format.GeoJSON,
styleMap: styleMap
});
styleMap:
var styleMap = new OpenLayers.StyleMap({
fillOpacity: 1,
pointRadius: 10,
rotation: heading,
});
Now wrapped in a timed function the imageFeature:
map.layers[3].addFeatures(new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(longitude, latitude), {
rotation: heading,
type: parseInt(Math.random() * 3)
}
));
Type refers to a lookup of 1 of 3 images.:
styleMap.addUniqueValueRules("default", "type", lookup);
var lookup = {
0: {
externalGraphic: "Image1.png",
rotation: heading
},
1: {
externalGraphic: "Image2.png",
rotation: heading
},
2: {
externalGraphic: "Image3.png",
rotation: heading
}
}
I have tried the 'redraw()' function: but it returns "tracking is undefined" or "map.layers[2]" is undefined.
tracking.redraw(true);
map.layers[2].redraw(true);
Heading is a variable: from a JSON feed.
var heading = 13.542;
But so far can't get anything to work it will only rotate the image onload. The image will move in coordinates as it should though.
So what am I doing wrong with the redraw function or how can I get this image to rotate live?
Thanks in advance
-Ozaki
Add: I managed to get
map.layers[2].redraw(true);
to sucessfully redraw layer 2. But it still does not update the rotation. I am thinking because the stylemap is updating. But it runs through the style map every n sec, but no updates to rotation and the variable for heading is updating correctly if i put a watch on it in firebug.
If I were to draw a triangle with an array of points & linestring.
How would I go about facing the triangle towards the heading.
I have the Lon/lat of one point and the heading.
var points = new Array(
new OpenLayers.Geometry.Point(lon1, lat1),
new OpenLayers.Geometry.Point(lon2, lat2),
new OpenLayers.Geometry.Point(lon3, lat3)
);
var line = new OpenLayers.Geometry.LineString(points);
Looking for any way to solve this problem Image or Line anyone know how to do either added a 100rep bounty I am really stuck with this.
//From getJSON request//
var heading = data.RawHeading;
Adding and removing the imageFeature
Solved the problem as follows:
var styleMap = new OpenLayers.StyleMap({
fillOpacity: 1,
pointRadius: 10,
rotation: "${angle}",
});
var lookup = {
0: { externalGraphic: "Image1.png", rotation: "${angle}" },
1: { externalGraphic: "Image2.png", rotation: "${angle}" },
2: { externalGraphic: "Image3.png", rotation: "${angle}" }
}
styleMap.addUniqueValueRules("default", "type", lookup);
map.layers[3].addFeatures(new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(lon, lat), {"angle": dir, type: parseInt(Math.random() * 3)}
), {"angle": dir});
then the request:
var dir = (function () {
$.ajax({
'async': false,
'global': true,
'url': urldefault,
'dataType': "json",
'success': function (data) {
dir = data.Heading
}
});
return dir;
})();
Problem solved. Works perfectly.
You can also try to put heading on the object as an attribute:
{"mapFeatures": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "1579001",
"x": 51.0,
"y": 1.2,
"geometry": {
"type": "Point",
"coordinates": [
51.0,
1.2
],
"crs": {
"type": "OGC",
"properties": {
"urn": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
}
},
"properties": {
"heading": 45,
"label": "some_label_goes_here"
}
}
]
}
}
Then you would have to rewrite your lookup function like this:
var lookup = {
0: {externalGraphic: "Image1.png", rotation: ${heading}},
1: {externalGraphic: "Image2.png", rotation: ${heading}},
2: {externalGraphic: "Image3.png", rotation: ${heading}}
}
Could you try that and see if it works? If you don' t know if the attributes are set correctly, you can always debug with firebug, that is what I always do. There is one tricky thing; when parsing geojson; "properties" are translated to "attributes" on the final javascript object.
First guess:
I assume your layer has a single point object that moves and rotates as when following a car with GPS?
It might be better if you would simply destroy all features on the layer (assuming it is only one feature) and redraw the feature with the new heading set.
Second guess:
Perhaps you need to use a function instead of a variable to maintain the live connection to the rotation.
Please check the documentation here: http://trac.openlayers.org/wiki/Styles on styles.
Hope this helps a bit.

Categories