Disclaimer: I am still learning some of the basics and I am still learning proper terminology.
I am trying to use an example of amCharts with live data and add another series into the chart. My goal is to have a single chart with two series/lines streaming data.
The basic example I am working from is here:
https://codepen.io/team/amcharts/pen/MGVbNV
I have managed to get two line series working, however its extremely clunky at the moment.
Here is where I am at:
am4core.useTheme(am4themes_animated);
am4core.useTheme(am4themes_dark);
var chart = am4core.create("chartdiv", am4charts.XYChart);
chart.hiddenState.properties.opacity = 0;
chart.padding(0, 0, 0, 0);
chart.zoomOutButton.disabled = true;
var data = [];
var upstream = 10;
var i = 0;
for (i = 0; i <= 30; i++) {
upstream -= Math.round((Math.random() < 0.5 ? 1 : -1) * Math.random() * 10);
data.push({ date: new Date().setSeconds(i - 30), Upstream: upstream });
}
var downstream = 10;
var j = 0;
for (j = 0; j <= 30; j++) {
downstream -= Math.round((Math.random() < 0.5 ? 1 : -1) * Math.random() * 10);
data.push({ date: new Date().setSeconds(j - 30), value: downstream });
}
chart.data = data;
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.grid.template.location = 0;
dateAxis.renderer.minGridDistance = 30;
dateAxis.dateFormats.setKey("second", "ss");
dateAxis.periodChangeDateFormats.setKey("second", "[bold]h:mm a");
dateAxis.periodChangeDateFormats.setKey("minute", "[bold]h:mm a");
dateAxis.periodChangeDateFormats.setKey("hour", "[bold]h:mm a");
dateAxis.renderer.inside = true;
dateAxis.renderer.axisFills.template.disabled = true;
dateAxis.renderer.ticks.template.disabled = true;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.tooltip.disabled = true;
valueAxis.interpolationDuration = 500;
valueAxis.rangeChangeDuration = 500;
valueAxis.renderer.inside = true;
valueAxis.renderer.minLabelPosition = 0.05;
valueAxis.renderer.maxLabelPosition = 0.95;
valueAxis.renderer.axisFills.template.disabled = true;
valueAxis.renderer.ticks.template.disabled = true;
var series1 = chart.series.push(new am4charts.LineSeries());
series1.dataFields.dateX = "date";
series1.dataFields.valueY = "Upstream";
series1.interpolationDuration = 500;
series1.defaultState.transitionDuration = 0;
series1.tensionX = 0.8;
var series2 = chart.series.push(new am4charts.LineSeries());
series2.dataFields.dateX = "date";
series2.dataFields.valueY = "Downstream";
series2.interpolationDuration = 500;
series2.defaultState.transitionDuration = 0;
series2.tensionX = 0.8;
chart.events.on("datavalidated", function () {
dateAxis.zoom({ start: 1 / 15, end: 1.2 }, false, true);
});
dateAxis.interpolationDuration = 500;
dateAxis.rangeChangeDuration = 500;
document.addEventListener("visibilitychange", function() {
if (document.hidden) {
if (interval) {
clearInterval(interval);
}
}
else {
startInterval();
}
}, false);
// add data
var interval;
function startInterval() {
interval = setInterval(function() {
upstream =
upstream + Math.round((Math.random() < 0.5 ? 1 : -1) * Math.random() * 5);
var lastdataItem = series1.dataItems.getIndex(series1.dataItems.length - 1);
chart.addData(
{ date: new Date(lastdataItem.dateX.getTime() + 1000), Upstream: upstream },
1
);
downstream =
downstream + Math.round((Math.random() < 0.5 ? 1 : -1) * Math.random() * 1);
var lastdataItem = series2.dataItems.getIndex(series2.dataItems.length - 1);
chart.addData(
{ date: new Date(lastdataItem.dateX.getTime() + 1000), Downstream: downstream },
1
);
}, 1000);
}
startInterval();
// all the below is optional, makes some fancy effects
// gradient fill of the series
series1.fillOpacity = 1;
var gradient = new am4core.LinearGradient();
gradient.addColor(chart.colors.getIndex(0), 0.2);
gradient.addColor(chart.colors.getIndex(0), 0);
series1.fill = gradient;
// this makes date axis labels to fade out
dateAxis.renderer.labels.template.adapter.add("fillOpacity", function (fillOpacity, target) {
var dataItem = target.dataItem;
return dataItem.position;
})
// need to set this, otherwise fillOpacity is not changed and not set
dateAxis.events.on("validated", function () {
am4core.iter.each(dateAxis.renderer.labels.iterator(), function (label) {
label.fillOpacity = label.fillOpacity;
})
})
// this makes date axis labels which are at equal minutes to be rotated
dateAxis.renderer.labels.template.adapter.add("rotation", function (rotation, target) {
var dataItem = target.dataItem;
if (dataItem.date.getTime() == am4core.time.round(new Date(dataItem.date.getTime()), "minute").getTime()) {
target.verticalCenter = "middle";
target.horizontalCenter = "left";
return -90;
}
else {
target.verticalCenter = "bottom";
target.horizontalCenter = "middle";
return 0;
}
})
// bullet at the front of the line
var bullet = series1.createChild(am4charts.CircleBullet);
bullet.circle.radius = 5;
bullet.fillOpacity = 1;
bullet.fill = chart.colors.getIndex(0);
bullet.isMeasured = false;
series1.events.on("validated", function() {
bullet.moveTo(series1.dataItems.last.point);
bullet.validatePosition();
});
Any insight and help on getting this to be smoother? I think I need to do something with SetInterval() or combine functions somehow.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Fist time i am using phaser.io, i am repeating background and also loading other thing in update function but after few second later my game is slowing time . it look like background is not moving more. Please have a look of my code and help me in for sort out this problem. Or please give any idea to change background repeatedly without changing other thing.
I have some code indentation problem sorry for that but please try to manage and help me.
Game.js
var scoreTxt, score, speed, scoreTextValue, ques_label, ques_label_pizza, scoreTextKey, timerTextValue, timerTextKey, textStyle_Key, textStyle_Value, anscloud, astroid1, astroid2, astroid3, astroid4;
/*var gameType;*/ //Pizza or Noun
var bullets, quesTextValue, ansTextValue, sprite;
var fireRate = 100;
var nextFire = 0;
var xAxis = [];
var yAxis = [];
var tempQues = [];
var tempAns = [];
var result = [];
var answear = [];
var ques = [];
var astroidContains = [];
var astroidContainsText = []; //['right', 'wrong', 'wrong', 'wrong']
var astroid, spaceShip, quesbar, diamond, randomAnsPosition;
var s1Copy;
var cloudContains = []; //['noun', 'pronoun', 'pronoun']
var QbarContainsQue = [];
var ans,rightans;
var isAnswerCorrect = false;
var allowClick = false;
var spaceShipXAxis = 40, loader1Width = 85, loader2Width = 70;
var bar, loader1, loader2, timer, timerSprite, timerSpriteCount = 0;
var timerCounter = 45; //timer counter will be of 45 seconds.
//var timerCounter_ = 100; //timer counter will be of 45 seconds.
var questCounter = 0; //question counter no. of question played.
var maxQuest = 10;//max questions will be displayed is 10.
var diamondTextColor = "#8D4FA8";
var defTextColor = "#5BEFFE";
var ansTextColor = "#9E13DA";
var errTextColor = '#FF0000';
var corrTextColor = '#228B22';
var corr_ans_fst;
var corr_ans_sec;
var fun_bckg, randQues;
var wrong_ans;
var barre1_x = 150;
var barre1_y = 115;
var healthValue = 100;
var x_loader = 180;
var check =0;
var setAns = [];
var setOne = [['12+16=','28'], ['15+11=','26'], ['16+22=','38'], ['13+14=','27'], ['15+24=','39'], ['14+12=','26'], ['10+17=','27'], ['11+11=','22'],
['13+15=','28'], ['12+21=','33'], ['24+13=','37'], ['33+21=','54'], ['40+18=','58'], ['34+31=','65'], ['25+42=','67'], ['22+15=','37'],
['24+12=','36'], ['20+15=','35'], ['25+14=','39'], ['21+21=','42'], ['41+25=','66'], ['53+24=','77'], ['35+31=','66'], ['62+37=','99'],
['54+35=','89']];
var setTwo = [['15+18=','33'], ['17+17=','34'], ['13+19=','32'], ['18+14=','32'], ['15+27=','42'], ['18+17=','35'], ['27+29=','56'], ['23+28=','51'],
['36+37=','73'], ['45+25=','70'], ['46+45=','91'], ['38+57=','95'], ['49+43=','92'], ['37+53=','90'], ['48+33=','81']];
var Game = {
preload : function() {
// Load the needed image for this(play) game screen.
//load the menu screen
this.load.image('menu', './assets/images/menu.png');
// Here we load all the needed resources for the level.
// background image screen
this.load.image('playgame', './assets/images/back.png');
// globe image screen
this.load.image('playgame', './assets/images/back.png');
// win image screen
//this.load.image('win', './assets/images/win.png');
// spaceship image screen
this.load.image('spaceship', './assets/images/spaceship.png');
// Question bar image screen
this.load.image('quesbar', './assets/images/quesbar.png');
// Diamond image screen
this.load.image('diamond', './assets/images/diamond.png');
// Astroid image screen
this.load.image('astroid1', 'assets/images/asteroid1.png');
this.load.image('astroid2', 'assets/images/asteroid2.png');
this.load.image('astroid3', 'assets/images/asteroid3.png');
this.load.image('astroid4', 'assets/images/asteroid4.png');
// Loader image screen
this.load.image('loaderbck', 'assets/images/loaderbck.png');
this.load.image('loader1', 'assets/images/loader1.png');
this.load.image('loader2', 'assets/images/loader2.png');
//Load the bullet
this.load.image('bullet', 'assets/images/bullet.png');
},
create : function() {
// By setting up global variables in the create function, we initialise them on game start.
// We need them to be globally available so that the update function can alter them.
textStyle_Value = { font: "bold 20px Segoe UI", fill: defTextColor, align: "center" };
textStyleAns = { font: "bold 22px 'Comic Sans MS', 'Comic Sans'", fill: ansTextColor, wordWrap: true, wordWrapWidth: 10, align: "center"};
textStyleQues = { font: "bold 20px 'Comic Sans MS', 'Comic Sans'", fill: defTextColor, wordWrap: true, wordWrapWidth: 10, align: "center"};
sprite = game.add.sprite(310, 485, 'spaceship');
sprite.anchor.set(0.5);
// Loading backround image
this.playBackground();
this.playBackground1();
// Additional Sprites, like cloud
this.addSprites();
// Loading spaceship image
//this.spaceship();
// Loading questionbar image
this.questionbar();
// Call fun. for ques
this.comeQus();
// csll fun. for place astroid
// this.astroid();
// call fun. for Ans
this.generateQues();
this.generateAns();
// Loading Diamond image
this.diamond();
// Start timer
this.startTimer();
// Set timer.
this.setTimer();
this.initLoader();
},
update: function() {
// The update function is called constantly at a high rate (somewhere around 60fps),
// updating the game field every time - also destroying previous objects and creating new.
// Our bullet group
//bullets.destroy();
sprite.destroy();
bullets = game.add.group();
bullets.enableBody = true;
bullets.physicsBodyType = Phaser.Physics.ARCADE;
bullets.createMultiple(200, 'bullet', 100, false);
bullets.setAll('anchor.x',0);
bullets.setAll('anchor.y', 0.9);
bullets.setAll('outOfBoundsKill', true);
bullets.setAll('checkWorldBounds', true);
//Repeating background..
if(playgame != null && playgame.body.y > 600) {
playgame.destroy();
this.playBackground();
}
if(playgame1.body.y > 0) {
playgame1.destroy();
this.playBackground1();
this.initLoader();
}
if(astroid1 != undefined) astroid1.destroy();
if(astroid2 != undefined) astroid2.destroy();
if(astroid3 != undefined) astroid3.destroy();
if(astroid4 != undefined) astroid4.destroy();
this.addSprites();
//timerTextValue.text = "00:" + timerCounter;
this.initLoader();
//destroing old diamond obj and creating new while change background
//diamond.destroy();
this.diamond();
//destroing old questionbar obj and creating new while change background
quesbar.destroy();
this.questionbar();
//Call comeQus, comeAns for show ques and ans at every background change
// quesTextValue.destroy();
if(quesTextValue != undefined) quesTextValue.destroy();
this.comeQus();
//ansTextValue.destroy();
if(ansTextValue != undefined) ansTextValue.destroy();
this.comeAns();
if (game.input.activePointer.isDown) {
this.fire();
}
allowClick = true;
},
playBackground: function() {
// console.log("playBackground called");
playgame = this.add.sprite(0, 0, 'playgame', 5);
playgame.scale.set(1);
playgame.smoothed = false;
anim_playgame = playgame.animations.add('walk');
anim_playgame.play(10, true);
this.physics.enable(playgame, Phaser.Physics.ARCADE);
playgame.body.velocity.y = 50;
},
playBackground1: function() {
//console.log("playBackground1 called");
//Second background..
playgame1 = this.add.sprite(0, -600, 'playgame', 5);
playgame1.scale.set(1);
playgame1.smoothed = false;
anim_playgame1 = playgame1.animations.add('walk');
anim_playgame1.play(10, true);
this.physics.enable(playgame1, Phaser.Physics.ARCADE);
playgame1.body.velocity.y = 50;
},
questionbar: function() {
quesbar = game.add.image(10, 530, 'quesbar');
},
diamond: function() {
diamond = game.add.image(680, 20, 'diamond');
},
addSprites: function() {
// loading answer cloud
astroid1 = this.add.button(30, 90, 'astroid1', this.astroidClicked, this);
astroid2 = this.add.button(220, 30, 'astroid2', this.astroidClicked, this);
astroid3 = this.add.button(400, 40, 'astroid3', this.astroidClicked, this);
astroid4 = this.add.button(600, 90, 'astroid4', this.astroidClicked, this);
},
inCorrectAnswerHit: function(index) {
allowClick = false;
isAnswerCorrect = false;
//this.playFx('wrong_ans');
for(i=0; i<=3; i++) {
if(cloudContains[i] == "right") {
//cloudContainsText[i].fill = corrTextColor;
console.log("right ans hit");
break;
}
}
},
checkAnswer: function(index) {
// If clicked Ans is right so astroid will destroy.
if(astroidContainsText[index] == "wrong") {
//Here collization function will call
isAnswerCorrect = true;
}
// If clicked word is noun (correct answer) and obstacle is redbird or blackbird - the dude will slide.
else {
this.inCorrectAnswerHit(index);
}
},
generateQues: function(){
var que;
// Generating random questions from given list of ques - setOne.
s1Copy = setOne.slice();
//var result = [];
for (var i = 0; i < 3; i++) {result.push(s1Copy.splice(~~(Math.random()*s1Copy.length),1)[0]);}
s1Copy.push(...setTwo);
for (var i = 0; i < 7; i++) {result.push(s1Copy.splice(~~(Math.random()*s1Copy.length),1)[0]);}
result.toString();
for(var i = 0; i < result.length ; i++ ) {
que = result[i];
ques.push(que[0]);
ques.toString();
//console.log(ques);
answear.push(que[1]);
}
},
comeQus: function() {
quesTextValue = this.add.text(50,541, ques[0],textStyleQues);
this.generateQues();
//tempNoun = [];
},
generateAns: function() {
//Generate two digitd rendom no. and create an array of ans setAns[]
// Add digitd in array
for(var i = 0; i < 3 ; i++) {
var digit = Math.floor(Math.random() * 90 + 10);
//console.log(digit);
setAns.push(digit);
astroidContains[i] = "wrong";
}
console.log(astroidContains);
//console.log(answear);
setAns.push(answear[0]);
astroidContains[i] = "right";
console.log(astroidContains);
shuffle(setAns);
randomAnsPosition = [0, 1, 2, 3];
shuffle(randomAnsPosition);
},
comeAns: function() {
// x and y axis param for placing Answers text.
xAxis = [ 85, 255, 453, 675];
yAxis = [130, 48, 60, 120];
// console.log(setAns);
// Set Answers from above array of Ans - setAns.
for (var i = 0; i < setAns.length; i++) {
var ans = setAns[i];
//console.log(ans);
ansTextValue = this.add.text(xAxis[randomAnsPosition[i]], yAxis[randomAnsPosition[i]], ans, textStyleAns);
astroidContainsText[i] = ansTextValue;
//console.log(ansTextValue.text);
}
},
// Observing which cloud is clicked and checking answer accordingly.
astroidClicked: function() {
// alert("HEllo called");
if(!allowClick) {
return;
}
if(astroid1.game.input._x > 85 && astroid1.game.input._x < 130) {
console.log("cloud_1_Clicked, Clicked:" + astroidContains[0]);
this.checkAnswer(0);
}
else if(astroid2.game.input._x > 255 && astroid2.game.input._x < 48) {
//console.log("cloud_2_Clicked, Clicked:" + astroidContains[1]);
this.checkAnswer(1);
}
else if(astroid3.game.input._x > 453 && astroid3.game.input._x < 60) {
//console.log("cloud_3_Clicked, Clicked:" + astroidContains[2]);
this.checkAnswer(2);
}
else if(astroid4.game.input._x > 675 && astroid4.game.input._x < 120) {
//console.log("cloud_3_Clicked, Clicked:" + astroidContains[2]);
this.checkAnswer(3);
}
allowClick = false;
},
startTimer: function() {
// Create our Timer
timer = game.time.create(false);
// Set a TimerEvent to occur after 1 seconds
timer.loop(1000, this.updateCounter, this);
// Set a TimerEvent to occur after 1 seconds
// timer.loop(100, this.timerStripeChange, this);
// Start the timer running - this is important!
// It won't start automatically, allowing you to hook it to button events and the like.
timer.start();
},
gameOver: function() {
//Gameover screen
this.state.start('Game_Over', true, false);
},
initLoader: function() {
//*******Loader
check +=1;
var bmd = this.game.add.bitmapData(185, 30);
bmd.ctx.beginPath();
bmd.ctx.rect(0, 0, 185, 36);
bmd.ctx.fillStyle = '#00685e';
bmd.ctx.fill();
var bglife = this.game.add.sprite(100, 38, bmd);
bglife.anchor.set(0.5);
if(check != 0)
bmd = this.game.add.bitmapData(x_loader-4, 26);
else
bmd = this.game.add.bitmapData(x_loader, 26);
bmd.ctx.beginPath();
bmd.ctx.rect(0, 0, 180, 26);
if(x_loader <= 120 && x_loader > 60) {
bmd.ctx.fillStyle = "#FFFF00";
} else if(x_loader <= 60) {
bmd.ctx.fillStyle = "#EA0B1E";
} else {
bmd.ctx.fillStyle = '#00f910';
}
bmd.ctx.fill();
this.widthLife = new Phaser.Rectangle(0, 0, bmd.width, bmd.height);
this.totalLife = bmd.width;
//x_loader = ;
/*console.log(this.totalLife);
console.log(this.widthLife);*/
this.life = this.game.add.sprite(93 - bglife.width/2 + 10, 38, bmd);
this.life.anchor.y = 0.5;
this.life.cropEnabled = true;
this.life.crop(this.widthLife);
// this.game.time.events.loop(1450, this.cropLife, this);
},
updateCounter: function() {
if(timerCounter <= 0) {
this.gameOver();
return;
}
timerCounter--;
if(this.widthLife.width <= 0){
this.widthLife.width = this.totalLife;
}
else{
//this.game.add.tween(this.widthLife).to( { width: (x_loader - 4) }, 200, Phaser.Easing.Linear.None, true);
//console.log(this.widthLife.width);
this.widthLife.width = x_loader - 4;
x_loader = this.widthLife.width;
}
},
fire: function () {
if (game.time.now > nextFire && bullets.countDead() > 0)
{
nextFire = game.time.now + fireRate;
var bullet = bullets.getFirstDead();
bullet.reset(sprite.x - 80, sprite.y - 80);
game.physics.arcade.moveToPointer(bullet, 300);
}
}
}
/**
* Shuffles array in place.
* #param {Array} a items The array containing the items.
*/
function shuffle(a) {
var j, x, i;
for (i = a.length; i; i -= 1) {
j = Math.floor(Math.random() * i);
x = a[i - 1];
a[i - 1] = a[j];
a[j] = x;
}
}
As already noted it is a lot of code.
So far what I can see, is a memory leak in the update() function:
bullets = game.add.group();
bullets.enableBody = true;
bullets.physicsBodyType = Phaser.Physics.ARCADE;
bullets.createMultiple(200, 'bullet', 100, false);
bullets.setAll('anchor.x',0);
bullets.setAll('anchor.y', 0.9);
bullets.setAll('outOfBoundsKill', true);
bullets.setAll('checkWorldBounds', true);
With that you are constantly creating new bullets. Put that in the create() function and try again.
I'm quite new to javaScript and programing in general and i'm trying to make a one vs one 2D tank game using Phaser API.
I have been stuck for the past two days trying to figure out how to kill a single bullet that hits the other tank. I did manage to get it to work using the arcade physics and by using the Phaser example tank game. But i can't seem to convert my knowlegde so far and apply it to the P2 physics which i am currently using and would like to stick to.
This is the tank constructor which i use to create two tanks, each tank holds its individual bulletGroup named bullets, at the far bottom i have a function called shoot which reset a bullet and make it fly towards the target (this particular function is mostly taken from the phaser tank example)
var tank = function(playerIndex, startX, startY, facing, keyLeft, keyRight, keyUp, keyDown, keyTLeft, keyTRight, keyShoot) {
this.playerIndex = playerIndex.toString();;
this.tankBody;
this.tankTurret;
this.facing = facing;
this.bullets;
this.fireRate = 200;
this.nextFire = 0;
this.health = 100;
this.isAlive = true;
this.bodyTurnSpeed = 2;
this.turretTurnSpeed = 2;
this.currentSpeed = 0;
this.maxSpeed = 50;
this.keyLeft = keyLeft;
this.keyRight = keyRight;
this.keyUp = keyUp;
this.keyDown = keyDown;
this.keyTLeft = keyTLeft;
this.keyTRight = keyTRight;
this.keyShoot = keyShoot;
this.create = function() {
if (this.playerIndex === "1") {
this.tankBody = game.add.sprite(startX, startY, "body_player_one");
this.tankTurret = game.add.sprite(startX, startY, "turret_player_one");
} else if (this.playerIndex === "2") {
this.tankBody = game.add.sprite(startX, startY, "body_player_two");
this.tankTurret = game.add.sprite(startX, startY, "turret_player_two");
}
this.tankBody.anchor.setTo(0.5, 0.5);
this.tankTurret.anchor.setTo(0.5, 0.5);
game.physics.p2.enable([this.tankBody]);
this.tankBody.body.immovable = false;
this.tankBody.body.collideWorldBounds = true;
this.tankBody.body.debug = false;
this.tankBody.body.fixedRotation = true;
this.tankBody.body.mass = 50;
// this.tankBody.body.kinematic = true;
this.bullets = game.add.group();
this.bullets.enableBody = true;
this.bullets.physicsBodyType = Phaser.Physics.P2JS;
this.bullets.createMultiple(100, '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);
switch (this.facing) {
case "left":
this.tankBody.rotation = this.tankBody.body.rotation = Phaser.Math.degToRad(-90);
this.tankTurret.rotation = Phaser.Math.degToRad(-90);
break;
case "right":
this.tankBody.rotation = this.tankBody.body.rotation = Phaser.Math.degToRad(90);
this.tankTurret.rotation = Phaser.Math.degToRad(90);
break;
case "up":
this.tankBody.rotation = this.tankBody.body.rotation = Phaser.Math.degToRad(0);
this.tankTurret.rotation = Phaser.Math.degToRad(0);
break;
case "down":
this.tankBody.rotation = this.tankBody.body.rotation = Phaser.Math.degToRad(180);
this.tankTurret.rotation = Phaser.Math.degToRad(180);
break;
}
}
this.update = function() {
if (this.isAlive) {
if (game.input.keyboard.isDown(this.keyLeft)) {
this.tankBody.rotation = this.tankBody.body.rotation -= Phaser.Math.degToRad(this.bodyTurnSpeed);
}
if (game.input.keyboard.isDown(this.keyRight)) {
this.tankBody.rotation = this.tankBody.body.rotation += Phaser.Math.degToRad(this.bodyTurnSpeed);;
}
if (game.input.keyboard.isDown(this.keyUp)) {
this.tankBody.body.moveForward(50);
} else if (game.input.keyboard.isDown(this.keyDown)) {
this.tankBody.body.moveBackward(50);
} else this.tankBody.body.setZeroVelocity();
if (game.input.keyboard.isDown(this.keyTLeft)) {
this.tankTurret.rotation -= Phaser.Math.degToRad(this.turretTurnSpeed);
} else if (game.input.keyboard.isDown(this.keyTRight)) {
this.tankTurret.rotation += Phaser.Math.degToRad(this.turretTurnSpeed);
}
if (game.input.keyboard.isDown(this.keyShoot)) {
this.shoot();
}
this.tankTurret.x = this.tankBody.x;
this.tankTurret.y = this.tankBody.y;
} else {
this.tankTurret.kill();
this.tankBody.kill();
}
}
this.shoot = function() {
if (game.time.now > this.nextFire && this.bullets.countDead() > 0) {
this.nextFire = game.time.now + this.fireRate;
var bullet = this.bullets.getFirstExists(false);
bullet.reset(this.tankTurret.x + this.tankTurret.width / 2 * Math.cos(this.tankTurret.rotation - Phaser.Math.degToRad(90)),
this.tankTurret.y + this.tankTurret.width / 2 * Math.sin(this.tankTurret.rotation - Phaser.Math.degToRad(90)));
bullet.body.rotation = this.tankTurret.rotation;
bullet.body.mass = 100;
bullet.body.moveForward(500);
}
}
}
This is where i assign collisionGroups and make them collide with eachother,
everything here is working as intended but the bullets do not dissapear
function create() {
game.add.sprite(0, 0, "background_one");
game.physics.startSystem(Phaser.Physics.P2JS);
game.physics.p2.setImpactEvents(true);
//creating the collisiongroups
var bulletsCollisionGroup = game.physics.p2.createCollisionGroup();
var playerOneCollisionGroup = game.physics.p2.createCollisionGroup();
var playerTwoCollisionGroup = game.physics.p2.createCollisionGroup();
var wallCollisionGroup = game.physics.p2.createCollisionGroup();
//sets the objects to collide with gamestage borders (prevent objects from moving out of bounds)
game.physics.p2.updateBoundsCollisionGroup();
//creating players, each player holds its own bulletgroup
player_one.create();
player_two.create();
//creates the tiles (mouseclick to place)
createTiles();
//sets sprites to different collisiongroups
player_one.tankBody.body.setCollisionGroup(playerOneCollisionGroup);
for (var i = 0; i < player_one.bullets.children.length; i++) //player_one bullets
{
player_one.bullets.children[i].body.setCollisionGroup(bulletsCollisionGroup);
}
player_two.tankBody.body.setCollisionGroup(playerTwoCollisionGroup);
for (var i = 0; i < player_two.bullets.children.length; i++) //player_two bullets
{
player_two.bullets.children[i].body.setCollisionGroup(bulletsCollisionGroup);
}
for (var i = 0; i < tiles.children.length; i++) //tiles
{
tiles.children[i].body.setCollisionGroup(wallCollisionGroup);
}
//makes the collisiongroups collide with eachother
player_one.tankBody.body.collides([playerTwoCollisionGroup, wallCollisionGroup, bulletsCollisionGroup]);
player_two.tankBody.body.collides([playerOneCollisionGroup, wallCollisionGroup, bulletsCollisionGroup]);
for (var i = 0; i < tiles.children.length; i++) //tiles with everything
{
tiles.children[i].body.collides([playerOneCollisionGroup, playerTwoCollisionGroup, bulletsCollisionGroup]);
}
for (var i = 0; i < player_one.bullets.children.length; i++) //player_one bullets with everything
{
player_one.bullets.children[i].body.collides([wallCollisionGroup]);
player_one.bullets.children[i].body.collides(playerTwoCollisionGroup, function() {
bulletHitPlayer(player_two)
}, this);
}
for (var i = 0; i < player_two.bullets.children.length; i++) //player_two bullets with everything
{
player_two.bullets.children[i].body.collides([wallCollisionGroup]);
player_two.bullets.children[i].body.collides(playerOneCollisionGroup, function() {
bulletHitPlayer(player_one)
}, this);
}
}
this is the function i tried to use for callback on collision with a tank, it seems to work in arcade physics with overlap
function bulletHitPlayerOne(tank, bullet) {
bullet.kill()
tank.health -= 20;
if (player.health <= 0) {
tank.isAlive = false;
}
}
and this is how i tried to implement the function above to my collisionHandler
for (var i = 0; i < player_two.bullets.children.length; i++) {
player_two.bullets.children[i].body.collides(playerOneCollisionGroup, bulletHitPlayerOne, this);
}
Now, I've tried a various of different ways to solve this problem but im completely stuck, I'm begining to think that i can't kill a sprite in a group with the P2 physics enabled (but then again why wouldn't it work?)
I did seacrh and tried to read as much documentations as possible but with this particular problem i seem to be alone :)
Thank you for your time!
/Martin
Something like this should work.
Game.prototype = {
create: function(){
//...
var bulletsCollisionGroup = game.physics.p2.createCollisionGroup();
var playerOneCollisionGroup = game.physics.p2.createCollisionGroup();
//....
this.bullets = game.add.group();
this.bullets.enableBody = true;
this.bullets.physicsBodyType = Phaser.Physics.P2JS;
this.bullets.createMultiple(100, '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);
this.bullets.forEach(function(bullet){
bullet.body.setCollisionGroup(bulletsCollisionGroup);
bullet.body.collides(playerOneCollisionGroup);
});
player.body.setCollisionGroup(playerOneCollisionGroup);
player.body.collides(bulletsCollisionGroup, this.hit, this);
},
/...
hit: function(player,bullet){
bullet.parent.sprite.kill();
}
}
Bear in mind that player will collide with the bullet and it will change velocity, acceleration and other properties before the bullet is killed. You may want to use onBeginContact or maybe BroadphaseCallback
I need to create an animation of dropping box, which supposed to bounce 10 times when it reaches a certain Y point on canvas, each time twice lower that the previous. So I have the animation of the dropping box, but I can't make the bounce work. Here are the functions that I wrote:
function dropBox(y, width, height) {
var img_box = new Image();
img_box.src = 'images/gift_box_small.png';
var box_y_pos = y;
if(y==0)
box_y_pos = y-img_box.naturalHeight;
img_box.onload = function(){
ctx_overlay.save();
ctx_overlay.clearRect(0,0,width,height);
ctx_overlay.drawImage(img_box, (width/2)-(img_box.naturalWidth/2), box_y_pos);
ctx_overlay.restore();
}
box_y_pos += 3;
var box_bottom_position = box_y_pos - img_box.naturalHeight;
if(box_y_pos+img_box.naturalHeight<height-25)
var loopTimer = setTimeout(function() {dropBox(box_y_pos, width, height)},24);
else
bounceBox(img_box, box_y_pos, box_y_pos, (height/2)-(img_box.naturalHeight/2), "up");
}
function bounceBox(img, img_final_pos, y, midway_pos, direction){
var midway = midway_pos;
var direction = direction;
var img_y_pos = y;
img.onload = function(){
ctx_overlay.save();
ctx_overlay.clearRect(0,0,docWidth,docHeight);
ctx_overlay.drawImage(img, (docWidth/2)-(img.naturalWidth/2), img_y_pos);
ctx_overlay.restore();
}
for(var i = 0; i < 10; i++){
if(direction=="up"){
//going up
if(img_y_pos>midway_){
img_y_pos -= 3;
var loopTimer = setTimeout(function() {bounceBox(img, img_final_pos, img_y_pos, midway_pos, "up")},24);
} else {
img_y_pos += 3;
midway = Math.floor(midway /= 2);
if(midway%2>0)
midway += 1;
var loopTimer = setTimeout(function() {bounceBox(img, img_final_pos, img_y_pos, midway_pos, "down")},24);
}
} else {
//going down
if(img_y_pos < img_final_pos){
img_y_pos += 3;
var loopTimer = setTimeout(function() {bounceBox(img, img_final_pos, img_y_pos, midway_pos, "down")},24);
}
}
}
}
JSFiddle: http://jsfiddle.net/n2derqgw/3/
Why isn't it working and how can I make it work?
To avoid getting a headache, you've better handle the animation within a single function called with a setInterval.
And keep all animation-related data in one object.
So the code below does not exactly what you want, but should get you started :
http://jsfiddle.net/n2derqgw/4/
Setup :
var canvas_overlay, ctx_overlay, docWidth, docHeight;
var img_box = new Image();
img_box.src = 'http://corkeynet.com/test/images/gift_box_small.png';
var mustBeReadyCount = 2; // must load image and window
img_box.onload = launchWhenReady;
window.onload = launchWhenReady;
var animationStep = '';
var boxAnimationData = {
animationStep: '',
y: 0,
maxY: 0,
bounceCount: 6,
direction: -1,
bounceHeight: 0
};
function launchWhenReady() {
mustBeReadyCount--;
if (mustBeReadyCount) return;
docWidth = window.innerWidth;
docHeight = window.innerHeight;
canvas_overlay = document.getElementById('canvas_overlay');
ctx_overlay = canvas_overlay.getContext('2d');
resizeCanvas(docWidth, docHeight);
boxAnimationData.animationStep = 'falling';
boxAnimationData.bounceHeight = docHeight / 2 - img_box.height;
setInterval(animateBox, 30);
};
More interesting code is here :
function animateBox() {
if (boxAnimationData.animationStep == 'falling') dropBox();
else if (boxAnimationData.animationStep == 'bouncing') bounceBox();
}
function dropBox() {
ctx_overlay.clearRect(0, 0, docWidth, docHeight);
boxAnimationData.y += 3;
if (boxAnimationData.y + img_box.height > docHeight) {
boxAnimationData.animationStep = 'bouncing';
}
ctx_overlay.drawImage(img_box, (docWidth / 2) - (img_box.width / 2), boxAnimationData.y);
}
function bounceBox() {
ctx_overlay.clearRect(0, 0, docWidth, docHeight);
boxAnimationData.y += boxAnimationData.direction * 3;
if (boxAnimationData.y + img_box.height > docHeight) {
// reached floor ? swap direction
boxAnimationData.direction *= -1;
// and reduce jump height
boxAnimationData.bounceHeight *= 3 / 2;
boxAnimationData.bounceCount--;
if (!boxAnimationData.bounceCount) boxAnimationData.animationStep = '';
} else if (boxAnimationData.y < boxAnimationData.bounceHeight) {
boxAnimationData.direction *= -1;
}
ctx_overlay.drawImage(img_box, (docWidth / 2) - (img_box.width / 2), boxAnimationData.y);
}
Total noob here, i'm assuming there's a way to write this faster/smaller. Any advice?
Sorry if its not really reduced down & out of the framework i'm using, but here's a live example if that helps.
Live Example: http://linkthegeek.com/public/code/bookmarker/index.html
(only works in webkit, & I've only tested in chrome)
BannerOne = 1;
BannerTwo = 2;
BannerThree = 3;
BannerFour = 4;
BannerFive = 5;
PSD['bannerdrop-'+ BannerOne].y= -200;
PSD['bannerdrop-'+ BannerTwo].y= -200;
PSD['bannerdrop-'+ BannerThree].y= -200;
PSD['bannerdrop-'+ BannerFour].y= -200;
PSD['bannerdrop-'+ BannerFive].y= -200;
PSD['bannerbtn-'+ BannerOne].on("click", function(){Bookmark(BannerOne) });
PSD['bannerdrop-'+ BannerOne].on("click", function(){Bookmark(BannerOne) });
PSD['bannerbtn-'+ BannerTwo].on("click", function(){Bookmark(BannerTwo) });
PSD['bannerdrop-'+ BannerTwo].on("click", function(){Bookmark(BannerTwo) });
PSD['bannerbtn-'+ BannerThree].on("click", function(){Bookmark(BannerThree) });
PSD['bannerdrop-'+ BannerThree].on("click", function(){Bookmark(BannerThree) });
PSD['bannerbtn-'+ BannerFour].on("click", function(){Bookmark(BannerFour) });
PSD['bannerdrop-'+ BannerFour].on("click", function(){Bookmark(BannerFour) });
PSD['bannerbtn-'+ BannerFive].on("click", function(){Bookmark(BannerFive) });
PSD['bannerdrop-'+ BannerFive].on("click", function(){Bookmark(BannerFive) });
function Bookmark (viewnum) {
item = PSD['item-'+ viewnum ]
bannerbtn = PSD['bannerbtn-'+ viewnum ]
bannerdrop = PSD['bannerdrop-'+ viewnum ]
var down;
var away;
var small;
if (bannerbtn.opacity == 1) {
away = 0;
small = .03;
down = -13;
};
if (bannerbtn.opacity == 0) {
away = 1;
small = 1;
down = -200;
};
//animations
bannerdrop.animate({
properties:{y:down},
curve:"spring(100,15,200)"
});
bannerbtn.animate({
properties:{opacity:away, scale:small},
curve:"linear",
time:100
});
};
Don't quite understand your application here, but here's something that might set you in the right direction.
This is definitely not functional as I don't have a lot of the background information and have made assumptions:
var BannerCount = 5;
var PSD = [];
for (i = 0; i < count; i++) {
PSD[i] = {};
PSD[i].btn = document.getElementById('bannerbtn-' + i);
PSD[i].btn.on("click", function (eevent) {
Bookmark(eevent.srcElement);
});
PSD[i].y = -200;
PSD[i].on("click", function (eevent) {
Bookmark(eevent.srcElement);
});
PSD[i].drop = document.getElementById('bannerdrop-' + i).addEventListener("click",
function (eevent) {
Bookmark(eevent.srcElement);
});
}
function Bookmark(itemPSD) {
var down;
var away;
var small;
if (itemPSD.btn.style.opacity == 1) {
away = 0;
small = 0.03;
down = -13;
} else if (itemPSD.btn.style.opacity === 0) {
away = 1;
small = 1;
down = -200;
}
//animations
itemPSD.drop.animate({
properties: {
y: down
},
curve: "spring(100,15,200)"
});
itemPSD.btn.animate({
properties: {
opacity: away,
scale: small
},
curve: "linear",
time: 100
});
}
We may be need an object bannerdrop will save any attribute you have. So what we do is declare array of this object like:
function bannerdrop(y){
this.y = y;
this.on('click', function(){bookmark(this);});
}
function bookmark(obj){
var down;
var away;
var small;
//animations
obj.animate({
properties:{y:down},
curve:"spring(100,15,200)"
});
}
var bannerArray = new Array(new bannerdrop(-200), new bannerdrop(-200), new bannerdrop(-200));