Linzeestomp Posted June 19, 2018 Share Posted June 19, 2018 So, I've been playing with the audio manager a bit. I've tried to add footstep sounds for when my player moves but if I put it in the update function it literally just plays the first half a second maybe? Over and over again--it sounds awful. I finally figured out it's because the update scene literally runs so many times a second and it's just request a new play on every update hence why the sound is so awful. Does anyone have any suggestions on how I can add a conditional play on event that won't result in a lawn mower sound? Code below illustrates what I've been trying to do: function preload () { this.load.audio('playerStep', 'assets/audio/steps/playerStep2.mp3', { instances: 1 }); } function create () { this.sound.add('playerStep'); } function update (time, delta) { let cursors = this.input.keyboard.createCursorKeys(); if (cursors.right.isDown && this.player.body.onFloor()) { this.sound.play('playerStep'); } } Any and all help appreciated--thanks! Link to comment Share on other sites More sharing options...
brentstrandy Posted June 20, 2018 Share Posted June 20, 2018 Ideally I would connect your SFX to a walking animation. So if you ever get a walking animation you can add the following code: this.player.on('animationrepeat', function () { if(this.player.anims.currentAnim.key === 'walking') { this.sound.play('playerStep'); } }); The above code will play a SFX every time the animation loops - which means it will *probably* play every time the player takes a step. Without an animation you can do the following: function create () { this.sound.add('playerStep'); // Create an event that fires every half-second and plays a footstep // sound if the player is currently walking this.footsteps = this.time.addEvent({ duration: 500, repeat: -1, callbackScope: this, callback: function () { if(this.player.isWalking) { this.sound.play('playerStep'); } } }); // Create the cursors only once - not every game loop this.cursors = this.input.keyboard.createCursorKeys(); } function update (time, delta) { if (this.cursors.right.isDown && this.player.body.onFloor()) { this.player.isWalking = true } else { this.player.isWalking = false } } Link to comment Share on other sites More sharing options...
Linzeestomp Posted June 20, 2018 Author Share Posted June 20, 2018 Thank you for replying! Trying your first example in my create function, I seem to be having a scope issue with this.sound.play inside the callback function. Says can't call play of undefined. Gonna keep playing with it. //scene always extends Phaser.Scene class sceneA extends Phaser.Scene { constructor() { super({ key: 'sceneA', active: true, physics: { default: 'arcade', arcade: { debug: false, gravity: { y: 500 } } }, }); } init() { } preload() { //////////////////////// // Begin Progress Bar // //////////////////////// let progressBar = this.add.graphics(); let progressBox = this.add.graphics(); progressBox.fillStyle(0x222222, 0.8); progressBox.fillRect(240, 270, 320, 50); let width = this.cameras.main.width; let height = this.cameras.main.height; // Displays 'Loading...' Text let loadingText = this.make.text({ x: width / 2, y: height / 2 - 50, text: 'Loading...', style: { font: '20px monospace', fill: '#ffffff' } }); loadingText.setOrigin(0.5, 0.5); // Displays progress percentage let percentText = this.make.text({ x: width / 2, y: height / 2 - 5, text: '0%', style: { font: '18px monospace', fill: '#ffffff' } }); percentText.setOrigin(0.5, 0.5); // Display assets being loaded let assetText = this.make.text({ x: width / 2, y: height / 2 + 50, text: '', style: { font: '18px monospace', fill: '#ffffff' } }); assetText.setOrigin(0.5, 0.5); ////////////////////// // End Progress Bar // ////////////////////// // 'progress' event listener this.load.on('progress', function (value) { //console.log(value); progressBar.clear(); progressBar.fillStyle(0xffffff, 1); progressBar.fillRect(250, 280, 300 * value, 30); percentText.setText(parseInt(value * 100) + '%'); }); // 'file progress' event listener this.load.on('fileprogress', function (file) { //console.log(file.src); assetText.setText('Loading asset: ' + file.src + " [ " + file.key + " ]"); }); // 'complete' event listener this.load.on('complete', function () { //console.log('complete'); progressBar.destroy(); progressBox.destroy(); loadingText.destroy(); percentText.destroy(); assetText.destroy(); }); // grabs JSON file with tilemap data. tilemapTiledJSON(key, src) this.load.tilemapTiledJSON('atlas', 'assets/tiles/Level 1/Level1.json'); // grabs tilesheet and sets tile size for the sheet this.load.spritesheet({ key: 'tiles', url: 'assets/tiles/Level 1/spritesheet.png', frameConfig: { frameWidth: 32, frameHeight: 32, spacing: 0, margin: 0 } }); // grabs background tilesheet and sets tile size for the sheet this.load.spritesheet({ key: 'bg', url: 'assets/tiles/Level 1/bg.png', frameConfig: { frameWidth: 32, frameHeight: 32, spacing: 0, margin: 0 } }); this.load.spritesheet('playerAnimations', 'assets/sprites/movePerson.png', { frameWidth: 600, frameHeight: 600 } ); /*this.load.image({ key: 'target', url: 'assets/tiles/Level 1/reticle.png' });*/ this.load.audio('playerStep', 'assets/audio/steps/playerStep2.mp3'); ///////////////////// // Start Plugins // ///////////////////// } create() { // place camera in the sceen and set bounds this.cameras.main.setBounds(0, 0, 1920 * 2, 1080 * 2); // make a tilemap with id or key 'atlas' let map = this.make.tilemap({ key: 'atlas' }); // create variables to hold the tileset images we preloaded earlier let groundTiles = map.addTilesetImage('tiles', 'tiles'); let bgTiles = map.addTilesetImage('bg', 'bg'); // place a static layer in the scene for our background map.createStaticLayer('bg', bgTiles, 0, 0); // place a dynamic layer in the scene for the platform let platform = map.createDynamicLayer('platform', groundTiles, 0, 0); // let physics engine know in the above layer only tiles with a value in them will have collision platform.setCollisionByExclusion([-1]); // set physics world bounds (keeps player on screen) this.physics.world.bounds.width = platform.width; this.physics.world.bounds.height = platform.height; // place more dynamic layers in the scene (however many we need) map.createDynamicLayer('layerOne', groundTiles, 17, 0); map.createDynamicLayer('layerTwo', groundTiles, 0, 0); map.createDynamicLayer('layerThree', groundTiles, 0, 0); //create the animations using our spritesheet this.anims.create({ key: 'idle', frames: this.anims.generateFrameNumbers('playerAnimations', { start: 0, end: 9, first: 9 }), frameRate: 9, repeat: -1 }); this.anims.create({ key: 'move', frames: this.anims.generateFrameNumbers('playerAnimations', { start: 10, end: 19, first: 19 }), frameRate: 20, repeat: -1 }); this.anims.create({ key: 'attack', frames: this.anims.generateFrameNumbers('playerAnimations', { start: 20, end: 29, first: 29 }), frameRate: 20, repeat: -1 }); this.anims.create({ key: 'dead', frames: this.anims.generateFrameNumbers('playerAnimations', { start: 30, end: 39 }), frameRate: 20 }); // place the player sprite in the scene this.player = this.physics.add.sprite(300, 68, 'playerAnimations', 0); // scale player sprite size this.player.setScale(0.35, 0.35); // set player bounce factor this.player.setBounce(0.0); // set collision against canvas borders to keep player on screen this.player.setCollideWorldBounds(true); // set camera to follow the player this.cameras.main.startFollow(this.player, true, 0.05, 0.05); // let physics engine know which layer we want the player to collide with this.physics.add.collider(platform, this.player); // load sound manager this.sound.add('playerStep'); } update(time, delta) { //this.player.rotation = Phaser.Math.Angle.Between(this.player.x, this.player.y, this.reticle.x, this.reticle.y); //this.reticle.body.velocity.x = this.player.body.velocity.x; //this.reticle.body.velocity.y = this.player.body.velocity.y; this.player.setVelocityX(0); let cursors = this.input.keyboard.createCursorKeys(); if (cursors.left.isDown && this.player.body.onFloor()) { this.player.setVelocityX(-300); this.player.flipX = true; this.player.anims.play('move', true); this.player.on('animationrepeat', function () { if(this.anims.currentAnim.key === 'move') { this.sound.play('playerStep'); } }); } else if (cursors.right.isDown && this.player.body.onFloor()) { this.player.setVelocityX(300); if (this.player.flipX === true) { this.player.flipX = false; } this.player.anims.play('move', true); } else if (cursors.space.isDown && this.player.body.onFloor()) { //this.player.setVelocityY(-100); //this.player.anims.play('attack', true); this.player.anims.play('dead', true); } else { this.player.anims.play('idle', true); } } } Link to comment Share on other sites More sharing options...
brentstrandy Posted June 20, 2018 Share Posted June 20, 2018 You have to bind the context to your callback function this.player.on('animationrepeat', function () { if(this.anims.currentAnim.key === 'move') { this.sound.play('playerStep'); } }.bind(this)); Link to comment Share on other sites More sharing options...
Recommended Posts