I'm createing a very basic HTML5 game but I can't seem to get the collision detection to work correctly. When a bullet collides with a enemy the bullet is set alive variable is set to false, this means it is not draw and isn't used for collision detection, but it still seems it is. Here is my collision detection method
//Collision detection between bullet and enemy
for (var j = 0; j < enemies.length; j++ )
{
for (var i = 0; i < bullets.length; i++ )
{
if( pointInRect( bullets[i].xPos, bullets[i].yPos, enemies[j].xPos, enemies[j].yPos, 32, 32 ) && ( bullets[i].alive == true ) )
{
bullets[i].alive = false;
enemies[j].xPos = -100;
}
}
}
But when it does collides with an enemy sometimes, and only sometimes the bullet will just continue. can anyone see the problem? I can give some more code if needed.
Canvas
When a bullet was created. It used a recycle system that someone helped me with on stackoverflow. but we forgot to do the check on the first creation, here is the code
for (var i = 0; i < bullets.length; i++ )
{
if ( ! bullets[i].alive && ! bulletDone )
{
bulletDone = true;
bullets[i] = new Bullet( player.xPos + 14, player.yPos);
console.log( "Bullet created" );
}
}
if ( ! bulletDone )
{
bullets[bullets.length] = new Bullet( player.xPos + 14, player.yPos);
console.log( "Bullet created" );
}
Basically the line
if ( ! bullets[i].alive && ! bulletDone )
was
if ( ! bullets[i].alive)
So even if a bullet was not alive, it would still create a new bullet and then spawn two bullets.
Related
My simple JavaScript game is a Space Invaders clone.
I am using the p5.js client-side library.
I have tried many things to attempt at speeding up the game.
It start off fast, and then over time it get slower, and slower, it isn't as enjoyable.
I do not mean to show every bit of code I have. I am not showing every class, but I will show the main class where everything is happening.
Could someone eyeball this and tell me if you see anything major?
I am new to JS and new to making games, I know there is something called update()
that people use in scripting but I am not familiar with it.
Thank you.
var ship;
var flowers = []; // flowers === aliens
var drops = [];
var drops2 = [];
function setup() {
createCanvas(600, 600);
ship = new Ship();
for (var i = 0; i < 6; i ++) {
flowers[i] = new Flower(i * 80 + 80, 60);
}
flower = new Flower();
}
function draw() {
background(51);
ship.show();
ship.move();
shipDrops();
alienDrops();
dropsAndAliens();
dropDelete();
drop2Delete();
}
// if 0 drops, show and move none, if 5, etc..
function shipDrops() {
for (var i = 0; i < drops.length; i ++) {
drops[i].show();
drops[i].move();
for (var j = 0; j < flowers.length; j++) {
if(drops[i].hits(flowers[j]) ) {
flowers[j].shrink();
if (flowers[j].r === 0) {
flowers[j].destroy();
}
// get rid of drops after it encounters ship
drops[i].evaporate();
}
if(flowers[j].toDelete) {
// if this drop remove, use splice function to splice out of array
flowers.splice(j, 1); // splice out i, at 1
}
}
}
}
function alienDrops() {
// below is for alien/flower fire drops 2
for (var i = 0; i < drops2.length; i ++) {
drops2[i].show();
drops2[i].move();
if(drops2[i].hits(ship) ) {
ship.shrink();
drops2[i].evaporate(); // must evap after shrink
ship.destroy();
if (ship.toDelete) {
delete ship.x;
delete ship.y;
} // above is in progress, deletes after ten hits?
}
}
}
function dropsAndAliens() {
var randomNumber; // for aliens to shoot
var edge = false;
// loop to show multiple flowers
for (var i = 0; i < flowers.length; i ++) {
flowers[i].show();
flowers[i].move();
// ******************************************
randomNumber = Math.floor(Math.random() * (100) );
if(randomNumber === 5) {
var drop2 = new Drop2(flowers[i].x, flowers[i].y, flowers[i].r);
drops2.push(drop2);
}
//**************** above aliens shooting
// below could be method, this will ensure the flowers dont
//go offscreen and they move
//makes whtever flower hits this space become the farther most
//right flower,
if (flowers[i].x > width || flowers[i]. x < 0 ) {
edge = true;
}
}
// so if right is true, loop thru them all again and reset x
if (edge) {
for (var i = 0; i < flowers.length; i ++) {
// if any flower hits edge, all will shift down
// and start moving to the left
flowers[i].shiftDown();
}
}
}
function dropDelete() {
for (var i = drops.length - 1; i >= 0; i--) {
if(drops[i].toDelete) {
// if this drop remove, use splice function to splice out of array
drops.splice(i, 1); // splice out i, at 1
}
}
}
function drop2Delete() {
for (var i = drops2.length - 1; i >= 0; i--) {
if(drops2[i].toDelete) {
// if this drop remove, use splice function to splice out of array
drops2.splice(i, 1); // splice out i, at 1
}
}
}
function keyReleased() {
if (key != ' ') {
ship.setDir(0); // when i lift the key, stop moving
}
}
function keyPressed() {
// event triggered when user presses key, check keycode
if(key === ' ') {
var drop = new Drop(ship.x, height); // start ship x and bottom of screen
drops.push(drop); // when user hits space, add this event to array
}
if (keyCode === RIGHT_ARROW) {
// +1 move right
ship.setDir(1);
} else if (keyCode === LEFT_ARROW) {
// -1 move left
ship.setDir(-1);
} // setir only when pressing key, want continuous movement
}
Please post a MCVE instead of a disconnected snippet that we can't run. Note that this should not be your entire project. It should be a small example sketch that just shows the problem without any extra code.
But to figure out what's going on, you need to debug your program. You need to find out stuff like this:
What is the length of every array? Are they continuously growing over time?
What is the actual framerate? Is the framerate dropping, or does it just appear to be slower?
At what point does it become slower? Try hard-coding different values to see what's going on.
Please note that I'm not asking you to tell me the answers to these questions. These are the questions you need to be asking yourself. (In fact, you should have all of these answers before you post a question on Stack Overflow!)
If you still can't figure it out, then please post a MCVE in a new question post and we'll go from there. Good luck.
I am using three.js to make a simulation of the Brownian Motion and I'm stuck on a part where I need to get the little molecules to collide against each other. This is what I have so far:
function intersects(sphere, other){ //check if the distance between one sphere and the other is less than radius of both (4)
var distance = Math.sqrt((sphere.position.x - other.position.x) * (sphere.position.x - other.position.x) +
(sphere.position.y - other.position.y) * (sphere.position.y - other.position.y) +
(sphere.position.z - other.position.z) * (sphere.position.z - other.position.z));
if(distance < (4)){
return true;
} else {
return false;
}
}
function checkCollision(current){
for(var i = 0; i < balls.length; i++) {
if(intersects(balls[current], balls[i]) == true){
// balls[current].velocity.negate();
alert('hey');
}
}
}
When I run the code, I know for certain that the balls don't collide/intersect with each other, however I continuously get an alert box. I've tried to check if it's less than (sphere.radius + other.radius) but I don't think that's correct since it didn't seem to work. Also when I do keep it '< 4', it messes up the performance and it starts to run slowly at around 5 fps or less. checkCollision gets used here during the animation, so basically it checks it every time.
function animate(){
for(var i = 0; i < balls.length; i++){
balls[i].position.add(balls[i].velocity);
checkWallBoundaries(i);
checkCollision(i);
}
THREEx.WindowResize(renderer, camera);
requestAnimationFrame(animate);
renderer.render(scene, camera);
controls.update();
stats.update();
}
I don't know why I can't get this to work. If someone could help me, that'd be greatly appreciated.
edit: Here's a picture of what happens when I uncomment the balls[current].velocity.negate() line https://puu.sh/uG1eS.png. The balls keep going back and forth but they're not even remotely close to each other, so I don't know why collision is being detected
Every ball collides with itself. You need to exclude i === current
for(var i = 0; i < balls.length; i++) {
if(current === i) continue;
if(intersects(balls[current], balls[i]) == true){
alert('hey');
}
}
In this code I can't remove all children if I delete half of them?? and I got error child is not dignified while i define it? each node has children spheres (nods) and edges (lines) this method delete only nods, why? could any one help me please?
function onMouseClick( e ) {
mouseVector.x = 2 * (e.clientX / containerWidth) - 1;
mouseVector.y = 1 - 2 * ( e.clientY / containerHeight );
var raycaster = projector.pickingRay( mouseVector.clone(), camera ),
intersects = raycaster.intersectObjects( scene.children );
for( var i = 0; i < intersects.length; i++ ) {
//INTERSECTED = intersects[0].object;
INTERSECTED = intersects[i].object;
//obj = intersection.object;
alert(INTERSECTED.id);
/*1-*/ //this
//scene.remove(INTERSECTED);
/*2-*/ //or this
for ( c = 0, cl = INTERSECTED.children.length; c < cl; c ++ ) {
var child = INTERSECTED.children[ c ];
alert(child.id);
//child.parent.remove(obj);
INTERSECTED.remove(child);
//var lin = scene.children[child.id+1];
//r lin = scene.getObjectById(child.id+1, true );
// alert(child.id+1);
// INTERSECTED.remove(scene.children[child.id+1]);
}
//scene.remove(INTERSECTED);
scene.add(INTERSECTED);
animate();
}
}
I think that the problem lies in the fact that you loop an array of which you are changing the length. This has nothing to do with three.js but is a basic (beginners) error you made in your javascript code.
Maybe you should rewrite your code and use a while loop instead:
while( INTERSECTED.children.length > 0 ){
var child = INTERSECTED.children[ 0 ];
INTERSECTED.remove(child);
}
I would like to be able to select a point from my pointCloud. To do that, I found a lot of examples:
Interactive particles example
Interactive raycasting pointcloud example
So I wrote the following code:
function intersectionCheck(event)
{
if(pointClouds != null)
{
event.preventDefault();
var mouse = new THREE.Vector2();
var raycaster = new THREE.Raycaster();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
var intersections = raycaster.intersectObjects( pointClouds );
intersection = ( intersections.length ) > 0 ? intersections[ 0 ] : null;
if(intersection != null)
{
console.log(intersection.point);
sphere.position.copy( intersection.point );
}
}
}
That code was supposed to place a green sphere on the screen only if the user clicked on an entity from the pointcloud.
But it was false, the sphere appeard even if there was no entity, as shows the following screenshot:
It seemed that there was a problem with the size of my entities, because the function returned me a position even if I was far away from any entity.
So I changed the way that the position was selected. I checked if the distanceToRay of the point was smaller than sizeOfMyEntities/2.
if(intersection != null)
{
for(var i = 0; i < intersections.length; i++)
{
var testPoint = intersections[i];
if(material.size/2 > testPoint.distanceToRay)
{
point = intersections[i].point;
console.log(point);
sphere.position.copy(point);
break;
}
}
}
Now it works fine, but I'd like to understand why it was not working before. Why is that verification not done in the intersection process?
And also I would like to know if my second function was ok, or if it's a weird way to do what I want.
Is there a better way to do the same?
ps: I am new with all that kind of stuff, so if I am wrong please explain me :D
I create a panorama has a compass in the middle, the compass is pointing towards the top center of the image, initially.
Now I want to move the compass with respect to this point, since it is a 360 panorama, it creates an adjacent duplicate. So what I wanted is to point the compass to the point to whichever point is closer as you move from left to right or right to left.
Here is the what I have done so far, which doesn't behave like what I wanted.
So here is the code for that: https://gist.github.com/joeyhipolito/8678bf35dba7795de4d5
What I did is that I created two points:
points.push({
x: target.offset().left + (windowWidth) / 2,
y: target.offset().top
});
points.push({
x: (target.offset().left + (windowWidth) / 2) + (common.width / 2),
y: target.offset().top
});
And then try to calculate which points is closer to the reference by pythagorean theorem
var closestPoint = points[0];
var closestValue = Math.sqrt(Math.pow(points[0].x, 2) + Math.pow(points[0].y, 2));
for (var i = 1; i >= points.length; i++) {
var z = Math.sqrt(Math.pow(points[i].x, 2) + Math.pow(points[i].y, 2));
if(z < closestValue) {
closestPoint = points[i];
closestValue = z;
}
};
What do you think I am missing out?
You seem to have an issue with the control of your for loop. This loop:
for (var i = 1; i >= points.length; i++) {
};
(note the exit condition) does not run, because 1 (initial value of i) is immediately below the array's length, which is presumably at least 2. On the other hand, if the array length was at most 1, then this loop will never terminate, as i will keep increasing, and the i>=length statement remains true.
You probably want to change that exit condition to i<=length, then the minimum-finding logic should be fine.
Change
// ↓↓
for ( var i = 1; i >= points.length; i++ ) {
// ...
};
to
// ↓
for ( var i = 1; i < points.length; i++ ) {
// ...
};
Another way to do this is using Array.reduce(). It may not be as quick, but it may be more semantic:
function distFromOrigin( point ) {
return Math.sqrt( Math.pow( point, 2 ) + Math.pow( point, 2 ) );
}
var closestPoint = points.reduce(
function( closestPoint, currPoint, index, array ) {
var currDist = distFromOrigin( currPoint ),
closestDist = distFromOrigin( closestDist );
if ( currDist < closestDist ) {
return currPoint;
} else {
return closestPoint;
}
}
);