In phaser 3 I use overlap to check for collision. My code follows:
//bulletA is an array(one of the 2 arrays where collison is being checked) it contains all my bullet sprites
//enemy1 is an array containing all the enemies, which I am testing for collision with my bullets. It contains all my enemy sprites
this.physics.add.overlap(bulletA, enemy1, collide1, null, this);
The collision detection works fine(I tested using console.log on collision). However, I need to be able to tell which specific enemy sprite in the enemy1 array is colliding with my bullets. This needs to happen so that I can play an explosion animation on the enemy, and remove that specific one from the game. Is there any way to get the specific element of the array on which overlap is being used?
The overlap function takes a callback that return the two collided object
https://photonstorm.github.io/phaser3-docs/Phaser.Physics.Arcade.ArcadePhysics.html#overlap
For instance
overlap(bulletA, enemy1, collide1)
function collide1 (ob1, ob2) {
// ob1 is the bullet that collided with the enemy
// ob2 is the enemy that collided with the bullet
}
Related
I am practicing with making players and enemies for 2d games using vanilla JavaScript and HTML Canvas. The only problem I have is that I am trying to remove the projectiles from the playerProjectiles array when the projectile goes off of the screen. This is so that the game doesn't have to keep track of a bunch of projectiles that are not even on the screen, so the game will run smoother. I have tried sifting through the array using .forEach and splicing the current projectile that it is looping through as long as that projectile is off the screen. However, using this method, if there are multiple projectiles on the screen and one of them goes off of the screen, the entire array gets spliced and all of the projectiles are removed. What am I doing wrong here? Also, would it be better to put the code for the different mechanics of the projectiles in a different function? Etc. moving the projectiles up when they are shot out, actually drawing them to the screen, splicing them from the array when they go off the screen.
function populatePlayerProjectilesArray() {
playerProjectiles.forEach(projectile => {
projectile.draw();
projectile.y -= pdy;
if(projectile.y <= 0 - projectile.rad) {
playerProjectiles.splice(projectile)
}
})
}
Array.prototype.splice()
Examples:
splice(start)
splice(start, deleteCount)
deleteCount Optional An integer indicating the number of elements in the array to remove from start. If deleteCount is omitted [...], then all the elements from start to the end of the array will be deleted.
I think you want to change your splice statement to:
playerProjectiles.splice(projectile, 1)
I have a total of 1 to 64 blobs and they all move to my mouse position. But i want them to not go into each other, in other words circle collision detection. However i can't seem to make it smooth and also push new objects after they move for the first time?
Tried checking each blob for collision with other blobs. If collosion is true, then set the distance between the blobs to their accumulated radiuses.
This is how i wrote the colliding function, but this way of doing it makes the resetting of positions too fast. I want it to be a smooth, but fast transition. Like instead of now 1 frame, lets say 10 frames. And another problem is when two objects' are distanced to their radiuses, they might collide into new ones and that will cause this code to run again, and then all blobs go crazy.
this.collide = function() {
var length = this.blobs.length; // How many blobs?
this.blobs.forEach(function(item, index) {
for (var i = 0; i < length; i++) {
// Get absolute distance between two vectors
var v0 = vectorFromTo(blob.blobs[i].pos.x, blob.blobs[i].pos.y, //[x2, y2]
item.pos.x, item.pos.y); //[x1, y1]
// if colliding, set distance between to their accumulated radiuses
if (magnitude(v0) < blob.blobs[i].r + item.r) {
item.pos.add(v0.setMag(magnitude(v0) - (blob.blobs[i].r + item.r)));
}
}
});
}
I haven't tried to code another way of doing this yet because i haven't learned about vectors in school, but i do understand them quite a bit. But what i think would work is if i checked for collision, and if they collide they go opposite directions 50% of the deficit distance, and then they check if they hit new blobs. But this would require physics right? Cause then it would have to do something with the mass and speed of the blob as well to know whats gonna happen to the new blob it crashes into?
EDIT:
This is what im looking for: https://youtu.be/QvlhRGtlcsw
This is what it currently looks like: https://youtu.be/QEpHnCgomqY
I'm having a problem I can't seem to solve when using the p5 javascript library. Essentially I want to create a random "snake" of circles in p5.js.
My code looks like this.
function setup() {
createCanvas(400, 400)
background(220)
noFill()
noLoop()
}
function draw() {
translate(200,200)
strokeWeight(1)
for(j=0;j<5;j++) {
snake()
}
}
function snake() {
rad = 10
ellipse(0,0,rad,rad)
push()
for(i=0;i<100;i++) {
a = random(0,360)
translate(rad*sin(a),rad*cos(a))
ellipse(0,0,rad,rad)
}
pop()
}
What I do is create a circle in the centre, then select a random point 360 degrees around that circle at a certain radius from it, and create a new circle there. Then I translate the centre point (the 0,0) to the centre of that new circle and start the process again.
That delivers a snake, but the problem is the circles inevitably start overlapping.
What I want to do is have my code check whether a randomly created new circle will overlap with any of the previous ones, and if it does, select a new location for that circle.
All the approaches to overlap detection in p5.js I encountered so far, however, use distance to calculate whether circles overlap. Which of course the use of translate messes up.
So if anyone has a solution for my problem, feel free to let me know.
You need to store the positions and sizes of the circles in some kind of data structure, like an array. Then check against those circles before you create a new one.
You might be able to do this using the translate() function, but if I were you I would instead do the translation myself. Instead of using the translate() function, keep track of the circle X and circle Y, and move that point as you draw new circles.
This will allow you to work in screen coordinates, which will make it easier to do collision detection.
So I'm using Three.js and I have some cubes inside of a box. I'm using the Transform Control to move the cubes around inside of the box with my mouse. I'd like to use raycasting in order to check for collisions. The question is how to I prevent the transform controller from moving the object if there is a collision? I'd like to stop it if it hits the wall. By the way, I'm on version r81 for Three.js.
UPDATE: I've used the size of the room to constrain the cubes from
moving outside of the room. This seems to work well. Is there a way
to use the cannon.js just for collisions? I don't want the momentum
or gravity or any other feature. JUST the collision check and to stop
it dead in its tracks when there is a collision.
I know this post is from a long time ago, but hopefully a googler finds this helpful. I wasn't able to stop the user from moving my object, but I was able to move it back to its proper position immediately afterward by adding some logic to the render method.
For the original poster's problem with collisions, you could attach an event listener to the transform controls and request the object to be repositioned if it is in an illegal state.
transformControls.addEventListener('objectChange', (e) => {
if (illegalPosition(this.obj.position)) {
needsReset = true;
}
lastPosition = attachedObject.position.clone();
});
and then in your render function
if (needsReset) {
attachedObject.position.set(lastPosition.x, lastPosition.y, lastPosition.z);
}
If this feels a little hacky, that's because it is. But for those of us who don't have the time or skill to read and modify TransformControls.js, I think it may prove helpful.
You could create helper raycaster and place all colliders in separate container. After movement is applied to object move raycaster to its position and test if ray intersects any of other objects in container. If yes: reset previous position for that object. In case of cube colliders you could want to raycast from cube center in multiple directions with half of side length as ray length.
Ben S does have the best and most painless way to implement collision detection with transform controls. Within a event listener.
But I don't know if the time of writing his answer he knew about or if there even was a function called "requestAnimationFrame". All you would have to do for collision detection instead of simply resetting the models position is to set up your render call within a loop (60 fps) by adding "requestAnimationFrame" to your render (I call it animate since that is more descriptive) function.
Since it is in a loop and is called when the every frame the scene is drawn it will just not allow the object to move past the point of collision.
function animate() {
// Called to draw onto screen every frame (60fps).
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
And your event listener would just look like this.
control.addEventListener('objectChange', (e) => {
// Collision detection code here. Set colliding model position here.
// No need to set it in render
});
Old post, I know. But here is a method that is still fairly simple but does not flicker or use ray casting. The biggest catch here is that you have a little bit of a bounce if you move the Transform control really quickly. But otherwise it seems to work fairly well. You can control the precision of the collision by adjusting the step value.
let transStart = null;
//capture objects position on start
control.addEventListener('mouseDown', function(){
transStart = control.object.position.clone();
})
//you'll have to provide your own collision function
control.addEventListener('objectChange', function(e){
if(collision(sphere, cube)){ stopControls() };
});
function stopControls(){
if(control.dragging && stopAt){
//calculate direction object was moving at time of collision
const s = transStart;
const e = control.object.position.clone();
const n = e.clone().sub(s).negate().normalize();
//janky hack nonsense that stops the transform control from
//continuing without making the camera controller go nuts.
control.pointerUp({button:0});
control.dragging = true;
//translate back the direction it came by the step amount and do not
//stop until the objects are no longer colliding.
//Increase the step size if you do not need super precise collision
//detection. It will save calculations.
let step = 0.00005;
while(colliding(sphere, cube)){
sphere.translateOnAxis( n, step ) ;
sphere.updateMatrix();
}
}
}
My game board
Hello , recently I started to deal with the object of Canvas and make the game a series of Atari . I have a question on how to use the methods or Canvas object is best done to my character stopped from touching the walls and move around certain tracks ? I tried to conditions such as:
if (pozX > 180 && pozX < 190) {
pozX = 185
}
Instead doing collision testing...
Map out the acceptable paths for your game characters
For example, here is part of your game board.
Here is a corresponding map of the acceptable paths. "1" represents an allowed move while "0" represents a disallowed move (a game wall). Edit: Ouch! I messed up the map in the lower right -- pardons!
Now you can refer to your acceptable move map when the player presses the arrow keys to move.
For example, if the player starts in the upper left (they start at the "blue 1"). They can move right and down because those moves map to "1"s. But they cannot move up or left because those moves map to "0"s.