alexandernst Posted March 6, 2018 Share Posted March 6, 2018 I have done a demo code that creates a gun (blue box) and bullets (red boxes). How can I set the initial position of the bullets depending of the rotation of the gun? Said with other words, if I rotate the gun (left/right arrows) , the bullets keep coming from the top side of the gun (box) instead of rotating accordingly. Code: http://plnkr.co/edit/3evg6J2cGo0nS7QKxiak?p=preview Preview: http://run.plnkr.co/AodG3n4Ykb3osdh2/ Link to comment Share on other sites More sharing options...
AdamRyanGameDev Posted March 6, 2018 Share Posted March 6, 2018 Hey, i couldnt actually get the gun to rotate, but looking at the code quickly, you could try putting the gun fire code in the update() loop too. If it is in create() it will not update as the gun changes, so always fires as per calculations in the called once only create()..... Link to comment Share on other sites More sharing options...
alexandernst Posted March 6, 2018 Author Share Posted March 6, 2018 Hi! You must use the "preview" link, as plnkr won't capture key input in the "code" mode. Thanks for the suggestion, let me try. Link to comment Share on other sites More sharing options...
alexandernst Posted March 6, 2018 Author Share Posted March 6, 2018 It doesn't work. And I think because the (x,y) vector doesn't change. Why would it? I'm not moving the gun, I'm only rotating it. Link to comment Share on other sites More sharing options...
AdamRyanGameDev Posted March 6, 2018 Share Posted March 6, 2018 Preview says internal server error... If the gun is not moving at all fair enough, but remember that maybe it is because the sprite is transformed after its position. Ie what we see is not what the code will have as its position. But I am a phaser3 noob too, so can-t guarantee, but it appears that is its modus operandi. To test it, start with the gun angled in create(), then see how it fires EDIT HAD A LOOK and this isnt the problem, sorry Link to comment Share on other sites More sharing options...
alexandernst Posted March 7, 2018 Author Share Posted March 7, 2018 Same result. Let's see if somebody else can shed some light on this. AdamRyanGameDev 1 Link to comment Share on other sites More sharing options...
AdamRyanGameDev Posted March 7, 2018 Share Posted March 7, 2018 Put this in your update() and fire repeatedly update() { this.gun.setOrigin(0,0); this.gun.angle -= 1; this.gun.x -= 1; } Notice that you are firing from the origin, its pivot point. I may well have been right after all on closer inspection. It fires from origin() irrespective of subsequent transforms. Not sure what you can do now though? I am still tinkering.... try Groups??? or setOrigin dynamically as it rotates? Link to comment Share on other sites More sharing options...
alexandernst Posted March 7, 2018 Author Share Posted March 7, 2018 I feel my entire approach is not optimal. There must be "something" that I can use, like "attach" that "something" to one of the sides of the box and make the bullets go out from that "something", no matter where it's located or how it's rotated. Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 7, 2018 Share Posted March 7, 2018 I've modified your code, now it should work as expected. There's still a problem with your bullet's move direction, you need to use a Point/Vector2 or an angle to control that. class Bullet extends Phaser.GameObjects.Sprite { constructor(scene) { super(scene, 0, 0, 'bullet'); this.speed = Phaser.Math.GetSpeed(400, 1); } fire(x, y) { this.setPosition(x, y); this.setActive(true); this.setVisible(true); } update(time, delta) { this.y -= this.speed * delta; this.x -= this.speed * delta; if (this.y < -50) { this.setActive(false); this.setVisible(false); } } } class Gun extends Phaser.Scene { constructor(config) { super({ key: "Gun" }) } preload() { this.load.html("gun", "gun.html", 50, 50); this.load.html("bullet", "bullet.html", 20, 20); } create() { this.gun = this.add.image(400, 300, 'gun'); this.key_left = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.LEFT); this.key_right = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.RIGHT); this.bullets = this.add.group({ classType: Bullet, maxSize: 10, runChildUpdate: true }); this.input.on("pointerdown", (event) => { let bullet = this.bullets.get(); if(bullet) { let offset = new Phaser.Geom.Point(0, -this.gun.height / 2); Phaser.Math.Rotate(offset, this.gun.rotation); bullet.fire(this.gun.x + offset.x, this.gun.y + offset.y); } }); } update() { if(this.key_left.isDown) { this.gun.angle -= 1; } else if(this.key_right.isDown) { this.gun.angle += 1; } } } var config = { width: 800, height: 600, type: Phaser.CANVAS, parent: 'phaser-example', scene: [Gun], physics: { default: 'arcade', arcade: { gravity: { z: 300 }, debug: true } } }; var game = new Phaser.Game(config); alexandernst 1 Link to comment Share on other sites More sharing options...
alexandernst Posted March 7, 2018 Author Share Posted March 7, 2018 Yes, exactly! Thank you, @PixelPicoSean Those 2 lines are exactly what I was looking for. let offset = new Phaser.Geom.Point(0, -this.gun.height / 2); Phaser.Math.Rotate(offset, this.gun.rotation); You probably know where I'm going with this, so I'll shoot my next question. How can I change the direction of the bullets depending of the angle of the gun? Currently, bullets will always go to the upper left corner, which is not a desirable thing. Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 7, 2018 Share Posted March 7, 2018 First in the bullet class: class Bullet extends Phaser.GameObjects.Sprite { constructor(scene) { super(scene, 0, 0, 'bullet'); this.speed = Phaser.Math.GetSpeed(400, 1); // Use velocity for movement // Note that `velocity` is a built-in property // if you are using any of the physics engines // of Phaser this.velocity = new Phaser.Geom.Point(0, 0); } // Pass direction to bullet as 3rd param fire(x, y, direction) { this.setPosition(x, y) .setActive(true) .setVisible(true) this.velocity.setTo(0, -this.speed) Phaser.Math.Rotate(this.velocity, direction) } update(time, delta) { // Update position based on velocity this.x += this.velocity.x * delta; this.y += this.velocity.y * delta; if (this.y < -50) { this.setActive(false); this.setVisible(false); } } } And fire the bullet: bullet.fire(this.gun.x + offset.x, this.gun.y + offset.y, this.gun.rotation); But I suggest look at physics engines of Phaser that have all these features built-in, there're tons of physics examples available that you take as a reference. alexandernst 1 Link to comment Share on other sites More sharing options...
alexandernst Posted March 7, 2018 Author Share Posted March 7, 2018 Great! Just to keep the post up to date, this is the final result now: http://plnkr.co/edit/qvCmo6hXjkKsRtemx2GF?p=preview I have a few more questions. @PixelPicoSean As you suggested, I'm going to switch to physics engine. This example looks exactly as what I want to do http://labs.phaser.io/view.html?src=src\physics\arcade\space.js , but it's broken. I already opened an issue: https://github.com/photonstorm/phaser/issues/3341 Currently I have this http://plnkr.co/edit/s3CFDNzhvnMTrtPam3Ld?p=preview but, for some reason, `body` (in the bullet context) is null. Why is that? Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 8, 2018 Share Posted March 8, 2018 The default group factory create a Group instance, while this.physics.add.group create a PhysicsGroup and that is what you need. Looks like that example uses old methods that no longer exist, you can take a look at other examples and experiment. alexandernst 1 Link to comment Share on other sites More sharing options...
alexandernst Posted March 9, 2018 Author Share Posted March 9, 2018 All right, this is looking nice! Update with the latest code: http://plnkr.co/edit/FI3odryYIolonM8KwyPz?p=preview What would be the way to instantiate a single `Phaser.Physics.Arcade.Image` class? I mean, if I do this.scene.physics.add.group({ classType: Bullet,... I'm creating a group of instances of the class `Bullet`. But how would I create a single instance (not a group)? Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 9, 2018 Share Posted March 9, 2018 // image this.physics.add.image(0, 0, 'bullet'); // sprite this.physics.add.sprite(0, 0, 'bullet'); Take a look at this example, and you will know how to create `Bullet` instances. BTW. you don't need to call `Phaser.Physics.Arcade.Image.call(this, scene, ...)` when `super(scene, ...)` is already called, they do the same thing. alexandernst 1 Link to comment Share on other sites More sharing options...
alexandernst Posted March 9, 2018 Author Share Posted March 9, 2018 But if I do that, I'm not instantiating a class of my own. I'll be literally creating a new object directly from a loaded image. I want to instantiate my "Gun" class from the scene, and then call some of the methods that class has. Something like `this.physics.add.class(Gun)` Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 9, 2018 Share Posted March 9, 2018 Take a look at this example, and you will know how to create `Gun` instances. Link to comment Share on other sites More sharing options...
alexandernst Posted March 9, 2018 Author Share Posted March 9, 2018 This is weird. I'm not really sure if I'm doing something wrong or I'm hitting a bug. I'm extending my class from Phaser.Physics.Arcade.Image and then "this.body" is null. What am I missing? Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 9, 2018 Share Posted March 9, 2018 Not a bug, but you will need to call `this.scene.physics.enable(this)`, which will create the `body` property. Link to comment Share on other sites More sharing options...
alexandernst Posted March 9, 2018 Author Share Posted March 9, 2018 There doesn't seem to be such a method (I'm inspecting all the methods with Chrome's debugger). Are you sure this is correct? Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 9, 2018 Share Posted March 9, 2018 Sorry my fault, it should be `this.scene.physics.world.enable(this)` alexandernst 1 Link to comment Share on other sites More sharing options...
alexandernst Posted March 9, 2018 Author Share Posted March 9, 2018 Yuhuuuu!!! It's working \o/ Nice! Thank you! Link to comment Share on other sites More sharing options...
alexandernst Posted March 9, 2018 Author Share Posted March 9, 2018 @PixelPicoSean I have another problem with the position of the bullets. http://plnkr.co/edit/wEsq9eFKaQKAL0wyPQTB?p=preview Note that I have set the initial position to be `x + 40`. If I fire the gun right after launching the game, the position of the bullets is correct, but when I rotate the gun, the bullets don't rotate using the gun's "orbit". <-- this is correct <--- this is incorrect How can I "orbit" rotate the bullets? Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 9, 2018 Share Posted March 9, 2018 Change your fire method to: fire(gun) { this.lifespan = 2000; this.setActive(true); this.setVisible(true); this.setRotation(gun.rotation); // angle is in degree, rotation is in radian var offset = new Phaser.Geom.Point(40, 0); Phaser.Math.Rotate(offset, gun.rotation); // you can only rotate with radian this.setPosition(gun.x + offset.x, gun.y + offset.y); // this.body.reset(gun.x + offset.y, gun.y + offset.y); // var angle = Phaser.Math.DegToRad(gun.body.rotation); this.body.world.scene.physics.velocityFromRotation(gun.rotation, this.speed, this.body.velocity); this.body.velocity.x *= 2; this.body.velocity.y *= 2; } alexandernst 1 Link to comment Share on other sites More sharing options...
alexandernst Posted March 9, 2018 Author Share Posted March 9, 2018 Great! Everything looks like it would have been very easy to figure out, only if there were some books/docs on Phaser 3... Anyway, my next question: how can I make my gun always face the pointer? I saw this demo ( http://labs.phaser.io/edit.html?src=src\input\mouse\pointer lock 3d rotate.js ), so I already know how to detect when the pointer is moving, and I know how to get the (x,y) vector of the pointer, but I don't know how to translate that position to the required angle. Link to comment Share on other sites More sharing options...
Recommended Posts