• Content Count

  • Joined

  • Last visited

About piotr

  • Rank
    Advanced Member

Contact Methods

  • Website URL

Profile Information

  • Gender
    Not Telling

Recent Profile Visitors

1528 profile views
  1. You can't set the tint directly like this. What I do is takeDamage() { flashColor(0xFF0000); } flashColor(color) { this.setTint(color); this.scene.time.addEvent({ delay: 200, callback: function(){ this.clearTint(); }, callbackScope: this, }); } Here's one example of how to achieve it: https://phaser.discourse.group/t/how-phaser-can-make-a-flashing-animation-of-sprite/1503/4 Here's a more advanced one:
  2. @windyWin If you are still interested in this topic, I've found and posted a solution on Discourse: https://phaser.discourse.group/t/solved-posted-with-code-enable-disable-hit-boxes-once-per-animation-frame/8712/12
  3. For future reference, here the solution I've found: https://phaser.discourse.group/t/solved-posted-with-code-enable-disable-hit-boxes-once-per-animation-frame/8712/12
  4. Hi all, this seems easy but all the examples I found destroy or remove overlap permanently. I need the sword to check overlap with enemies every time the space bar is pressed. That means enable overlap for 1 frame and then disable it the next frame. I'm using animations on the sword to trigger the body but what I get at most is that the collisions happens 4 times per update Is there a way to check overlap / collision only once per update? export default class Play extends Phaser.Scene { create() { //Player this.player = new Player(this, 0, 0); this.container = this.add.container(100, 100); this.container.setSize(16, 16); this.physics.world.enable(this.container); this.container.add(this.player); //Weapon this.meleeWeapon = new MeleeWeapon(this, 0, 0); this.physics.world.enable(this.meleeWeapon); this.container.add(this.meleeWeapon); //Enemy this.enemy = new Enemy(this, 600, 600); this.enemies = this.add.group(); this.enemies.add(this.enemy) //Collisions this.physics.add.overlap(this.meleeWeapon, this.enemies, this.onMeetEnemy, false, this); } onMeetEnemy(weapon, enemy) { enemy.takeDamage(weapon.damage); } update() { if(this.spaceBar.isDown) { this.meleeWeapon.attack(); } } MeleeWeapon.js export default class MeleeWeapon extends Phaser.Physics.Arcade.Sprite { constructor (scene, x, y) { this.body.enable = false; } attack () { if(!this.isAttacking) { this.isAttacking = true; this.attackAnimation = this.anims.play('attack', false); this.attackAnimation.on('animationupdate', () => { if(this.attackAnimation.anims.currentFrame.index == 2) { this.body.enable = true; } else { this.body.enable = false; }; }); this.attackAnimation.on('animationcomplete', () => { this.isAttacking = false; }); } }
  5. Solved. The issue was the game's low resolution (400x300). I was trying to make my 16x16 sprites to look sharp and big enough and therefore the bitmap fonts where crunched. On top of that I wasn't using .setScale to set the font's size. So to this is the current set up I'm using to get a retro pixel looking game: 1. Don't set a too low resolution and set zoom to 1 var config = { scale: { width: 1600, height: 1200 }, pixelArt: true, roundPixels: false, antialias: false, zoom: 1 }; 2. Use .setScale(); for bitmap fonts this.add.bitmapText(0, 0, '8bit', 'Game Title').setScale(1); 3. If you have small sprites, 16x16, then change the scale of all sprites to blew them up and show those nice pixel var player = this.add.sprite(x, y, "player"); player.setScale(4);
  6. I've also added these lines, without any improvements: To the config file mode: Phaser.Scale.NONE, To the scene this.cameras.main.setRoundPixels(true);
  7. Here's a post that explains how to call a function on the last frame of an animation. For your specific case you could start with a disabled collider (say on a sword) and then once the attack animation is complete, enable it.
  8. Hi all, Bitmap fonts don't display correctly on both Chrome and Safari (both on Mac), but sprites render correctly (green gradient on the side of the attached images) I've tried with different fonts and this is my configuration. This happens with both zoom:1 and zoom: 2 and larger canvases (e.g 800x600) var config = { type: Phaser.AUTO, scale: { parent: 'gameDiv', autoCenter: Phaser.Scale.CENTER_BOTH, width: 400, height: 300, }, pixelArt: true, roundPixels: false, antialias: false, backgroundColor: '#000000', scene: [ Boot, Preload, Title, Options, Credits, Play, End ], physics: { default: 'arcade', arcade: { debug: false } }, zoom: 2, }; This is how I load and use the fonts. I've tried using both .xml and .fnt //load this.load.bitmapFont('pinscher', 'assets/fonts/pinscher-hd.png', 'assets/fonts/pinscher-hd.xml'); //use var title = this.add.bitmapText(0, 0, 'pinscher', 'Game Title', 30); Thanks for any help in fixing this
  9. Yay! Thank you Rich, I'm very happy that I can start with Phaser again. Yes, the bit about the tag's order was wrong; the order was dictated by how the states where added to the main game. For others that may see this thread, in addition to Rich's example, here's a step by step tutorial (I just found) for putting together a template. Also the code to add 'main.js' in the html as a module would be (also in the tutorial above) <body> <script type="module" src="main.js"></script> </body> Rich, I saw that in the Germs game example, there's a boot.json file. Do I need that one too? What is it for?
  10. hi all, Is there a way to break a Phaser 3 project down into multiple files for objects (Player.js, Enemy,js) and scenes (Boot.js, Game.js...) while using ES6 classes but without Node.js, Webpack and so on? All the templates I found rely on some additional app and I'd like to avoid using them. Starting with Phaser 3 has been way more complicated than starting with Phaser 2 years ago. Setting up all those dependencies and debugging them has been a huge time sink and they still don't work to my great frustration. In Phaser 2 it was a matter of linking all the files in the main HTML file via the <script src="..."></script> tag in the right order, and adding all the states to the global game object. I appreciate it wasn't ideal but it was simple. Thanks for any help!
  11. Thanks, that helped! Here's the code that is working for me var distanceFromTarget = 10; var targetVelocity; var pointBehindTarget = new Phaser.Point(); targetVelocity = new Phaser.Point(target.body.velocity.x, target.body.velocity.y); //make a copy of the velocity vector targetVelocity.multiply(-1,-1); //invert its direction targetVelocity.normalize(); //set its length to 1 targetVelocity.multiply(distanceFromTarget,distanceFromTarget); //scale it to the desired length pointBehindTarget = Phaser.Point.add(target.position,targetVelocity); //create a new point
  12. Hi, how do you get the velocity vector of a sprite? sprite.body.velocity is phaser point or as a vector, going from the 0,0 to the sprite. What I need is a velocity vector going from the sprite onward. I need then to multiply by -1 and add it to the sprite position to get a point behind it like this image Thanks
  13. Hi all, If I set tiles to collide only on top, then when I swap tiles with "putTile", "removeTile" or "replace", any collision data previously set is lost. Is this working as intended? (Assuming that all tiles are in the "blocksArray" array) var playState = { create: function() { //create and save all Tiled layers into an array this.allLayers = []; for(var i = 0; i < this.map.layers.length; i++) { //crate all layers var layer = this.map.createLayer(''+ this.map.layers[i].name +''); //save all created layers this.allLayers.push(layer); } //search all layers for(var i = 0; i < this.allLayers.length; i++) { //set special collision for all tiles in the blocksArray if(blocksArray.length > 0) { this.setBlockCollision(this.allLayers[i], blocksArray, { top: true, bottom: false, left: false, right: false }); } } } update: function() { for(var i = 0; i < this.allLayers.length; i++) { game.physics.arcade.collide(this.player, this.allLayers[i], function(player, block){ this.contactWithPlatform(player, block, this.allLayers[i]);}, null, this); } } //------- ISSUES START HERE -------- // contactWithPlatform: function (player, block, platformLayer) { //method 1 //this.map.removeTile(block.index); //this.map.putTile(block.index, block.x, block.y); //method2 this.map.replace(block.index,block.index++, 1, 1, 1, 1); } //------- ISSUES EDS HERE -------- // //http://thoughts.amphibian.com/2015/11/single-direction-collision-for-your.html setBlockCollision: function (mapLayer, idxOrArray, dirs) { var mFunc; // tile index matching function if (idxOrArray.length) { // if idxOrArray is an array, use a function with a loop mFunc = function(inp) { for (var i = 0; i < idxOrArray.length; i++) { if (idxOrArray[i] === inp) { return true; } } return false; }; } else { // if idxOrArray is a single number, use a simple function mFunc = function(inp) { return inp === idxOrArray; }; } // get the 2-dimensional tiles array for this layer var d = mapLayer.map.layers[mapLayer.index].data; for (var i = 0; i < d.length; i++) { for (var j = 0; j < d[i].length; j++) { var t = d[i][j]; if (mFunc(t.index)) { t.collideUp = dirs.top; t.collideDown = dirs.bottom; t.collideLeft = dirs.left; t.collideRight = dirs.right; t.faceTop = dirs.top; t.faceBottom = dirs.bottom; t.faceLeft = dirs.left; t.faceRight = dirs.right; } } } },
  14. Thanks Casey. I've tried the first options, and it works. 1. Tiled setup Put each platform on a separate Tiled layer. The layer should have a custom boolean property called "complete" Every tile should have a boolean custom property called "touched" 2. The code create: function() { //create and save all Tiled layers this.allLayers = []; for(var i = 0; i < this.map.layers.length; i++) { //crate all layers var layer = this.map.createLayer(''+ this.map.layers[i].name +''); //save all created layers this.allLayers.push(layer); } //set collision for the layers created for(var i = 0; i < this.allLayers.length; i++) { this.map.setCollisionBetween(0,1000, true, this.allLayers[i]); } }, update: function() { for(var i = 0; i < this.allLayers.length; i++) { //pass the actual layer as an extra argument, because the first accourance is a tile game.physics.arcade.collide(this.player, this.allLayers[i], function(player, tile){ this.touchTile(player, tile, this.allLayers[i]);}, null, this); } }, touchTile: function(player,tile,layer) { if(tile.properties.touched == false) { tile.properties.touched == true; } this.checkPlatform(player,tile,layer); }, checkPlatform: function (player,tile,layer) { //if not all tiles have been touched if(tile.layer.properties.complete == false) { //get all tiles in the layer var platformTiles = layer.getTiles(layer.x,layer.y,layer.width, layer.height,true,true); var touchedTiles = []; //look for touched tiles in the layers and save them in an array for(var i = 0; i < platformTiles.length; i++) { if(platformTiles[i].properties.touched == true) { touchedTiles.push(platformTiles[i]); } } //check if the all tiles have been touched if(touchedTiles.length === platformTiles.length) { for(var i = 0; i < platformTiles.length; i++) { platformTiles[i].index++; } //all tiles have been touched tile.layer.properties.complete = true; } } },