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

2013/7/23

Physics Engine - Confusion With getY/X() via Multiple Objects

1
2
8bitcarrotjuice 8bitcarrotjuice

2013/7/23

#
The title says it all; if I have numerous same actors in the same world will getY/X() work correctly inorder to detect ground? Thanks in advance.
danpost danpost

2013/7/23

#
Each actor will have its own x and y coordinates in the world returned when using those methods.
8bitcarrotjuice 8bitcarrotjuice

2013/7/23

#
How would I detect the ground bellow me then? Can I use this method? And I need help with the detection for a filled rectangle. Here is what I have so far, I will note where I need help. I need help with detection, thanks.
import greenfoot.*;  
import java.awt.Color;  
public class Cube extends Conector  
{  
    public boolean jump;  
    private double gravity=0.2;  
    private double exactX;    
    private double exactY;     
    private boolean ready=true;  
    public boolean fall = false;  
    public double ygravity=0.2;;
    public double xgravity;
    public void addedToWorld(World world)    
    {  
        GreenfootImage image=new GreenfootImage(25,25);    
        image.setColor(new Color(205,201,201,175));    
        image.fill();   
        setImage(image);  
}  
    public void setLocation(int x, int y) {    
    exactX = x;    
    exactY = y;    
    super.setLocation(x, y);    
}          
    public void setLocation(double x, double y) {    
    exactX = x;    
    exactY = y;    
    super.setLocation((int) x, (int) y);    
}    
    public double getexactX() {    
    return exactX;    
}    
    public double getexactY() {    
    return exactY;    
}    
    public void act()   
    {  
        platnumber(); vector();

}
    public void platnumber()
{
        if(getOneIntersectingObject(Plat1.class)!=null)  {
            setLocation(getexactX(),platy1-20);  
            plat=1;
            ready=true;
            ydefiner=0;
            fall=false;
            ygravity=-0.2;
            xgravity=0;
        }
        if(getOneIntersectingObject(Plat2.class)!=null)  {
            setLocation(platy2+20,getexactY());              
            plat=2;
            ready=true;
            xdefiner=0;
            fall=false;
            ygravity=0;
            xgravity=0.2;
        }
        if(getOneIntersectingObject(Plat3.class)!=null)  {
            setLocation(getexactX(),platy3+20);              
            plat=3;
            ready=true;
            ydefiner=0;
            fall=false;
            ygravity=0.2;
            xgravity=0;
        }
        if(getOneIntersectingObject(Plat4.class)!=null)  {
            setLocation(platy4-20,getexactY());                          
            plat=4;
            ready=true;
            xdefiner=0;
            fall=false;
            ygravity=0;  
            xgravity=0.2;
        }   
        if(getOneObjectAtOffset(0,40,Plat5.class)!=null)  {       //from here I need help
            setLocation(getexactY(),platy5+40);                          
            plat=3;
            ready=true;
            ydefiner=0;
            fall=false;
            ygravity=-0.2;  
            xgravity=0;
        } 
        if(getOneObjectAtOffset(-25,25,Plat5.class)!=null)  {
            setLocation(platy5-25,getexactY());                          
            plat=2;
            ready=true;
            xdefiner=0;
            fall=false;
            ygravity=0;
            xgravity=0.2;
        }
        if(getOneObjectAtOffset(25,25,Plat5.class)!=null)  {
            setLocation(getexactY(),platy5+25);                          
            plat=1;
            ready=true;
            ydefiner=0;
            fall=false;
            ygravity=0.2;  
            xgravity=0;
        }
        if(getOneObjectAtOffset(25,25,Plat5.class)!=null)  {
            setLocation(platy5+25,getexactX());                          
            plat=4;
            ready=true;
            ydefiner=0;
            fall=false;
            ygravity=0;  
            xgravity=-0.2;
        }                                                                 //to here
} 
    public void vector()
{
        if(plat==1&&ready==true&&Greenfoot.isKeyDown("w")){
            ydefiner=-6;   
            xdefiner=0;   
            ready=false;  
            fall=true;
        }
        if(plat==2&&ready==true&&Greenfoot.isKeyDown("w")){
            ydefiner=0;
            xdefiner=6;   
            ready=false;  
            fall=true;
        }
        if(plat==3&&ready==true&&Greenfoot.isKeyDown("w")){
            ydefiner=6;  
            xdefiner=0;
            ready=false;  
            fall=true;
        }
        if(plat==4&&ready==true&&Greenfoot.isKeyDown("w")){
            ydefiner=0; 
            xdefiner=-6;   
            ready=false;  
            fall=true;
        }
        
        if(fall==true&&plat==1)
        {
            ydefiner -= ygravity;
            setLocation(getexactX()+xdefiner, getexactY()+ydefiner);
        }
        if(fall==true&&plat==2)
        {
            xdefiner -= xgravity;
            setLocation(getexactX()+xdefiner, getexactY()+ydefiner);
        }
        if(fall==true&&plat==3)
        {
            ydefiner -= ygravity;
            setLocation(getexactX()+xdefiner, getexactY()+ydefiner);
        }
        if(fall==true&&plat==4)
        {
            xdefiner += xgravity;
            setLocation(getexactX()+xdefiner, getexactY()+ydefiner);
        }
        
        if(Greenfoot.isKeyDown("a")&&plat==1){
            setLocation(getexactX()-2,getexactY());
        }
        if(Greenfoot.isKeyDown("a")&&plat==2){
            setLocation(getexactX(),getexactY()-2);
        }
        if(Greenfoot.isKeyDown("a")&&plat==3){
            setLocation(getexactX()+2,getexactY());
        }
        if(Greenfoot.isKeyDown("a")&&plat==4){
            setLocation(getexactX(),getexactY()+2);
        }
        if(Greenfoot.isKeyDown("d")&&plat==1){
            setLocation(getexactX()+2,getexactY());
        }
        if(Greenfoot.isKeyDown("d")&&plat==2){
            setLocation(getexactX(),getexactY()+2);
        }
        if(Greenfoot.isKeyDown("d")&&plat==3){
            setLocation(getexactX()-2,getexactY());
        }
        if(Greenfoot.isKeyDown("d")&&plat==4){
            setLocation(getexactX(),getexactY()-2);
        }
}}
danpost danpost

2013/7/23

#
I get the feeling that line 79 has the wrong offsets. And, lines 97 and 106 both check the same offsets.
8bitcarrotjuice 8bitcarrotjuice

2013/7/23

#
Please- someone help me; I can't get the detection correct and even if I did the gravity won't take effect on the cube. I could just draw an actor which is a filled rectangle and just add smaller actors on the edge inorder to make the detection as I did before, but do you have any idea on how I would make the getOneObjectAtOffset(x,y,clss.class) work? just saw your post- going to check it right now.
8bitcarrotjuice 8bitcarrotjuice

2013/7/23

#
still does not work, check it out http://www.greenfoot.org/scenarios/9046
danpost danpost

2013/7/23

#
If this is for your Physic Engine scenario, then you could use the 'getOneIntersectingObject(Class)' method to determine if any intersection is occurring. Then, if the object is instance of Plat1, move the cube to be 'standing' on that object; if the object is instance of Plat2, etc. If the object is instance of Plat5, then, ... well, I do not know what you want here ('stand' on Plat5 object or bounce).
8bitcarrotjuice 8bitcarrotjuice

2013/7/23

#
Plat5 is a new 'platform': A cube, not just a platform. I need to be able to determine which side he is on; I can't do that with 'getOneIntersectingObject(Class)'. I have no idea what to do.
danpost danpost

2013/7/23

#
Looking at the scenario (without downloading the update), it appears you are not taking into account the width of the Cube object when setting the cube to 'stand' on the 'filled rectangle'. Maybe you want something like this: If the object is instance of Plat5, then
int p5w = plat5.getImage().getWidth(); // plat5 width
int p5h = plat5.getImage().getHeight(); // plat5 height
int cw = getImage().getWidth(); // cube width
int ch = getImage().getHeight(); // cube height
int cx = getX(); // cube x coordinate
int cy = getY(); // cube y coordinate
int p5x = plat5.getX(); // plat5 x coordinate
int p5y = plat5.getY(); // plat5 y coordinate
if (Math.abs(cx - p5x) < (cw + p5w) / 2)
{
    if (cx - p5x > 0) setLocation(p5x + (p5w + cw) / 2, cy);
    else setLocation(p5x - (p5w + cw) / 2, cy);
}
// do the same as lines 9 through 13 with y and h values
danpost danpost

2013/7/23

#
I did say 'something like'. You may want to see the code of my Pong Pinball to see how I took care of intersecting a rectangular object. I know the code I used is quite in-depth and precise; but, you could simplify it a bit to come up with something that would work for you. (I do realize the code above will keep your cube in one quadrant and will not work properly for you).
8bitcarrotjuice 8bitcarrotjuice

2013/7/24

#
Keep getting an error:
java.lang.NullPointerException
	at Cube.platnumber(Cube.java:81)
	at Cube.act(Cube.java:39)
	at greenfoot.core.Simulation.actActor(Simulation.java:568)
	at greenfoot.core.Simulation.runOneLoop(Simulation.java:526)
	at greenfoot.core.Simulation.runContent(Simulation.java:215)
	at greenfoot.core.Simulation.run(Simulation.java:205)
Thanks, I will look at your code! Thanks for the help again.
danpost danpost

2013/7/24

#
I tried to see what I would come up with on my own. I still am not sure what kind of interplay you are wanting between the 'filled rectangle' and the cube. Anyway, this is what I came up with:
// world class 'Field'
import greenfoot.*;

public class Field extends World
{
    public Field()
    {
        super(600, 600, 1);
        addObject(new Wall(10, 560), 25, 300);
        addObject(new Wall(10, 560), 575, 300);
        addObject(new Wall(560, 10), 300, 25);
        addObject(new Wall(560, 10), 300, 575);
        addObject(new Wall(100, 100), 300, 300);
        addObject(new Cube(), 300, 545);
    }
}

// actor class 'Wall'
import greenfoot.*;
import java.awt.Color;

public class Wall extends Actor
{
    public Wall(int wide, int high)
    {
        GreenfootImage image = new GreenfootImage(wide, high);
        image.setColor(Color.darkGray);
        image.fill();
        setImage(image);
    }
}

// actor class 'Cube'
import greenfoot.*;
import java.awt.Color;

public class Cube extends Actor
{
    private int gravity;

    public Cube()
    {
        GreenfootImage image = new GreenfootImage(49, 49);
        image.setColor(Color.gray);
        image.fill();
        setImage(image);
    }

    public void act()
    {
        // gravity and jump
        gravity += 2; // add gravity
        turn(90); // face 'down'
        move(gravity); // fall faster (or rise slower)
        boolean hitWall = false;
        while (getOneIntersectingObject(Wall.class) != null)
        { // move off any intersecting wall
            hitWall = true;
            move(-(int)Math.signum(gravity));
        }
        if (hitWall)
        { // add buffer space and stop fall (or rise)
            move(-(int)Math.signum(gravity));
            gravity = 0;
            // jump on command
            if (Greenfoot.isKeyDown("w") || Greenfoot.isKeyDown("up")) gravity -= 30;
        }
        turn(-90); // re-face 'forward'
        // left and right
        int d = 0; // to hold direction input by user
        if (Greenfoot.isKeyDown("a") || Greenfoot.isKeyDown("left")) d--;
        if (Greenfoot.isKeyDown("d") || Greenfoot.isKeyDown("right")) d++;
        if (d != 0)
        {
            move(4*d); // move in given direction
            if (getOneIntersectingObject(Wall.class) != null)
            { // intersecting wall after side movement
                turn(-90*d); // new gravity direction
                move(d); // add buffer from old ground wall
                gravity = 0;
            }
        }
    }
}
8bitcarrotjuice 8bitcarrotjuice

2013/7/28

#
Sorry I'm replying so late on this; I am on a vacation, so I can not try the code you have stated. The code looks awesome! Thanks, and I will get back to you tomorow(I will be home by then!). Dan, can you explain to me what the signum does? I googled it, and found some results that I have read but do not fully understand it. Thanks in advance!
danpost danpost

2013/7/28

#
Put simply, 'signum' return -1, 0 or +1 depending on the sign of the argument.
8bitcarrotjuice 8bitcarrotjuice

2013/7/29

#
Hey Dan, I tried your code and it's awesome, but as for the changing of gravity and detection of wall it's not that great :/. I know this would be a noobish aproach, but I would just have a cube(10x10pix) which would have the statement
public void addedToWorld(World world)    
{    
    int x=getexactX();
    int y=getexactY();
    World world=(Field)getWorld();
    world.addObject(new Side1(), x-5,y);
    world.addObject(new Side2(), x,y+5);
    world.addObject(new Side3(), x+5,y);
    world.addObject(new Side4(), x,y-5);
}   
Oh, and just to clarify, the sides are going to be used in conjunction with GetOneIntersectingObject(...) in order to change gravity. I know this is a pretty nooby way of doing this, but I am not that good at coding. I just though of another way, where I would get the cubes X & Y and just build on making paramiters; what do you think? Which method should I do?
There are more replies on the next page.
1
2