kristof Posted February 9, 2019 Share Posted February 9, 2019 Hy everyone, My question is about the hitArea of a sprite. First of all I am not quite sure if I understood the definition correctly, so I would really appreciate a clear explanation about it. What I want to do is: I have sprites in my game and I would test collision between them, but the sprite's width and height is not perfectly accurate to its 'actual appearance' so I would reduce the hitArea to improve my collision detection algorithm (but sometimes setting the hitArea is making it worse than using just the regular .getBounds() function). This is how I did it for the first time but collision didn't occur. let player = new PIXI.Sprite(texture); player.position.set(75, app.stage.view.height / 2); player.anchor.set(0.5); player.hitArea = new PIXI.Rectangle(player.x, player.y, 60, 20); Later I found out that it is because the enemy that I am checking the collision against, is not being compared to my player object, but the initial coordinates of the PIXI.Rectangle that I use to modify hitArea with. I have found out that if I want to compare the player.hitArea of the current position of my player object to enemy.getBounds(), in my game loop I update the hitArea of player like: app.ticker.add( () =>{ player.x += player.velocityX; player.y += player.velocityY; player.hitArea = new PIXI.Rectangle(player.x, player.y, 75, 85); }; I feel like this is a poor solution that I have came up with. Is there a better way of always updating hitArea coordinates to the player object's current coordinates? Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 9, 2019 Share Posted February 9, 2019 HitArea is not absolute, you can specify (0,0, 60, 20) there and it'll be fine Is (x,y) your left-top corner? kristof 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 9, 2019 Share Posted February 9, 2019 Here is Sprite default area: https://github.com/pixijs/pixi.js/blob/dev/packages/sprite/src/Sprite.js#L433 , Pixi converts coords to local and then it checks rect (-anchor.x * w, -anchor.y * h, (1-anchor.x)*w, (1-anchor.y) * h) If you want different w,h , your hitArea has to be relative that (0,0) that is CENTER of your sprite because you specified anchor=0.5. It'll be like (-30, -10, 60, 20) kristof 1 Quote Link to comment Share on other sites More sharing options...
kristof Posted February 9, 2019 Author Share Posted February 9, 2019 So if I did not set anchor of the sprite I would always just use (0,0, widthValue, heightValue) and no need to ever update it? And when anchor is set to center of the sprite as 0.5 then it is (-widthValue/2, -heightValue/2, widthValue, heightValue)? Sorry for asking silly questions I just want to make sure that I understand it Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 9, 2019 Share Posted February 9, 2019 Exactly. But sprite checks that rectangle anyway in `containsPoint`. you are not sure that its different from your sprite dimensions. However, hitArea behaviour is different if element has children, I cant explain it, just give you the code: https://github.com/pixijs/pixi.js/blob/dev/packages/interaction/src/InteractionManager.js#L1030 https://github.com/pixijs/pixi.js/blob/dev/packages/interaction/src/InteractionManager.js#L1105 So, why do you need hitArea? kristof 1 Quote Link to comment Share on other sites More sharing options...
kristof Posted February 9, 2019 Author Share Posted February 9, 2019 I used hitArea because coming from it's name I thought it would solve my issue. I have used the bounding box collision detection algorithm in my game, but when I tested it for some reason I had some gaps between my 2 objects when I already got the collision alert. For this reason I thought if I reduce the size of my target sprite (its hitArea) the algorithm would work fine. Am I approaching the problem in a bad way? Do you have any suggestions? Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 9, 2019 Share Posted February 9, 2019 yeah, its a good idea, but getBounds() is not related to hitArea and to get collisions you have to convert that hitArea to global coords first... Maybe you need you own field there , and convert it every frame? I don't know , there are so many ways to do that, and its just general JS game implementation problem, not pixi problem. And if you start rotations there , getBounds() will still get you normal and not rotated rectangle, so it'll collide on corners where its not supposed to.. Its a big topic, I don't believe I have time to discuss it. What I can is to give you the references, but you have to look in docs and sources yourself. "Bounds.addFrame(transform, x0, y0, x1, y1)" can convert local bounds to global using element transform, of course if you understand what `Bounds` is and why did we make that class. You have to store your stuff in different field, because hitArea exists for interaction and not for collision. In general, NOTHING in pixi exists for collision, collision has to be your engine problem, the engine you are building on top of pixi. kristof 1 Quote Link to comment Share on other sites More sharing options...
kristof Posted February 9, 2019 Author Share Posted February 9, 2019 My objects do not rotate, they only move on the x axis so I guess I do not have to worry about the 'Bound' class, or do I? What I intended to do is: if(doCollied(player.getBounds(), enemy.hitArea)){ //collision handling } Are you telling me that I cannot compare these 2 even though they both have their width, height, x, y properties? I have checked the toGlobal() method in the docs, do I just apply on enemy.hitArea or what did you mean by that? Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 9, 2019 Share Posted February 9, 2019 yeah, because hitArea is supposed to be local. If you want it to be global, name it something else , or it will affect interaction. toGlobal() wont work on rectangle, you have to develop your own method (THE HORROR!) of transforming stuff. I think I gave you enough links to source code to get some info from it We are talking about intersection of two rectangles each with their own transform, that's a 1st grade college material, I dont know how to explain simple things, I just sit and write them like they are nothing special kristof 1 Quote Link to comment Share on other sites More sharing options...
jonforum Posted February 10, 2019 Share Posted February 10, 2019 also if this can help you ? debug this https://codepen.io/osublake/pen/eMvZmo kristof and ivan.popelyshev 1 1 Quote Link to comment Share on other sites More sharing options...
kristof Posted February 10, 2019 Author Share Posted February 10, 2019 Thank you for the answers, and the codepen link as well, the way I have solved the issue is that I was playing around with replacing my sprites with pure rectangles with the height and width of the player and the enemy sprites, and compared them to the actual sprites' appearance. I found out that the height of my player sprite is approximately twice as big as the player's sprite's height, so what I did was in the collision checking algorithm I divided height by 2 and I got an approximately perfect solution without the need of using hitArea ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.