Bullet spawn speed or generation speed phaser - phaser-framework

Hi all I have a function that generates bullets every time the player touches the screen.
Is there a way that I can limit the amount of bullets generated? Basically if I press the screen very quickly lots of bullets get generated but I would like to limit it to at least i per second instead of 2 or 3 per second.
Below you can find my firing function and my bullet creation function:
createBullets: function(){
//Bullets
this.bullets = this.add.group();
this.bullets.enableBody = true;
this.bullets.physicsBodyType = Phaser.Physics.P2JS;
this.bullets.createMultiple(500, 'bullet', 0, false);
this.bullets.setAll('anchor.x', 0.5);
this.bullets.setAll('anchor.y', 0.5);
this.bullets.setAll('outOfBoundsKill', true);
this.bullets.setAll('checkWorldBounds', true);
},
fireBullet: function(){
this.bullet = this.bullets.getFirstExists(false);
if (this.bullet) {
this.bullet.reset(this.tanque.x, this.tanque.y - 20);
this.bullet.body.velocity.y = -500;
}
},
and my update function:
if(this.input.activePointer.isDown){
if (!this.mouseTouchDown) {
this.touchDown();
}
}else {
if (this.mouseTouchDown) {
this.touchUp();
}
}
Any help I would really appreciate.

One option is to store two values:
nextShotTime: next time a shot can be fired
shotDelay: delay between shots (can be set like Phaser.Timer.SECOND * 2)
I don't see where you're calling fireBullet() in your example code above, but either before you make the call, or within the function, you could then check to see if the nextShotTime is in the past. If it is, fire another bullet and then update the nextShotTime with the current time plus the shotDelay.
For example:
if (this.nextShotTime < this.time.now) {
this.nextShotTime = this.time.now + this.shotDelay;
// add your code that will fire a bullet.
}

I have had similar problems in games before. The solution I used is the same as the one posted above. I found it in this
Phaser tutorial.
The fire function used in the tutorial is:
fire: function() {
if (this.nextShotAt > this.time.now) {
return;
}
this.nextShotAt = this.time.now + this.shotDelay;
You can modify it to suit your purposes.
This is part of a fire function I used in a game I made:
fire: function() {
//Make sure the player can't shoot when dead and that they are able to shoot another bullet
if(!this.player.alive || this.time.now < this.nextFireTime) {
return;
}
this.nextFireTime = this.time.now + this.fireRate;
var bullet;
//If weaponlvl = 0, shoot a normal bullet
if(this.weaponlvl === 0) {
if(this.bullet1.countDead() === 0) {
return;
}
//Properties for the basic weapon
this.fireRate = 500;
bullet = this.bullet1.getFirstExists(false);
bullet.reset(this.player.x, this.player.y-22);
bullet.body.velocity.y = -300;
}
Hope this helps you in some way.

Related

Dodge Effect Fix? (FNF Psych Engine)

case 'Dodge': //hahahahahahahaha beat that demo
new FlxTimer().start(0.1, function(tmr:FlxTimer)
{
var warning = new FlxText(0, 0, 0, 'Press Space Bar Now!', 32);
warning.cameras = [camOther];
warning.setFormat(Paths.font("vcr.ttf"), 24, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
warning.screenCenter(X);
warning.size = 50;
warning.screenCenter(Y);
warning.updateHitbox();
add(warning);
});
new FlxTimer().start(0.6, function(tmr:FlxTimer)
{
if (FlxG.keys.justPressed.SPACE)
{
health = 1;
boyfriend.playAnim('dodge', true); //woosh
FlxG.sound.play(Paths.sound('dodge')); //stab
remove(warning);
warning.destroy();
}
else {
health -= 2;
vocals.volume = 0;
doDeathCheck(true); //dead noises
};
});
so it does it but it wont detect space bar being hit
i need it so it will detect the space bar being hit
i am not sure what i did wrong or what i did but it just goes to game over
I would Use lua ( not using source ) Since there is no offical event sorry im a Psych engine nerd- I made 2 engines so i would say make a lua event with it

How to get nearest PositionComponent in a good way?

I have a "player" and several "enemy" beside:
Now I just use a loop to get every distance:
void fireBullet() {
var enemies = gameRef.children.whereType<Enemy>();
if (enemies.isEmpty) return;
PositionComponent nearestEnemy = enemies.first;
enemies.forEach((element) {
if (element.distance(playerComponent) < nearestEnemy.distance(playerComponent)) {
nearestEnemy = element;
}
});
// fire bullet to enemy
}
I think it's not the best solution. If there's too many enemy, performance will degrade.
Is there any better way to get nearest PositionComponent?
There is no better built-in method unfortunately.
There are a few improvements that you can do to your game though that will make a big performance difference:
Use distance2, because then it won't have to do a square root operation behind the scenes.
Save the last distance calculation to avoid doing it twice.
Use query instead of whereType (the query is cached).
So it would be something like this:
void fireBullet() {
var enemies = gameRef.children.query<Enemy>();
if (enemies.isEmpty) return;
var nearestEnemy = enemies.first;
var nearestDistance = nearestEnemy.position.distance2(playerComponent);
enemies.forEach((element) {
final distance = element.position.distance2(playerComponent.position);
if (distance < distanceNearest) {
nearestEnemy = element;
nearestDistance = distance;
}
});
// fire bullet to enemy
}
I believe that you would have other performance issues before you hit performance issues with this code in the updated state.

How to improve canvas fabric.js performance with large number of Objects

I need make an App that has about 30k Objects, a user can Pan, Zoom or "Select on click" any of those objects.
Fabric.js Canvas is being used
I have done the same using SVG's and the svg-pan-zoom plugin (no Canvas Element) with better results
Problem: there is a significant Lag while Zooming, Panning or Object on Click
will removing Fabric.js improve performance?
will switching to WebGL improve performance?
Have tried Fabric specific options
fabric.Object.prototype.objectCaching = false;
fabric.Object.prototype.statefullCache = false;
fabric.Object.prototype.noScaleCache = true;
fabric.Object.prototype.needsItsOwnCache = false;
UPDATE
Heres the updated Fiddle
for reference :
canvas-vs-svg-vs-div Stackoverflow
Stackoverflow
Don't Render in IO EVENTS!
Though not a complete fix to the update speed this answer will about double the interaction speed.
A common, almost standard, mistake made with mouse and event interaction with the canvas (and DOM) is to delegate rendering to mouse/touch events. This is very bad practice as mouse events fire at much higher rates than the display can display. It becomes worse when your rendering time is high as you queue up mouse events (pseudo render events) and do a re render for every movement of the mouse
Note blocking code will stop mouse events but as soon as the engine is idle the mouse will start firing at full rate again.
Use the mouse events just to get the mouse state. Use an animation loop that is synced to the display to render only when needed and there is time available. Things like the wheel and mouse movement deltas should be recorded cumulatively.
mouse.dx += event.movementX;
mouse.dy += event.movementY;
mouse.wheel += event.wheelDelta;
And consume them in the main render loop...
function update(){
// ... code to use mouse
// consume deltas
mouse.x = mouse.y = mouse.wheel = 0;
...this ensures that the mouse state is accurately followed when you may have many mouse events between render updates.
Example, separating events from rendering.
Change you code in the fiddle you provided to the following, on my machine it about doubled the rendering speed (which is still very slow).
// from just after the function applyZoom replace all the code
var mouse = { // holds the mouse state
x : 0,
y : 0,
down : false,
w : 0,
delta : new fabric.Point(0,0),
}
// event just track mouse state
function zoom(e) {
if(e != null) { e.preventDefault() }
var evt=window.event || e;
mouse.x = e.offsetX;
mouse.y = e.offsetY;
mouse.w += evt.detail? evt.detail*(-120) : evt.wheelDelta;
return false;
}
canvas.on('mouse:up', function (e) { mouse.down = false });
canvas.on('mouse:out', function (e) { mouse.down = false });
canvas.on('mouse:down', function (e) { mouse.down = true });
canvas.on('mouse:move', function(e) {
if (e && e.e) {
mouse.delta.x += e.e.movementX;
mouse.delta.y += e.e.movementY;
}
});
// main animation loop
function update(){
if(mouse.w !== 0){ // if the wheel has moved do zoom
var curZoom = canvas.getZoom();
canvas.zoomToPoint(
{ x : mouse.x, y: mouse.y },
canvas.getZoom() + mouse.w / 4000
);
mouse.w = 0; // consume wheel delta
}else if(mouse.down) { // if mouse button down
canvas.relativePan(mouse.delta);
}
// consume mouse delta
mouse.delta.x = 0;
mouse.delta.y = 0;
requestAnimationFrame(update);
}
requestAnimationFrame(update);

Phaser P2 Collision

I'm trying to have my bullets group that already collides with the enemies, both of them are a group, but now that I want to add a static block or obstacle, it simply wont collide or overlap or nothing, what I want is that when the bullet collides or overlaps it gets destroyed or at least bounce into the obstacle, see code below:
////////////////My Bullets//////////These work fine and collide correctly with my enemies.//////
createBullets: function() {
this.bullets = this.game.add.group();
this.bullets.enableBody = true;
this.bullets.physicsBodyType = Phaser.Physics.P2JS;
this.bullets.createMultiple(100, 'bulletSprite', 0, false);
this.bullets.setAll('anchor.x', 0.5);
this.bullets.setAll('anchor.y', 0.5);
this.bullets.setAll('outOfBoundsKill', true);
this.bullets.setAll('checkWorldBounds', true);
},
fireBullet: function(){
if (this.bulletTimer < this.game.time.time) {
this.bulletTimer = this.game.time.time + 500;
this.bullet = this.bullets.getFirstExists(false);
if (this.bullet) {
this.bullet.reset(this.tanke.x, this.tanke.y - 20);
this.bullet.body.setCollisionGroup(this.bulletCG);
this.bullet.body.collides([this.figuraCG]);
this.bullet.body.velocity.y = -3500;
}
}
},
//////This is the block or obstacle this just wont work no matter what I try///////////
makeOneBloque: function(){
this.bloque = this.game.add.sprite(500, 950, 'Blokes');
this.bloque.enableBody = true;
this.game.physics.p2.enable(this.bloque, true);
this.bloque.body.kinematic = true;
this.bloque.body.collides(this.bullets, this.collisionBulletBloque, this); //////I tried overlaps and it just crashes the lvl
},
collisionBulletBloque: function(bullet) {
bullet.sprite.destroy();
},
Any Help would be greatly appreciated.
////Try this on this part use it like so Im not shure If it'll work havent tried it myself with your code but give it a shoot and let me know!
game.physics.arcade.overlap(this.bloque.body.collides, this.bullets, this.collisionBulletBloque, null, this);
//////I tried overlaps and it just crashes the lvl

How to snap a polyline to a road with walking travelmode in Google Maps?

II want an user to draw a route with polylines on GoogleMaps. I've found a way to snap a polyline ( example in the link, code in below ). The code works with the directions service to draw a polyline on a road, the only problem is this only works with G_TRAVELMODE_DRIVING but I want to use G_TRAVELMODE_WALKING and when you use WALKING you have to supply the map and a div in the constructor of the directions object. When I do that it automatically removes the last line and only displays the current line. I've tried several things like supplying the map as null, or leaving out the map in the constructor.. I've also tried to give a second map in the constructor, get the polylines from the directions service and display them on the right map. But nothing works! I'd appreciate it if someone could help me!
http://econym.org.uk/gmap/example_snappath.htm
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(53.7877, -2.9832),13)
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
var dirn = new GDirections();
var firstpoint = true;
var gmarkers = [];
var gpolys = [];
var dist = 0;
GEvent.addListener(map, "click", function(overlay,point) {
// == When the user clicks on a the map, get directiobns from that point to itself ==
if (!overlay) {
if (firstpoint) {
dirn.loadFromWaypoints([point.toUrlValue(6),point.toUrlValue(6)],{getPolyline:true});
} else {
dirn.loadFromWaypoints([gmarkers[gmarkers.length-1].getPoint(),point.toUrlValue(6)],{getPolyline:true});
}
}
});
// == when the load event completes, plot the point on the street ==
GEvent.addListener(dirn,"load", function() {
// snap to last vertex in the polyline
var n = dirn.getPolyline().getVertexCount();
var p=dirn.getPolyline().getVertex(n-1);
var marker=new GMarker(p);
map.addOverlay(marker);
// store the details
gmarkers.push(marker);
if (!firstpoint) {
map.addOverlay(dirn.getPolyline());
gpolys.push(dirn.getPolyline());
dist += dirn.getPolyline().Distance();
document.getElementById("distance").innerHTML="Path length: "+(dist/1000).toFixed(2)+" km. "+(dist/1609.344).toFixed(2)+" miles.";
}
firstpoint = false;
});
GEvent.addListener(dirn,"error", function() {
GLog.write("Failed: "+dirn.getStatus().code);
});
}
else {
alert("Sorry, the Google Maps API is not compatible with this browser");
}
I know it's an old post, but since no answer came forward and I've recently been working on this sort of code (and got it working), try swapping the addListener with this.
GEvent.addListener(map, "click", function(overlay,point) {
// == When the user clicks on a the map, get directiobns from that point to itself ==
if (!overlay) {
if (firstpoint) {
dirn1.loadFromWaypoints([point.toUrlValue(6),point.toUrlValue(6)],{ getPolyline:true,travelMode:G_TRAVEL_MODE_WALKING});
} else {
dirn1.loadFromWaypoints([gmarkers[gmarkers.length-1].getPoint(),point.toUrlValue(6)],{ getPolyline:true,travelMode:G_TRAVEL_MODE_WALKING});
}
}
});

Resources