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

2014/12/9

Trying to let a bullet fly in a correct angle

1
2
UNDEAD_DC UNDEAD_DC

2014/12/9

#
For my tank game i am trying to let a bullet fly from a tank the bullets gets added to the world using 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;      
    } 
and the code i have in the shell itself is:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class TankShell here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class TankShell extends Ammo
{
    /**
     * Act - do whatever the TankShell wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    private int speed1 = 5;
    public void act() 
    {
        // Add your action code here.
        //move(5);
        Smove();
        checkSide();
    }    
    public void Smove()
    {
        int x1 = getX();  
        int y1 = getY();  
        int ww1 = getWorld().getWidth();  
        int wh1 = getWorld().getHeight();
        
        x1 += Math.cos(Math.toRadians(getRotation()))*speed1;  
        y1 += Math.sin(Math.toRadians(getRotation())) * speed1;  
        x1 = 1+(x1+(ww1-3))%(ww1-2);  
        y1 = 1+(y1+(wh1-3))%(wh1-2);  
        setLocation((int)x1, (int)y1);
    }
}
anyone can help me why it doesnt want to go in the correct angle and only wants to go 45* 90* etc etc
danpost danpost

2014/12/9

#
The first code posted is not adding the bullet into the world.
UNDEAD_DC UNDEAD_DC

2014/12/11

#
danpost wrote...
The first code posted is not adding the bullet into the world.
O selected the wrong one i see. this is the correct bit of code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Turret here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Turret extends Actor
{
    /**
     * Act - do whatever the Turret wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()   
        {  
            MouseInfo m = Greenfoot.getMouseInfo();    
            if(m != null)  {
                turnTowards(m); 
            }
            
            Tank Tank = (Tank)getWorld().getObjects(Tank.class).get(0);
            int x = 5;
            x = Tank.getX();  
            int y = 5;
            y = Tank.getY(); 
            setLocation(x, y);
            if (Greenfoot.mouseClicked(null)) 
            { 
                Turret Turret = (Turret)getWorld().getObjects(Turret.class).get(0);
                int a = Turret.getX(); 
                int b = Turret.getY(); 
                int c = Turret.getRotation();
                //getWorld().addObject(new TankShell(), x, y); 
                TankShell ts = new TankShell(){};
                ts.turn(c);
                getWorld().addObject(ts, x, y);
                
            }
        }      
    public void turnTowards (MouseInfo mi)    
        {    
            turnTowards(mi.getX(), mi.getY());    
        }    
       

}
danpost danpost

2014/12/11

#
Line 30 of the Turret class is looking for a Turret object .. why, when 'this' IS the Turret object. And is not the turret on the tank? Line 22 should use 'getOneIntersectingObject' -- not 'getWorld()...'. What would happen if you added more tanks (with turrets) into the world? You would not know which one would be returned! (in either case)
UNDEAD_DC UNDEAD_DC

2014/12/11

#
thanks i made it now this.getRotation and this.getX, But i dont get how to implement getOneIntersectingObject, when i add it it gives an error about Turret cannot be converted to java.lang.Class. and this doesnt solve the main problem yet about the direction the bullets are flying.
danpost danpost

2014/12/11

#
Please re-post your act method as it currently is.
UNDEAD_DC UNDEAD_DC

2014/12/11

#
from the turret:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Turret here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Turret extends Actor
{
    /**
     * Act - do whatever the Turret wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()   
        {  
            MouseInfo m = Greenfoot.getMouseInfo();    
            if(m != null)  {
                turnTowards(m); 
            }
            
            Tank Tank = (Tank)getWorld().getObjects(Tank.class).get(0);
            int x = 5;
            x = Tank.getX();  
            int y = 5;
            y = Tank.getY(); 
            setLocation(x, y);
            if (Greenfoot.mouseClicked(null)) 
            { 
                Turret Turret = getOneIntersectingObject(Turret);
                int a = this.getX(); 
                int b = this.getY(); 
                int c = this.getRotation();
                //getWorld().addObject(new TankShell(), x, y); 
                TankShell ts = new TankShell(){};
                ts.turn(c);
                getWorld().addObject(ts, x, y);
                
            }
        }      
    public void turnTowards (MouseInfo mi)    
        {    
            turnTowards(mi.getX(), mi.getY());    
        }    
    public void turnTowards (int x, int y)    
        {    
            double dx = x - getX();    
            double dy = y - getY();    
            double angle = Math.atan2(dy,dx)*180.0/(Math.PI);  
            setRotation( (int)angle );    
    }    

}
from the tankshell:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class TankShell here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class TankShell extends Ammo
{
    /**
     * Act - do whatever the TankShell wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    private int speed1 = 5;
    public void act() 
    {
        // Add your action code here.
        //move(5);
        Smove();
        checkSide();
    }    
    public void Smove()
    {
        int x1 = getX();  
        int y1 = getY();  
        int ww1 = getWorld().getWidth();  
        int wh1 = getWorld().getHeight();
        
        x1 += Math.cos(Math.toRadians(getRotation()))*speed1;  
        y1 += Math.sin(Math.toRadians(getRotation())) * speed1;  
        x1 = 1+(x1+(ww1-3))%(ww1-2);  
        y1 = 1+(y1+(wh1-3))%(wh1-2);  
        setLocation((int)x1, (int)y1);
    }
}
danpost danpost

2014/12/11

#
The error message is because of line 30 in the Turret class. You do not have the dot-class, '.class', after the name of the class, 'Turret'. However, you can remove that line, as well as several others below it. We will get back to that. Line 22 in the Turret class is where 'getOneIntersectingObject' should be used. Change that line to:
Actor tank = getOneIntersectingObject(Tank.class);
It does not need to be typecast as a Tank object because you will only be using Actor class methods on it ('getX' and 'getY'). Still, this is not the best way to go about keeping the turret on the tank. If another tank happens to intersect the turret, which tank will 'getOneIntersectingObject' return? Your guess is as good as mine. The best way is to have a tank assigned to the turret. That way there will be no confusion. You can use the 'getOneIntersectingObject' method in an 'addedToWorld' method to initially determine the tank it belongs to. Have a reference to that tank saved in a field that holds an Actor (or Tank) reference. Now for the block of code between lines 29 and 39 of the Turret class. You should be able to replace lines 30 through 38 with the following:
TankShell ts = new TankShell();
ts.setRotation(getRotation());
addObject(ts, getX(), getY());
The turret should already be located at the same place as the tank from previous code in the method (lines 22 through 27). So, it should not matter that we use the location of the turret instead of the location of the tank. If you declared the reference field as 'private Actor tank;' and added the 'addedToWorld' method to assign its value, then lines 22 through 27 can be replaced with this:
setLocation(tank.getX(), tank.getY());
UNDEAD_DC UNDEAD_DC

2014/12/15

#
hi. there wont be a problem with multiple tanks because it will only be possible to have 1 tank. also implemented the bit of code you gave me but for some reason the bullets still wont fly towards the mouse but still use the 22,5* angle Turret code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Turret here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Turret extends Actor
{
    /**
     * Act - do whatever the Turret wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()   
        {  
            MouseInfo m = Greenfoot.getMouseInfo();    
            if(m != null)  {
                turnTowards(m); 
            }
            
            Actor tank = getOneIntersectingObject(Tank.class);
            int x = 5;
            x = tank.getX();  
            int y = 5;
            y = tank.getY(); 
            setLocation(x, y);
            if (Greenfoot.mouseClicked(null)) 
            { 
                TankShell ts = new TankShell();
                ts.setRotation(getRotation());
                getWorld().addObject(ts, this.getX(), this.getY());
            }
        }      
    public void turnTowards (MouseInfo mi)    
        {    
            turnTowards(mi.getX(), mi.getY());    
        }    
    public void turnTowards (int x, int y)    
        {    
            double dx = x - getX();    
            double dy = y - getY();    
            double angle = Math.atan2(dy,dx)*180.0/(Math.PI);  
            setRotation( (int)angle );    
    }    

}
tankshell code: import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * Write a description of class TankShell here. * * @author (your name) * @version (a version number or a date) */ public class TankShell extends Ammo { /** * Act - do whatever the TankShell wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ private int speed1 = 5; public void act() { // Add your action code here. //move(5); Smove(); checkSide(); } public void Smove() { int x1 = getX(); int y1 = getY(); int ww1 = getWorld().getWidth(); int wh1 = getWorld().getHeight(); x1 += Math.cos(Math.toRadians(getRotation()))*speed1; y1 += Math.sin(Math.toRadians(getRotation())) * speed1; x1 = 1+(x1+(ww1-3))%(ww1-2); y1 = 1+(y1+(wh1-3))%(wh1-2); setLocation((int)x1, (int)y1); } }
UNDEAD_DC UNDEAD_DC

2014/12/15

#
changed line 22 back to this:
Tank Tank = (Tank)getWorld().getObjects(Tank.class).get(0);
            int x = 5;
            x = Tank.getX();  
            int y = 5;
            y = Tank.getY(); 
            setLocation(x, y);
because with the intersectingobject the turret cannot find the tank back when driving into a wall
danpost danpost

2014/12/15

#
In truth, the location of the turret should be controlled by the tank and the code for moving one should be with the code to move the other. If the rotation of the turret was not controlled by the location of the mouse, then the tank should also have a part in the rotation of the turret (every time the tank turns, the turret should turn with it. Any other controlled turning of the turret should be done separately. As in real life, as programmed (you might say). The turret, in real life, does not say, oops, the tank moved, I need to catch up to it; it is forcibly moved by the tank. As far as the direction of the shells, your 'Smove' method is still using unmagnified int values. You need to track the location using double types or magnify the distances (track using int values that are multiplied by a factor; but, setting location by the values divided by that factor).
UNDEAD_DC UNDEAD_DC

2014/12/16

#
I understand your point but what does it have to do with my code? for now i just want this to work correct. I dont really understand the last part of your message, I now have it changed to doubles:
public class TankShell extends Ammo
{
    /**
     * Act - do whatever the TankShell wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    private double speed = 5;
    int test = 5;
    public void act()
    {
        double a = getX();  
        double b = getY();  
        int ww = getWorld().getWidth();  
        int wh = getWorld().getHeight();
        checkSide();
        if (test==5)   
        {  
            a += Math.cos(Math.toRadians(getRotation()))*speed;  
            b += Math.sin(Math.toRadians(getRotation())) * speed;  
            setLocation((int)a, (int)b);  
        }  
    }
and that still doesnt work, tried doing what u said with multiplying and deviding but i dont really understand how that works.
davmac davmac

2014/12/16

#
        double a = getX(); 
        double b = getY();  
That's not tracking the position using double precision, it's just retrieving the integer based values and storing it into double-precision variables. You need to save the precise location across act calls (i.e. in instance variables).
UNDEAD_DC UNDEAD_DC

2014/12/17

#
How do I save them that way? I don't have a clue how i should fix it:(
danpost danpost

2014/12/17

#
You need to declare the double values outside the method so the value is retained between act cycles. Then you need to set their initial values using your lines 11 and 12 (minus the declared types) in the addedToWorld method. Setting their initial values cannot be accomplished until the actor is added into the world (so, the constructor is ruled out as a place to put that code) and you only want to set their initial values once (so, the act method is ruled out as a place to put that code). From then on, you will be adjusting those values by adding the results of lines 18 and 19 (continuous action goes in the act method).
There are more replies on the next page.
1
2