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

2016/6/10

getRotation() not setting rotation properly

Xevinaly Xevinaly

2016/6/10

#
I am making a missile command clone and have missiles firing from both the top and the bottom. In order to add some spontaneity to the game and allow the player to aim the missiles I have the missile turn towards a certain point every time the act method is called, both the missiles created by the player and those which are "enemy" missiles have the same class. This works fine for the missiles coming from the bottom of the screen but the ones coming from the top - those which are not spawned by the player - will almost always move straight downwards for a period of time before sometimes switching their direction. To fix this I created a separate missile class in order to solve the problem which is almost identical except the code for setting the angle. In the new class so far I have tried: -Using turnTowards() only once and once the missile has reached a certain point | sometimes works but not consistently -Setting the rotation manually with setRotation() using a randomly generated angle between 45 and 135 | same results -Setting the rotation manually with setRotation() after calculating the angle between the start and end points | used both regular calculation and Law of Sines but neither gave different results from he first two. What could be causing this problem? Here is my code for both the old missiles class and new one.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
import java.util.Random;
 
/**
 * New Missile class
 */
public class CompoundMissile extends Actor
{
    private Color contrailcolor;
    private int xcoordinate, ycoordinate, startx, starty, speed, rotation;
    private Contrail contrail = new Contrail();
    private boolean end = false, start = true;
    private Random generator = new Random();
    private int[][] coordinates = new int[][]{{92, 415}, {138, 412}, {187, 414}, {297, 412}, {358, 403}, {415, 412}, {45, 410}, {245, 410}, {477, 410}};
     
    /**
     * Constructor - sets the image and contrail color
     *
     * @param color    the contrails color
     * @param setspeed the speed of the missile
     */
    public CompoundMissile(Color color, int setspeed)
    {
        setImage(new FluidImage("MissileHead.txt", 2, 2));
        contrailcolor = color;
        setRotation(90);
        rotation = 130;
        speed = setspeed;
    }
     
    /**
     * Act - do whatever the Missile wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()
    {
        if(start)
        {
            startx = getX();
            starty = getY();
            int lastposition = generator.nextInt(147) + startx - 1;
            if(startx - lastposition > 0)
                rotation = 90 - (int)Math.toDegrees(Math.asin((double)(Math.abs(startx - lastposition))/(double)(Math.sqrt(21609 + (Math.abs(startx - lastposition) * Math.abs(startx - lastposition))))));
            else
                rotation = 90 + (int)Math.toDegrees(Math.asin((double)(Math.abs(startx - lastposition))/(double)(Math.sqrt(21609 + (Math.abs(startx - lastposition) * Math.abs(startx - lastposition))))));
            System.out.println(startx);
            System.out.println(lastposition);
            System.out.println((double)Math.abs(startx - lastposition));
            System.out.println((double)(Math.abs(startx - lastposition))/(double)(150-3));
            System.out.println(Math.asin((double)(Math.abs(startx - lastposition))/(double)(150-3)));
            System.out.println(Math.toDegrees(Math.asin((double)(Math.abs(startx - lastposition))/(double)(150-3))));
            System.out.println((int)Math.toDegrees(Math.asin((double)(Math.abs(startx - lastposition))/(double)(150-3))));
            System.out.println(90 - (int)Math.toDegrees(Math.asin((double)(Math.abs(startx - lastposition))/(double)(150-3))));
            System.out.println(90 + (int)Math.toDegrees(Math.asin((double)(Math.abs(startx - lastposition))/(double)(150-3))));
            start = false;
        }
        if(getY() == 40)
            setRotation(rotation);
        move(speed);
        if(getY() >= 150)
            end = true;
        if(getOneIntersectingObject(Explosion.class) != null)
        {
            Explosion explosion = (Explosion)getOneIntersectingObject(Explosion.class);
            if(((FluidImage)getImage()).compareHitboxs(explosion.getHitbox(),explosion.getX(), explosion.getY(), getX(), getY()))
                end = true;
        }
        if(end)
        {
            getWorld().addObject(new Explosion(), getX(), getY());
            getWorld().removeObject(this);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
 
/**
 * Old Missile class
 *
 * @author Xevinaly
 * @version v0.1.0
 */
public class Missile extends Actor
{
    private Color contrailcolor;
    private int xcoordinate, ycoordinate, startx, starty;
    private Contrail contrail = new Contrail();
    private boolean end = false, start = true;
     
    /**
     * Constructor - sets the image and contrail color
     *
     * @param color the contrails color
     * @param endx  x-coordinate to turn towards
     * @param endy  y-coordinate to turn towards
     */
    public Missile(Color color, int endx, int endy)
    {
        setImage(new FluidImage("MissileHead.txt", 2, 2));
        contrailcolor = color;
        xcoordinate = endx;
        ycoordinate = endy;
    }
     
    /**
     * Act - do whatever the Missile wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()
    {
        if(start)
        {
            startx = getX();
            starty = getY();
            turnTowards(xcoordinate, ycoordinate);
            start = false;
        }
        move(10);
        if(getY() <= ycoordinate)
            end = true;
        if(getOneIntersectingObject(Explosion.class) != null)
        {
            Explosion explosion = (Explosion)getOneIntersectingObject(Explosion.class);
            if(((FluidImage)getImage()).compareHitboxs(explosion.getHitbox(),explosion.getX(), explosion.getY(), getX(), getY()))
            {
                xcoordinate = getX();
                ycoordinate = getY();
                end = true;
            }
        }
        if(end)
        {
            getWorld().addObject(new Explosion(), xcoordinate, ycoordinate);
            getWorld().removeObject(this);
        }
    }
}
danpost danpost

2016/6/10

#
What lines of code are you using to create CompoundMissile objects (both for those starting at the top and for those starting at the bottom)?
Xevinaly Xevinaly

2016/6/11

#
1
2
3
4
5
6
7
if(count > 12 && barrage > 0)
        {
            int xspawn = generator.nextInt(500);
            getWorld().addObject(new CompoundMissile(Color.GREEN, 1), xspawn, 0);
            barrage--;
            count = 0;
        }
Is how the new missiles are fired in the act method of a class called Generator which only spawns missiles
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if(Greenfoot.isKeyDown(key) && canfire > 0 && missiles > 0)
            fireMissile();
 
/**
     * fireMissile - fires a missile
     */
    private void fireMissile()
    {
        missiles--;
        getWorld().removeObject(missileimages[missiles]);
        canfire = -12;
        getWorld().addObject(new Missile(Color.BLUE, target.getX(), target.getY()), getX(), getY() - 15);
        if(missiles == 3)
        {
            message = new FluidActor("Low.txt", 30, 15);
            getWorld().addObject(message, getX(), getY() + 25);
        }
        if(missiles == 0)
            message.setImage(new FluidImage("Out.txt", 30, 15));
    }
Is how the old missiles are fired out of a class called Bunker which holds the player's missiles.
danpost danpost

2016/6/11

#
The problem is due to the limitations of the screen and the speed of your CommandMissile actors, which is one. The pixels in the screen are arranged in rows and columns. When moving one pixel, there are a limited number of ways the movement can be made -- horizontally, vertically or diagonally (to one of eight pixels). This drastically reduces the number of angles that the missile can travel at. There are a couple of ways (at least) that you can compensate for this; one is to track the location coordinates of the missile with more precision and the other is to save the starting location of the actor and count the act cycles so you can return to start and move a bit further each act cycle.
You need to login to post a reply.