pixi.js how do I get draw count - pixi.js

I'm using this code to add a ticker. The draw method looks like this:
this.ticker = this.ticker || this.app.ticker.add(this.draw)
Here app is the PIXI.Application. The draw method looks like so:
private draw(): void {
console.log(this.ticker.FPS)
}
This gives me the FPS but how do I get the draw calls count? many thx
Draw calls are discussed here https://pixijs.io/pixi-batch-renderer/PIXI.brend.BatchRenderer.html
This object renderer renders multiple display-objects in batches. It can greatly reduce the number of draw calls issued per frame.

let drawCount = 0;
const renderer = app.renderer as any;
const drawElements = renderer.gl.drawElements;
renderer.gl.drawElements = (...args: any[]) => {
drawElements.call(renderer.gl, ...args);
drawCount++;
}; // rewrite drawElements to count draws
app.ticker.add((deltaTime) => {
console.log(`drawCount: ${drawCount}`);
drawCount = 0; // clear count per frame
});

Related

Three JS how to add color and line thickness to mesh loaded with GLTFLoader

So far I managed to load a mesh with GLTFLoader and turn it into a wireframe. I'm stuck at the part where I want to color it and give it a line thickness.
I don't completely understand how to use traverse().
My code so far:
var loader = new THREE.GLTFLoader();
loader.load('model.glb', handle_load);
var mesh;
function handle_load(gltf) {
mesh = gltf.scene;
mesh.traverse((node) => {
if (!node.isMesh) return;
node.material.wireframe = true;
});
scene.add(mesh);
mesh.position.z = 2;
}

HaxeFlixel: make object disappear in certain area

I'm trying to make a game where you can capture floating lights that moves randomly in the air. In the game there is going to be 3 different boxes where you can put the floating lights, so there is also going to be 3 different lights.
The lights works properly and I am able to drag them around like I want.
My issue is how to catch them and re-spawn them. I want to use the kill() method that you find in the flixel.FlxNapeSprite.
When you catch them, you should move them to the correct box, and when they come inside the box, they should get killed, you get points, and a new random light re spawn.
Link to image of the game so far
How do I kill the light-object inside a certain area?
I guess the boxes are FlxNapeSprites as well? Typically you would set up a collision callback here, which is called whenever the hitboxes of two nape bodies overlap (the light and the box in this case). You can display the nape bodies with napeDebugEnabled = true or by pressing the "N" button in the top right of flixel's debugger overlay.
Here's a simple example of how to set up a simple collision callback using Flixel + Nape:
package;
import flixel.addons.nape.FlxNapeSprite;
import flixel.addons.nape.FlxNapeState;
import flixel.util.FlxColor;
import nape.callbacks.CbEvent;
import nape.callbacks.CbType;
import nape.callbacks.InteractionCallback;
import nape.callbacks.InteractionListener;
import nape.callbacks.InteractionType;
import nape.phys.BodyType;
using flixel.util.FlxSpriteUtil;
class PlayState extends FlxNapeState
{
override public function create()
{
super.create();
bgColor = FlxColor.BLACK;
napeDebugEnabled = true;
var light = new Light(10, 10);
var box = new Box(10, 100);
add(light);
add(box);
light.body.velocity.y = 200;
FlxNapeState.space.listeners.add(new InteractionListener(
CbEvent.BEGIN,
InteractionType.COLLISION,
Light.CB_TYPE,
Box.CB_TYPE,
collideLightBox));
}
function collideLightBox(callback:InteractionCallback)
{
var light:Light = cast callback.int1.castBody.userData.sprite;
light.kill();
}
}
class Light extends FlxNapeSprite
{
public static var CB_TYPE(default, null) = new CbType();
public function new(x:Float, y:Float)
{
super(x, y);
makeGraphic(10, 10, FlxColor.TRANSPARENT);
var radius = 5;
drawCircle(5, 5, radius, FlxColor.WHITE);
createCircularBody(radius);
body.cbTypes.add(CB_TYPE);
// we need this to get the Light instance in the callback later
body.userData.sprite = this;
}
}
class Box extends FlxNapeSprite
{
public static var CB_TYPE(default, null) = new CbType();
public function new(x:Float, y:Float)
{
super(x, y);
makeGraphic(100, 50, FlxColor.GREEN);
createRectangularBody(width, height);
body.cbTypes.add(CB_TYPE);
body.type = BodyType.STATIC;
}
}
Be sure to check out the official FlxNape demo. The Nape website also has some very helpful examples + docs.

AS3 Display Objects & Sprites (Adding children based on a random number)

ActionScript 3.0
Essentially I need a function that displays a random number of butterfly objects. (Also I should make a reset function that resets the first function.)
I find though that the butterflies are not even displayed to begin with, It seems that the children are not being added to the stage even though I used the addChild().
Any help is appreciate thanks!
// Random Number
var randomNumber : int = Math.floor(Math.random() * 8);
// New Sprite
var bContainer: Sprite = new Sprite();
this.addChild(bContainer);
var butterfly: MovieClip = new Butterfly();
bContainer.addChild(butterfly);
//Function to Create Butterfly Objects:
function showButterfly(randomNumber:int):void {
while(bContainer.numChildren < randomNumber){
bContainer.addChild(butterfly);
}
//Reset Function, I am not sure about this (especially the second one)
function button(evt:MouseEvent): void {
if(numChildren>0) {
removeChildAt(0);
}
if(numChildren==0) {
showButterfly();
}
}
// Event Listener
button.addEventListener(MouseEvent.MOUSE_DOWN);
//
I'm not completely sure, but aren't you suppose to set the width and height for the sprite that works as a holder object?
var bContainer: Sprite = new Sprite();
bContainer.graphics.beginFill(0xffffff);
bContainer.graphics.drawRect(0, 0,stage.stageWidth, stage.stageHeight);
addChildAt(bContainer, 0);

Drag/Move Multiple Selected Features - OpenLayers

I know that I can easily allow a user to select multiple Features/Geometries in OpenLayers but I then want enable the user to easily drag/move all of the selected features at the same time.
With the ModifyFeature control it only moves one feature at a time ... is there a way to easily extend this control (or whatever works) to move all of the selected features on that layer?
Okay, skip the ModifyFeature control and just hook into the SelectFeature control to keep track of the selected features and then use the DragControl to manipulate the selected points at the same time.
Example of the control instantiation:
var drag = new OpenLayers.Control.DragFeature(vectors, {
onStart: startDrag,
onDrag: doDrag,
onComplete: endDrag
});
var select = new OpenLayers.Control.SelectFeature(vectors, {
box: true,
multiple: true,
onSelect: addSelected,
onUnselect: clearSelected
});
Example of the event handling functions:
/* Keep track of the selected features */
function addSelected(feature) {
selectedFeatures.push(feature);
}
/* Clear the list of selected features */
function clearSelected(feature) {
selectedFeatures = [];
}
/* Feature starting to move */
function startDrag(feature, pixel) {
lastPixel = pixel;
}
/* Feature moving */
function doDrag(feature, pixel) {
for (f in selectedFeatures) {
if (feature != selectedFeatures[f]) {
var res = map.getResolution();
selectedFeatures[f].geometry.move(res * (pixel.x - lastPixel.x), res * (lastPixel.y - pixel.y));
vectors.drawFeature(selectedFeatures[f]);
}
}
lastPixel = pixel;
}
/* Featrue stopped moving */
function endDrag(feature, pixel) {
for (f in selectedFeatures) {
f.state = OpenLayers.State.UPDATE;
}
}
Hmm...
I tried the code above, and couldn't make it work. Two issues:
1) To move each feature, you need to use the original position of that feature, and add the "drag vector" from whatever feature the DragControl is moving around by itself (i.e. the feature-parameter to doDrag).
2) Since DragFeatures own code sets lastPixel=pixel before calling onDrag, the line calling move() will move the feature to (0,0).
My code looks something like this:
var lastPixels;
function startDrag(feature, pixel) {
// save hash with selected features start position
lastPixels = [];
for( var f=0; f<wfs.selectedFeatures.length; f++){
lastPixels.push({ fid: layer.selectedFeatures[f].fid,
lastPixel: map.getPixelFromLonLat( layer.selectedFeatures[f].geometry.getBounds().getCenterLonLat() )
});
}
}
function doDrag(feature, pixel) {
/* because DragFeatures own handler overwrites dragSelected.lastPixel with pixel before this is called, calculate drag vector from movement of "feature" */
var g = 0;
while( lastPixels[g].fid != feature.fid ){ g++; }
var lastPixel = lastPixels[g].lastPixel;
var currentCenter = map.getPixelFromLonLat( feature.geometry.getBounds().getCenterLonLat() );
var dragVector = { dx: currentCenter.x - lastPixel.x, dy: lastPixel.y - currentCenter.y };
for( var f=0; f<layer.selectedFeatures.length; f++){
if (feature != layer.selectedFeatures[f]) {
// get lastpixel of this feature
lastPixel = null;
var h = 0;
while( lastPixels[h].fid != layer.selectedFeatures[f].fid ){ h++; }
lastPixel = lastPixels[h].lastPixel;
var newPixel = new OpenLayers.Pixel( lastPixel.x + dragVector.dx, lastPixel.y - dragVector.dy );
// move() moves polygon feature so that centre is at location given as parameter
layer.selectedFeatures[f].move(newPixel);
}
}
}
I had a similar problem and solved it by overriding DragFeature's moveFeature function and putting this.lastPixel = pixel inside the for loop that applies the move to all features within my layer vector. Until I moved this.lastPixel = pixel inside the loop, all features except the one being dragged got crazily distorted.
`OpenLayers.Control.DragFeature.prototype.moveFeature = function (pixel) {
var res = this.map.getResolution();
for (var i = 0; i < vector.features.length; i++) {
var feature = vector.features[i];
feature .geometry.move(res * (pixel.x - this.lastPixel.x),
res * (this.lastPixel.y - pixel.y));
this.layer.drawFeature(feature );
this.lastPixel = pixel;
}
this.onDrag(this.feature, pixel);
};
`

Help on Removal of Dynamically Created sprites

import flash.display.Sprite;
import flash.net.URLLoader;
var index:int = 0;
var constY = 291;
var constW = 2;
var constH = 40;
hydrogenBtn.label = "Hydrogen";
heliumBtn.label = "Helium";
lithiumBtn.label = "Lithium";
hydrogenBtn.addEventListener (MouseEvent.CLICK, loadHydrogen);
heliumBtn.addEventListener (MouseEvent.CLICK, loadHelium);
lithiumBtn.addEventListener (MouseEvent.CLICK, loadLithium);
var myTextLoader:URLLoader = new URLLoader();
myTextLoader.addEventListener(Event.COMPLETE, onLoaded);
function loadHydrogen (event:Event):void {
myTextLoader.load(new URLRequest("hydrogen.txt"));
}
function loadHelium (event:Event):void {
myTextLoader.load(new URLRequest("helium.txt"));
}
function loadLithium (event:Event):void {
myTextLoader.load(new URLRequest("lithium.txt"));
}
var DataSet:Array = new Array();
var valueRead1:String;
var valueRead2:String;
function onLoaded(event:Event):void {
var rawData:String = event.target.data;
for(var i:int = 0; i<rawData.length; i++){
var commaIndex = rawData.search(",");
valueRead1 = rawData.substr(0,commaIndex);
rawData = rawData.substr(commaIndex+1, rawData.length+1);
DataSet.push(valueRead1);
commaIndex = rawData.search(",");
if(commaIndex == -1) {commaIndex = rawData.length+1;}
valueRead2 = rawData.substr(0,commaIndex);
rawData = rawData.substr(commaIndex+1, rawData.length+1);
DataSet.push(valueRead2);
}
generateMask_Emission(DataSet);
}
function generateMask_Emission(dataArray:Array):void{
var spriteName:String = "Mask"+index;
trace(spriteName);
this[spriteName] = new Sprite();
for (var i:int=0; i<dataArray.length; i+=2){
this[spriteName].graphics.beginFill(0x000000, dataArray[i+1]);
this[spriteName].graphics.drawRect(dataArray[i],constY,constW, constH);
this[spriteName].graphics.endFill();
}
addChild(this[spriteName]);
index++;
}
Hi, I am relatively new to flash and action script as well and I am having a problem getting the sprite to be removed after another is called. I am making emission spectrum's of 3 elements by dynamically generating the mask over a picture on the stage. Everything works perfectly fine with the code I have right now except the sprites stack on top of each other and I end up with bold lines all over my picture instead of a new set of lines each time i press a button.
I have tried using try/catch to remove the sprites and I have also rearranged the entire code from what is seen here to make 3 seperate entities (hoping I could remove them if they were seperate variables) instead of 2 functions that handle the whole process. I have tried everything to the extent of my knowledge (which is pretty minimal # this point) any suggestions?
Thanks ahead of time!
My AS3 knowledge is rather rudimentary right now but I think two things may help you.
You could use removeChild before recreating the Sprite. Alternatively, just reuse the Sprite.
Try to add this[spriteName].graphics.clear(); to reset the sprite and start redrawing.
function generateMask_Emission (dataArray : Array) : void {
var spriteName:String = "Mask"+index;
trace(spriteName);
// Don't recreate if sprite object already created
if (this[spriteName] == null)
{
this[spriteName] = new Sprite();
// Only need to add sprite to display object once
addChild(this[spriteName]);
}
for (var i:int= 0; i < dataArray.length; i+=2)
{
this[spriteName].graphics.clear();
this[spriteName].graphics.beginFill(0x000000, dataArray[i+1]);
this[spriteName].graphics.drawRect(dataArray[i],constY,constW, constH);
this[spriteName].graphics.endFill();
}
index++;
}
Just in case anyone was curious or having a similar problem. Extremely simple fix but here is what I did.
Also should mention that I don't think that the graphics.clear function actually fixed the problem (though I didn't have the sprite being cleared properly before), but I believe the problem lies in the beginning of the onloaded function where 3 of those variables used to be outside of the function.
import flash.display.Sprite;
import flash.net.URLLoader;
import flash.events.Event;
var constY = 291; //this value represets the Y value of the bottom of the background spectrum image
var constW = 2; //this value represents the width of every emission line
var constH = 40; //this value represents the height of every emission line
//Create Button Labels
hydrogenBtn.label = "Hydrogen";
heliumBtn.label = "Helium";
lithiumBtn.label = "Lithium";
//These listen for the buttons to be clicked to begin loading in the data
hydrogenBtn.addEventListener (MouseEvent.CLICK, loadHydrogen);
heliumBtn.addEventListener (MouseEvent.CLICK, loadHelium);
lithiumBtn.addEventListener (MouseEvent.CLICK, loadLithium);
var myTextLoader:URLLoader = new URLLoader();//the object to load in data from external files
myTextLoader.addEventListener(Event.COMPLETE, onLoaded);//triggers the function when the file is loaded
var Mask:Sprite = new Sprite(); //This sprite will hold the information for the spectrum to be put on stage
function loadHydrogen (event:Event):void {
myTextLoader.load(new URLRequest("hydrogen.txt"));//starts loading Hydrogen emisson data
}
function loadHelium (event:Event):void {
myTextLoader.load(new URLRequest("helium.txt"));//starts loading Helium emission data
}
function loadLithium (event:Event):void {
myTextLoader.load(new URLRequest("lithium.txt"));//starts loading Lithium emission data
}
function onLoaded(event:Event):void {//the function that handles the data from the external file
var rawData:String = event.target.data; //create a new string and load in the data from the file
var DataSet:Array = new Array();//the array to load values in to
var valueRead1:String; //subset of array elements (n)
var valueRead2:String; //subset of array elements (n+1)
for(var i:int = 0; i<rawData.length; i++){ //loop through the string and cut up the data # commas
var commaIndex = rawData.search(",");
valueRead1 = rawData.substr(0,commaIndex);
rawData = rawData.substr(commaIndex+1, rawData.length+1);
DataSet.push(valueRead1);
commaIndex = rawData.search(",");
if(commaIndex == -1) {commaIndex = rawData.length+1;}
valueRead2 = rawData.substr(0,commaIndex);
rawData = rawData.substr(commaIndex+1, rawData.length+1);
DataSet.push(valueRead2);
}
generateMask_Emission(DataSet);//call the generateMaskEmission function on new data to fill emission lines
}
//This function loops through an array, setting alternating values as locations and alphas
function generateMask_Emission(dataArray:Array):void{
Mask.graphics.clear(); //Clears the Mask sprite for the next set of values
addChild(Mask); //Adds the blank sprite in order to clear the stage of old sprites
//This loop actually draws out how the sprite should look before it is added
for (var i:int=0; i<dataArray.length; i+=2){
Mask.graphics.beginFill(0x000000, dataArray[i+1]);
Mask.graphics.drawRect(dataArray[i],constY,constW, constH);
Mask.graphics.endFill();
}
addChild(Mask);// actually adds the mask we have created to the stage
}

Resources