This site requires JavaScript, please enable it in your browser!
Greenfoot back
Recorsi
Recorsi wrote ...

2017/9/25

make smaller/better hitboxes

Recorsi Recorsi

2017/9/25

#
Hello, i made a little scenario where you can fly around with a spaceship and shoot rocks. if you touch the rock with the ship it explodes. now i have the problem that it gets destroyed even if you dont hit the rock because the hitboxes are squares. How can i fix this? The spaceship The Rock thanks :)
danpost danpost

2017/9/26

#
You could try a different collision method (maybe having spaceship use the getNeighbours method). You could ask a neighboring rock to try getObjectsInRange back on the ship as a further stipulation. That way you are taking into account the near circular shape of the rock as well as the "diamond" shape of the ship. I think the combination of the two checks might make collision look a lot more reasonable.
Recorsi Recorsi

2017/9/27

#
Im a noob at programming can you maybe show me how to use the getNeighbours method with getObjectsInRange pls? The spaceship code:
import greenfoot.*;  

/**
 * The main actor.
 * 
 * @author (your name) 
 * @version 23.09
 */
public class Spaceship extends Actor
{
   private static final int NUM_FRAGMENTS = 20;
   GifImage myGif = new GifImage("spaceship.gif");
   private int dx;
   private int dy;
   Laser laser = new Laser();
   GreenfootSound Ton1 = new GreenfootSound("Laser.wav");
   private int horizontalSpeed = 5;
   private int verticalSpeed = 5;
   explosion explosion = new explosion();
   GreenfootSound Ton6 = new GreenfootSound("Explosion.mp3");
   private double v = 0;
   private int speed = 0;
   private static final int MAX_SPEED = 15;
   private int delay;
   private static final int MAX_DELAY = 20;
   GreenfootSound Ton = new GreenfootSound("Engine.mp3");
   public Spaceship()
   {
      GreenfootImage image = getImage();  
      image.scale(75, 52);
      setImage(image);
   }    
   public void act() 
   {
      Bewegen();
      pruefeKontaktRand();
      shoot();
      GIF();
      TriggerEx();
   }
   public boolean TriggerEx()
    {
        if (getOneIntersectingObject(Rock.class) != null)
        {
            explode2();
            //Ton6 gibt Fehler
            //Ton6.play();
            //Explosion noch nicht funktionabel
            //getWorld().addObject(explosion, getX()+1, getY()+1);
        }
        return false;
    }
   private void GIF()
   {
       setImage( myGif.getCurrentImage() );
       GreenfootImage image = getImage();
       image.scale(75, 52);
       setImage(image);
    }
   private void Bewegen()
   {
    

      if (Greenfoot.isKeyDown("a"))
       {
            turn(-4);
       } 
      if (Greenfoot.isKeyDown("d"))
       {
            turn(4);
       }
      if (Greenfoot.isKeyDown("w"))
       {
           
           speed++;
           if (speed > MAX_SPEED) speed = MAX_SPEED;
       } else if (speed > 0) speed--; move(-speed/3); 
    if (Greenfoot.isKeyDown("w"))
    {
        Ton.playLoop();
        Ton.setVolume(100);
    } else 
    {
        Ton.pause();
    }
      
      
      /*if (Greenfoot.isKeyDown ("w") && Greenfoot.isKeyDown("a"))
      {
          setRotation(310);
          
        }
      if (Greenfoot.isKeyDown ("w") && Greenfoot.isKeyDown("d"))
      {
          setRotation(50);
         
        } 
      if (Greenfoot.isKeyDown ("s") && Greenfoot.isKeyDown("a"))
      {
          setRotation(225);
         
        }
      if (Greenfoot.isKeyDown ("s") && Greenfoot.isKeyDown("d"))
      {
          setRotation(140);
          
        }  
  */ }
  private void pruefeKontaktRand()
  {
    if (getX() >=626) {
        dx = -dx;
        }  
    if (getX() <=14) {
        dx = -dx;
        }
    if (getY() >=466) {
        dy = -dy;
        }
    if (getY() <=14) {
        dy = -dy;
        }
}
/*private void shoot()
{
    if(Greenfoot.isKeyDown("space"))
    {
       World Spielfeld = getWorld();
       Spielfeld.addObject(laser, 0, 0);
       laser.setLocation(getX(), getY());
       laser.setRotation(getRotation()-90);
       Ton1.play();
       Ton1.setVolume(75);
    }
}*/
private void shoot()
 {
  if("space".equals(Greenfoot.getKey())){
    Laser laser = new Laser();
    getWorld().addObject(laser, getX(), getY());
    laser.setRotation(getRotation()-180);
    laser.move(40);
    Ton1.play();
  }
 }
public void explode2()
 {
   placeDestroyed (getX(), getY(), NUM_FRAGMENTS);
   getWorld().removeObject(this);
   Ton.stop();
 }
private void placeDestroyed(int x, int y, int numFragments)
{
   for (int i=0; i < numFragments; i++) {
       getWorld().addObject(new Destroyed(), x ,y );
    }
 }
}
thx :D
danpost danpost

2017/9/27

#
You would have something like this in the Spaceship class:
public void TriggerEx()
{
    Rock rock = (Rock)getOneInterssectingObject(Rock.class);;
    if (rock != null && getNeighbours(getImage().getWidth()/2, false, Rock.class).contains(rock) && rock.hitsShip(this))
    {
        explode2();
        //Ton6 gibt Fehler
        //Ton6.play();
        //Explosion noch nicht funktionabel
        //getWorld().addObject(explosion, getX()+1, getY()+1);
    }
}
Line 4 says if any rock is found touching the ship, see if it is within diamond hit box of ship; and if so, ask rock to check if ship is within circle hit box of rock. Then this in the Rock class:
public boolean hitsShip(Ship ship)
{
    return getObjectsInRange(getImage().getWidth()/2, Ship.class).contains(ship);
}
If you want to visually see what these hit boxes look like, check out my Hitbox Visualizer scenario.
Recorsi Recorsi

2017/9/29

#
Thank you it worked :) but can i do something like
getImage().getWidth()/1.5
? or how do i half the number?
danpost danpost

2017/9/29

#
The code you gave tries to get two-thirds the width, which I would do by way of a fraction (always multiplying first):
getImage().getWidth()*2/3
For half width, just divide by two (which is what I used in both code sets above).
You need to login to post a reply.