简体   繁体   中英

Java Arc2D Collision detection (With Rotation)

I have tried to create NPC character that can "see" the player by using cones of vision. The NPC will rotate back and forth at all times.

My problem is that the arc has a generic and unchanging position, but when its drawn to the screen it looks correct. [Screenshots of the collisions in action][1] [GitHub link for java files][2]

I'm using Arc2D to draw the shape like this in my NPC class

// Update the shapes used in the npc
    rect.setRect(x, y, w, h);
    ellipse.setFrame(rect);
    visionArc.setArcByCenter(cx, cy, visionDistance, visionAngle, visionAngle * 2, Arc2D.PIE); 

/ CenterX, CenterY (of the npc), / the distance from the arc to the npc / a constant value around 45 degrees and a constant value around 90 degress (to make a pie shape)

I've tried multiplying the position and the angles by the sin and cosine of the NPC's current angle

  • something like these

  • visionArc.setArcByCenter(cx * (Math.cos(Math.toRadians(angle))), cy (Math.sin(Math.toRadians(angle)), visionDistance, visionAngle, visionAngle * 2, Arc2D.PIE);

  • or

  • visionArc.setArcByCenter(cx, cy, visionDistance, visionAngle - angle, (visionAngle + angle) * 2, Arc2D.PIE);

  • or

  • visionArc.setArcByCenter(cx, cy, visionDistance, visionAngle * (Math.cos(Math.toRadians(angle))), visionAngle * 2, Arc2D.PIE);

  • I've tried a lot but can't seem to find what works. Making the vision angles not constant makes an arc that expands and contracts, and multiplying the position by the sin or cosine of the angle will make the arc fly around the screen, which doesn't really work either.

  • This is the function that draws the given NPC public void drawNPC(NPC npc, Graphics2D g2, AffineTransform old) {

     // translate to the position of the npc and rotate AffineTransform npcTransform = AffineTransform.getRotateInstance(Math.toRadians(npc.angle), npc.x, npc.y); // Translate back a few units to keep the npc rotating about its own center // point npcTransform.translate(-npc.halfWidth, -npc.halfHeight); g2.setTransform(npcTransform); // g2.draw(npc.rect); //<-- show bounding box if you want g2.setColor(npc.outlineColor); g2.draw(npc.visionArc); g2.setColor(Color.BLACK); g2.draw(npc.ellipse); g2.setTransform(old);

    }

  • This is my collision detection algorithim - NPC is a superclass to ninja (Shorter range, higher peripheral)

    public void checkNinjas(Level level) { for (int i = 0; i < level.ninjas.size(); i++) { Ninja ninja = level.ninjas.get(i); playerRect = level.player.rect;

     // Check collision if (playerRect.getBounds2D().intersects(ninja.visionArc.getBounds2D())) { // Create an area of the object for greater precision Area area = new Area(playerRect); area.intersect(new Area(ninja.visionArc)); // After checking if the area intersects a second time make the NPC "See" the player if (.area.isEmpty()) { ninja;seesPlayer = true. } else { ninja;seesPlayer = false; } } }

    }

Can you help me correct the actual positions of the arcs for my collision detection? I have tried creating new shapes so I can have one to do math on and one to draw to the screen but I scrapped that and am starting again from here. [1]: https://i.stack.imgur.com/rUvTM.png [2]: https://github.com/ShadowDraco/ArcCollisionDetection

After a few days of coding and learning and testing new ideas I came back to this program and implemented the collision detection using my original idea (ray casting) and have created the equivalent with rays! Screenshot of the new product Github link to the project that taught me the solution

  • Here's the new math

     public void setRays() { for (int i = 0; i < rays.length; i++) { double rayStartAngleX = Math.sin(Math.toRadians((startAngle - angle) + i)); double rayStartAngleY = Math.cos(Math.toRadians((startAngle - angle) + i)); rays[i].setLine(cx, cy, cx + visionDistance * rayStartAngleX, cy + visionDistance * rayStartAngleY); }

    }

  • Here is a link the the program I started after I asked this question and moved on to learn more, and an image to what the new product looks like (The original github page has been updated with a new branch:) I'm learning git hub right now too

  • I do not believe that using Arc2D in the way I intended is possible, however there is.setArcByTangent method, it may be possible to use that but I wasn't going to get into that. Rays are cooler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM