mk12001 Posted August 20, 2015 Share Posted August 20, 2015 Hi guys, I'm trying to create my first practice game using phaser and I need help badly (I only started coding recently). I used http://phaser.io/examples/v2/games/tanks as reference. I have attached the corresponding files in this post. The game's background:The game is based on an old arcade game wherein you control a naval ship (using left and right keys to move and spacebar to drop depth charges) and your goal is to destroy all enemy submarines. My issues:1. I want the submarines to randomly face left or right at the start. I tried to use game.rnd.between(1,2), but it seems to generate '1' always.2. The kill/destroy object code isn't optimized. I'm noticing some performance issues mid-game, as if the enemies and depth charges are not killed correctly. I'm not sure if I'm correctly referring to the proper objects (enemies, depth charges) being killed. As proof, I the enemySubmarines.length still shows 10 (original number), even if I already destroyed some subs.3. The explosion animation (called in destroySub function) moves along the destroyed submarine. I want it to be fixed in the position where the spot the submarine is destroyed.4. There are times when 2 depth charges collide with a single submarine, and both depth charges are taken out. I need opinion if this logic is already ok, or it would be better if 1:1 ratio is applied. I would really appreciate any help/inputs. Thank you! Enemy = function (index, game, torpedo) { var x = game.world.randomX; var y = (50*index)+140; var face = game.rnd.between(1,2); this.game = game; this.health = enemySubHealth; this.torpedo = enemyTorpedo; this.fireRate = 1000; this.nextFire = 0; this.alive = true; this.enemy = game.add.sprite(x, y, 'enemySub'); //this.enemy.anchor.set(0.5); this.enemy.name = index.toString(); game.physics.enable(this.enemy, Phaser.Physics.ARCADE); this.enemy.body.immovable = true; this.enemy.body.collideWorldBounds = true; this.enemy.body.bounce.x = 1; if(face = 1){ this.enemy.body.velocity.x = -100+(10*level); }else{ this.enemy.body.velocity.x = 100; } } Enemy.prototype.damage = function() { return false; } var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render }); //var text; //player global variables var score=0; var scoreStrinf =''; var lives = 3; var cursors; var left; var right; var shoot; var level = 1; //destroyer global variables var destroyer; var destroyerHp = 1; var destroyerDragX = 50; var destroyerVelocityX = 50; var depthChargeCount = 3; //depthCharge global variables var depthCharges; var depthChargeTime = 0; var depthChargeVelocity = 50; //submarines var enemySubmarines; var enemySubHealth = 1; var enemyTorpedo; var enemyTorpedoCount = 30; var numberOfEnemies; function preload() { game.load.spritesheet('test', 'TestSheet.png', 40, 45, 10); game.load.image('background','waterbg.png'); game.load.image('depthCharge', 'depthCharge.png'); game.load.image('enemySub', 'enemySub.png'); game.load.image('enemyTorpedo', 'enemyTorpedo.png'); game.load.spritesheet('explosion', 'explosion.png', 195, 195, 24); } function create() { //var style = { font: "bold 32px Arial", fill: "#fff", boundsAlignH: "center", boundsAlignV: "middle" }; // The Text is positioned at 0, 100 //intro = game.add.text(0, 0, "How many players?", style); //Add background var background = game.add.tileSprite(0, 0, 800, 600, 'background'); //land.fixedToCamera = true; //player cursor cursors = game.input.keyboard.createCursorKeys(); shoot = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR); //destroyer initialization destroyer = game.add.sprite(game.world.centerX, 55, 'test'); destroyer.smoothed=false; game.physics.enable(destroyer,Phaser.Physics.ARCADE); destroyer.body.collideWorldBounds = true; destroyer.body.bounce.x = 0.2; destroyer.animations.add('anim',[0,1],2,true); destroyer.play('anim'); destroyer.body.drag.x = destroyerDragX; destroyer.body.immovable = true; //depthCharge initialization depthCharges = game.add.group(); depthCharges.enableBody = true; depthCharges.physicsBodyType = Phaser.Physics.ARCADE; depthCharges.createMultiple(depthChargeCount,'depthCharge',0,false); depthCharges.setAll('outOfBoundsKill',true); depthCharges.setAll('checkWorldBounds',true); //enemyTorpedo initialization enemyTorpedo = game.add.group(); enemyTorpedo.enableBody = true; enemyTorpedo.physicsBodyType = Phaser.Physics.ARCADE; enemyTorpedo.createMultiple(enemyTorpedoCount,'enemyTorpedo',0,false); enemyTorpedo.setAll('outOfBoundsKill',true); enemyTorpedo.setAll('checkWorldBounds',true); //enemy submarines //enemySubmarines = game.add.group(); //enemySubmarines.enableBody = true; //enemySubmarines.physicsBodyType = Phaser.Physics.ARCADE; // Explosion pool explosions = game.add.group(); for (var ctr = 0; ctr < 10; ctr++){ var explosionAnimation = explosions.create(0, 0, 'explosion', [0], false); explosionAnimation.anchor.setTo(0.5, 0.5); explosionAnimation.animations.add('explosion'); } //create enemies enemySubmarines = []; numberOfEnemies = level*10; enemiesAlive = level*10; for (var ctr = 0; ctr < numberOfEnemies; ctr++){ enemySubmarines.push(new Enemy(ctr, game, enemyTorpedo)); } //HUD scoreString = 'Score: '; scoreText = game.add.text(10,10, scoreString + score, {font: '12px Calibri', fill: '#fff'}); } function render(){ game.add.text(game.world.width - 100,10, 'Enemies Alive: ' + enemiesAlive, {font: '12px Calibri', fill: '#fff'}); } function update(){ enemiesAlive = 0; for (var i = 0; i < enemySubmarines.length; i++){ if (enemySubmarines[i].alive){ enemiesAlive++; var test = game.physics.arcade.overlap(depthCharges, enemySubmarines[i].enemy, destroySub, null, this); console.log("update" + test); } } if(shoot.isDown){ shootdepthCharge(); } if (cursors.left.isDown){ destroyer.body.velocity.x = -destroyerVelocityX; } else if(cursors.right.isDown){ destroyer.body.velocity.x = destroyerVelocityX; } } function shootdepthCharge(){ if(game.time.now > depthChargeTime){ depthCharge = depthCharges.getFirstExists(false); if(depthCharge){ depthCharge.reset(destroyer.x+20,destroyer.y+45); depthCharge.body.velocity.y = depthChargeVelocity; depthChargeTime = game.time.now + 600; } } } function destroySub(depthCharge,enemySubmarines){ resetdepthCharge(depthCharge); enemySubmarines.health -= 1; if (enemySubmarines.health <= 0){ enemySubmarines.alive = false; enemySubmarines.kill(); console.log("destroyed sub"); var explosionAnimation = explosions.getFirstExists(false); explosionAnimation.reset(enemySubmarines.x, enemySubmarines.y); explosionAnimation.play('explosion', 30, false, true); } } function resetdepthCharge(depthCharge){ depthCharge.kill(); } }subDestroyer.zip Link to comment Share on other sites More sharing options...
mk12001 Posted August 21, 2015 Author Share Posted August 21, 2015 up Link to comment Share on other sites More sharing options...
Tilde Posted August 21, 2015 Share Posted August 21, 2015 I don't know offhand what all your problems are, but I do know that you can save yourself a lot of trouble by making your Enemy class extend Phaser.Sprite. It'll allow you to push it directly into Phaser groups, which is a really convenient way of handling your assets. Some of your problems might be related to the fact that you're conflating your Enemy class with a proper Sprite, but that's just a hypothesis. rnd.between should do what you're asking of it, not sure what the problem is there. Link to comment Share on other sites More sharing options...
mk12001 Posted August 21, 2015 Author Share Posted August 21, 2015 Thanks for the feedback, Tilde. Apologies, but I'm new in programming, so how do I extend the class? I tried playing around rnd.between and it works as is. I just don't know how to integrate it to the game. What I really want is for rnd.between to generate a random number, either 1 or 2 [game.rnd.between(1,2) already does the trick]. If 1, then the enemy submarine should start moving to the left. If 2, the enemy submarine should start moving to the right. For some reason, all the submarines move to the left, regardless of the value in "face" variable. Link to comment Share on other sites More sharing options...
Tilde Posted August 21, 2015 Share Posted August 21, 2015 Oh, I see your problem. Your if statement says "if (face = 1)". The thing is, = is the assignment operator. It assigns a value to a variable. It doesn't check for equivalence. You want == for that. Link to comment Share on other sites More sharing options...
rocus Posted August 21, 2015 Share Posted August 21, 2015 Hi there To extend a Phaser class, for example Phaser.Sprite, you can use prototype method. Roughly like the example belowclass_name = function(x, y, key, frame){ Phaser.Sprite.call(game, x, y, key, frame); game.world.add(this) this.inputEnabled = true; this.events.onTouchDown.add(this.onInputDown, this);}; class_name.prototype = Object.create(Phaser.Sprite.prototype);class_name.prototype.constructor = class_name;class_name.prototype.update = function() {};class_name.prototype.onTouchDown = function(item, pointer) {};And simply use it likevar myClassInstance = new class_name(x, y, "sprite sheet key", "frame key"); jdnichollsc 1 Link to comment Share on other sites More sharing options...
mk12001 Posted August 23, 2015 Author Share Posted August 23, 2015 Thanks for the help, guys! I really appreciate it Link to comment Share on other sites More sharing options...
Recommended Posts