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

2019/6/21

How to make the object rotate with another

1
2
3
4
MisterUnknown MisterUnknown

2019/6/21

#
My issue is, that the pipe-object moves with the tank, although it doesnt rotate. Here is the full code of the pipe:
public class Pipe extends Actor
{
    boolean didShoot = false;
    int shotCoolDown = 0;
    World myWorld = getWorld();
    BattleWorld battleWorld = (BattleWorld)myWorld;
    public int myPlayerNum;
    String shootKey = "o";
    GreenfootImage myImage;
    /**
     * Act - tut, was auch immer Rohr tun will. Diese Methode wird aufgerufen, 
     * sobald der 'Act' oder 'Run' Button in der Umgebung angeklickt werden. 
     */
    public Pipe(int playerNum, String image)
    {
        
        myImage = new GreenfootImage(image);
        myPlayerNum = playerNum;
        myImage.scale(25, 25);
        myImage = new GreenfootImage(image);
        
        if (playerNum == 1) {
            myImage = new GreenfootImage("Rohr1.PNG");
            
            shootKey = "o";
            
            
        }
        else {
            myImage = new GreenfootImage("Rohr2.PNG");
            
            shootKey = "e";
            
            
        }
        myImage.scale(50, 50);
        setImage(myImage);
    }
    public void act() 
    {
        
        shootStuff();
        didShoot = false;
        
        
        //getWorld().getObjects(Player.class).turnTowardsEnemy();
        //getWorld().getObjects(Player.class).movementEngine();
        World world = getWorld();
        List<Player> player = world.getObjects(Player.class);
        
        for (Player p : player)
        {
            p.turnTowardsEnemy();
        }
        for (Player p: player)
        {
            p.movementEngine();
        }
        
    }  
     public void shootStuff()
   {
       
        if(Greenfoot.isKeyDown(shootKey) && shotCoolDown == 0) {
            getWorld().addObject(new Bullet(getRotation()), getX(), getY());
            shotCoolDown = 20;
            didShoot = true;
        }
        if(shotCoolDown > 0)
           shotCoolDown -= 1;
    }
    
}
Here is the code of the Player-class: public void mutualmovement() { Pipe actor = (Pipe) getOneIntersectingObject(Pipe.class); if (actor != null) { actor.setLocation(this.getX(),this.getY()); } } My second problem is, that the bullets are only being shot into one direction and not even through the pipe. My goal is to make the bullets shoot through the pipe, which should be rotated like the tank itself.
danpost danpost

2019/6/21

#
The pipe is not an intersecting object -- it is connected object. I mean, sure, the player and pipe object do intersect; but, the relationship between the two is much more than that. In fact, for the most part, you will not find a pipe without a tank and, for the most part, you will not find a tank without a pipe. A pipe "belongs" to a tank. "Having" a pipe is a state of a tank. States are represented by instance fields within the class code. So:
private Pipe pipe = new Pipe();
is suggested in the Player (tank) class. You can make use of (override) the addedToWorld method to "build" the tank in the world:
protected void addedToWorld(World world)
{
    world.addObject(pipe, getX(), getY());
}
Any time your player moves or turns, you should do the same action to the pipe. This will "show" the connection between the two. The pipe can be made to turn separately if desired as like being on a turret. As far as the bullets -- we'll need to see your bullet class.
MisterUnknown MisterUnknown

2019/6/21

#
Should I put
private Pipe pipe = new Pipe();
into the constructor or into my mutualmovement()-method? Here is the code of my bullet-class:
public class Bullet extends Actor
{
    boolean justCreated = false;
    
    public Bullet(int dir)
    {
        
        setRotation(dir);
        justCreated = true;
    }
    /**
     * Act - tut, was auch immer Bullet tun will. Diese Methode wird aufgerufen, 
     * sobald der 'Act' oder 'Run' Button in der Umgebung angeklickt werden. 
     */
    public void act() 
    {
        if(justCreated) {
            justCreated = false;
            Greenfoot.playSound("gun.wav");
            move(35);
        }
        move(8);
        
        if(atWorldEdge())
            getWorld().removeObject(this);
    }    
     public boolean atWorldEdge()  
    {  
        if(getX() < 10 || getX() > getWorld().getWidth() - 10)  
            return true;  
        if(getY() < 10 || getY() > getWorld().getHeight() - 10)  
            return true;  
        else  
            return false;  
    }  
    
}
danpost danpost

2019/6/21

#
MisterUnknown wrote...
Should I put << Code Omitted >> into the constructor or into my mutualmovement()-method?
It is not to be just a variable -- it is to be a field. It does not go inside any method, but outside them.
Here is the code of my bullet-class: << Code Omitted >>
No problems spotted in the Bullet class. There should not be any issues with bullet rotation. If you still have issues, it might be best to put the shooting codes in the Player class instead of the Pipe class.
MisterUnknown MisterUnknown

2019/6/21

#
It gives me errors in return of writing the omitted code into my player-constructor so I had to add the parameters, and I am sure I make myself look like a big moron. Here is every bit of code from my player-class till the mutualmovement-method:
public class Player extends Actor
{
    String leftKey, rightKey, upKey, downKey;
    GreenfootImage myImage;
    public int myPlayerNum = 0;
    boolean didShoot = false;
    public double xVel = 0.0;
    public double yVel = 0.0;
    public double terminalSpeed = 5.0;
    public int counter;
    boolean playerContact = false;
    double currentForce = 0;
    private Pipe pipe = new Pipe(int playerNum, String image);
    public Player(int playerNum, String image, String left, String right, String up, String down)
    {
        myImage = new GreenfootImage(image);
        myPlayerNum = playerNum;
        
        leftKey = left;
        rightKey = right;
        upKey = up;
        downKey = down;
        
        myImage.scale(50, 50);
        setImage(myImage);
    }
    /**
     * Act - tut, was auch immer Player tun will. Diese Methode wird aufgerufen, 
     * sobald der 'Act' oder 'Run' Button in der Umgebung angeklickt werden. 
     */
    public void act() 
    {
        movementEngine();
        turnTowardsEnemy();
        wallBounce();
        calculateForce();
        doBulletHit(myPlayerNum);
        playerCollider();
        mutualmovement();
        
        
    }    
    public void mutualmovement()
    {
       
        Pipe actor = (Pipe) getOneIntersectingObject(Pipe.class);
        if (actor != null) {
            actor.setLocation(this.getX(),this.getY());
        }
        
    }
Already highly appreciate your help, dan. You must be more of an entity than a person, since I see you everywhere on this website and from posts that are at least six years old.
danpost danpost

2019/6/21

#
MisterUnknown wrote...
It gives me errors in return of writing the omitted code into my player-constructor so I had to add the parameters << Code Omitted >>
I do not see a need for the player number parameter for the pipe. As far as the image parameter is concerned: do you have multiple images that can be used for Pipe objects or just one?
MisterUnknown MisterUnknown

2019/6/21

#
Yeah, two to be precise.
danpost danpost

2019/6/21

#
MisterUnknown wrote...
Yeah, two to be precise.
Okay -- I will presume that each player will have a different pipe image. Use:
public Pipe pipe;
Then, after creating each player, create the pipe. For example, for each player, you could do this (in world constructor or prepare method):
Player player = new Player(...);
player.pipe = new Pipe(...);
Or, if you really wanted to, you could pass the pipe along with the other constructor parameters:
Player player = new Player(..., new Pipe(...));
MisterUnknown MisterUnknown

2019/6/22

#
It requires an identifier after compiling the code Here is my world-class:
public class BattleWorld extends World
{
    Player player = new Player(0, "tank.png", "left", "right", "up", "down");
    Player player2 = new Player(1, "tank2.png", "a", "d", "w", "s");
    Bar bar = new Bar();
    Bar bar2 = new Bar();
    public static int p1X = 100;
    public static int p1Y = 300;
    public static int p2X = 700;
    public static int p2Y = 300;
    public Pipe pipe;
    player.pipe =new Pipe(0, "Rohr1.PNG");
    //Pipe pipe1 = new Pipe(0, "Rohr1.PNG");
    //Pipe pipe2 = new Pipe(1, "Rohr2.PNG");
    player2.pipe = new Pipe(1, "Rohr2.PNG");
    /**
     * Konstruktor für Objekte der Klasse BattleWorld
     * 
     */
    public BattleWorld()
    {    
        // Erstellt eine neue Welt mit 600x400 Zellen und einer Zell-Größe von 1x1 Pixeln.
        super(800, 600, 1);
        addObject(player, 100, 300);
        addObject(player2, 700, 300);
        
        addObject(bar, 200, 40);
        addObject(bar2, 600, 40);
        addObject(pipe1,110, 300);
        addObject(pipe2, 710, 300);
        
        //addObject(playbutton, 300, 200);
    }
    public Bar getBar(int playerNum)
    {
        if (playerNum == 0)
        {
            return bar;
        }
        else
        {
            return bar2;
        }
        
    }

}
danpost danpost

2019/6/22

#
Remove line 11 thru 15 from the BattleWorld code above. Line 11 there (in BattleWorld) should replace line 13 in the Player class. Before line 24 in the BattleWorld class, insert the following:
player.pipe = new Pipe();
player.pipe.setImage(Rohr1.PNG);
player2.pipe = new Pipe();
player2.pipe.setImage(Rohr2.PNG);
MisterUnknown MisterUnknown

2019/6/22

#
 public BattleWorld()
    {    
        // Erstellt eine neue Welt mit 600x400 Zellen und einer Zell-Größe von 1x1 Pixeln.
        super(800, 600, 1);
        player.pipe = new Pipe();
        player.pipe.setImage("Rohr1.PNG");
        player2.pipe = new Pipe();
        player2.pipe.setImage("Rohr2.PNG");
        addObject(player, 100, 300);
        addObject(player2, 700, 300);
        
        addObject(bar, 200, 40);
        addObject(bar2, 600, 40);
        addObject(pipe1,110, 300);
        addObject(pipe2, 710, 300);
        
        //addObject(playbutton, 300, 200);
    }
Now it tells me that new Pipe() cannot be applied to given types required: int java.lang.String found: no arguments And when I add
int playerNum, String image
it tells me that class and ; are expected
 addObject(pipe1,110, 300);
        addObject(pipe2, 710, 300);
It can also not find these variables
Super_Hippo Super_Hippo

2019/6/22

#
Remove the parameters from the Pipe's constructor. You don't need to set an image there anymore and the playerNum shouldn't be needed there either. You may need to scale the image after setting it though. Remove the two lines which want to add pipe1 and pipe2. The pipes will be added by the player.
MisterUnknown MisterUnknown

2019/6/22

#
public Pipe()
    {
        
        //myImage = new GreenfootImage(image);
        //myPlayerNum = playerNum;
        myImage.scale(25, 25);
        //myImage = new GreenfootImage(image);
        
        if (playerNum == 1) {
            myImage = new GreenfootImage("Rohr1.PNG");
            
            shootKey = "o";
            
            
        }
        else {
            myImage = new GreenfootImage("Rohr2.PNG");
            
            shootKey = "e";
            
            
        }
        myImage.scale(50, 50);
        setImage(myImage);
    }
But how could I implement the shooting-code then?
Super_Hippo Super_Hippo

2019/6/22

#
You can probably remove the whole constructor to be honest.
public void setShootKey(String key)
{
    shootKey = key;
}
player.pipe = new Pipe();
player.pipe.setImage("Rohr1.PNG");
player.pipe.getImage().scale(50, 50);
player.pipe.setShootKey("o");
But I would probably have the shooting code in the Player's and not in the Pipe's code.
MisterUnknown MisterUnknown

2019/6/22

#
But how would It be able to have a single shootKey for each player, if I remove the whole code in public Pipe?
There are more replies on the next page.
1
2
3
4