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

2014/8/18

How do I set values in an array at the start of a class?

1
2
K_wow K_wow

2014/8/18

#
I've been trying to create classes that use multiple different images in an array, but I want to set the contents of the array before the constructor so that I don't have to create a number of images whenever the object is created. I thought it was something like this:
1
2
3
4
5
private GreenfootImage[] images = new GreenfootImage[10]
[
    new GreenfootImage("bullet"),
    new GreenfootImage("shotgun_pellet");
]
But that's not working. Can someone help me out please?
K_wow K_wow

2014/8/18

#
Never mind, I figured it out:
1
2
3
4
private GreenfootImage[] images = {
        new GreenfootImage("bullet"),
        new GreenfootImage("shotgun_pellet")
    };
Hope this helps anyone having the same problem!
danpost danpost

2014/8/18

#
K_wow wrote...
Never mind, I figured it out:
1
2
3
4
private GreenfootImage[] images = {
        new GreenfootImage("bullet"),
        new GreenfootImage("shotgun_pellet")
    };
Hope this helps anyone having the same problem!
This will cause the images to be created each time an object of the class is created. To have them created before any objects of the class are created (or at compile time), you need to make the fields 'static'. Making them 'final' would probably be a good idea also (since they would be constant fields):
1
2
private static final GreenfootImage[] IMAGES = {
// etc.
K_wow K_wow

2014/8/18

#
Thanks. :) I'm also having an issue with another part of this class, which is setting a random rotation. Here is my code:
1
setRotation(a.getRotation() + (Greenfoot.getRandomNumber(s * 2) - s));
but it seems to set such an orderly rotation, to the point where two objects created at the same time will set the same rotation!
K_wow K_wow

2014/8/18

#
Upon further inspection it would seem that the bullets did set to slightly different rotations, but they still occupied the same space exactly. I conclude that this is simply caused by the way greenfoot moves objects, but is there some way around it?
danpost danpost

2014/8/18

#
You will have to track the coordinates of the bullets more accurately by either using 'double' values or by multiplying and dividing by a factor (or quotient). Then, use 'setLocation' instead of 'move'. Using 'doubles', you would use 'setLocation((int) xDouble, (int) yDouble)'. Here you can work with decimal values. Using a factor, you would use 'setLocation(xFactor/factor, yFactor/factor)'. Here you can work with int values less than the factor which, in themselves, become fractional values. I kind of prefer this way as int value operations are handled much faster than double operations.
K_wow K_wow

2014/8/18

#
Then, wouldn't I have to use some kind of mathematical equation to find out which way to move the bullet based on the bullet's rotation? That's some pretty advanced math, which I unfortunately don't know.
danpost danpost

2014/8/18

#
With either way, you will have to get the vertical and horizontal differences in location for the direction of movement, which makes dx equal to cos(angle)*speed and dy equal to sin(angle)*speed, where angle is in radians, not degrees. With
1
private double exactX, exactY;
as your fields to hold your exact coordinates, and the following method
1
2
3
4
5
public void addedToWorld(World world)
{
    exactX = (double) getX();
    exactY = (double) getY();
}
to initialize the fields,
1
2
double dx = Math.cos(getRotation()*Math.PI/180)*speed;
double dy = Math.sin(getRotation()*Math.PI/180)*speed;
or
1
2
double dx = Math.cos(Math.toRadians(getRotation())*speed;
double dy = Math.sin(Math.toRadians(getRotation())*speed;
would get the movement per act along both the horizontal and vertical. Then,
1
setLocation((int)(exactX += dx), (int)(exactY += dy));
should move the object along its trajectory.
K_wow K_wow

2014/8/18

#
Thanks for that! The second initializing option didn't seem to be affected at all by the speed of the bullet, but the first option worked just great!
danpost danpost

2014/8/19

#
Oh. The second one was supposed to be:
1
2
double dx = Math.cos(Math.toRadians(getRotation()))*speed;
double dy = Math.sin(Math.toRadians(getRotation()))*speed;
with another closing parenthesis before '*speed' in both lines.
K_wow K_wow

2014/8/19

#
Ah, ok. Is the second option any more accurate than the first?
K_wow K_wow

2014/8/19

#
Also, another problem I'm having with my game is that when too many keys are held down at once, some of the keys lock in, meaning that characters can get stuck moving or attacking. This is really bad for the game, as movement must be precise and attacking must be timed. I'm pretty sure this is just a problem with the computer/keyboard, but do you know of a way to prevent this?
danpost danpost

2014/8/19

#
K_wow wrote...
Ah, ok. Is the second option any more accurate than the first?
Nope. The second option just uses a method call to do the conversion instead of converting it yourself as in the first option.
danpost danpost

2014/8/19

#
K_wow wrote...
Also, another problem I'm having with my game is that when too many keys are held down at once, some of the keys lock in, meaning that characters can get stuck moving or attacking. This is really bad for the game, as movement must be precise and attacking must be timed. I'm pretty sure this is just a problem with the computer/keyboard, but do you know of a way to prevent this?
Will need to see relevant codes (image field declarations, key detection, movement/attacking codes).
K_wow K_wow

2014/8/19

#
Here's the movement code:
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
if (Greenfoot.isKeyDown(leftKey))
{
    setRotation(180);
    move(speed);
}
if (Greenfoot.isKeyDown(rightKey))
{
    setRotation(0);
    move(speed);
}
if (Greenfoot.isKeyDown(upKey))
{
    setRotation(270);
    move(speed);
}
if (Greenfoot.isKeyDown(downKey))
{
    setRotation(90);
    move(speed);
}
if (Greenfoot.isKeyDown(downKey) && Greenfoot.isKeyDown(rightKey))
{
    setRotation(45);
}
if (Greenfoot.isKeyDown(downKey) && Greenfoot.isKeyDown(leftKey))
{
    setRotation(135);
}
if (Greenfoot.isKeyDown(upKey) && Greenfoot.isKeyDown(leftKey))
{
    setRotation(225);
}
if (Greenfoot.isKeyDown(upKey) && Greenfoot.isKeyDown(rightKey))
{
    setRotation(315);
}
if (!Greenfoot.isKeyDown(leftKey) && !Greenfoot.isKeyDown(rightKey) && !Greenfoot.isKeyDown(upKey) && !Greenfoot.isKeyDown(downKey))
{
    isWalking = false;
}
else
{
    isWalking = true;
}
Here's my attacking code:
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
if (Greenfoot.isKeyDown(weaponKey))
{
    if (currentWeapon == 1 && swordTimer <= 0)
    {
        //getWorld().addObject(new Sword(this, getRotation(), backSwing, false), getX(), getY());
        if (backSwing)
        {
            backSwing = false;
        }
        else
        {
            backSwing = true;
        }
        swordTimer = 20;
    }
    else if (currentWeapon == 2 && gunTimer <= 0)
    {
        getWorld().addObject(new Bullet(0, 3, 20, 10, 8, 600, getArms()), getX(), getY());
        gunTimer = 5;
    }
    else if (currentWeapon == 3 && gunTimer <= 0)
    {
        for (int i = 0; i < 7; i++)
        {
            getWorld().addObject(new Bullet(1, 5, 75, 8, 30, 20, getArms()), getX(), getY());
        }
        gunTimer = 50;
        knockbackLeft = 30;
        knockbackSpeed = 3;
    }
    else if (currentWeapon == 4 && gunTimer <= 0)
    {
        getWorld().addObject(new Grenade(6, getRotation(), getArms()), getX(), getY());
        gunTimer = 60;
    }
}
if (Greenfoot.isKeyDown(specialKey))
{
    if (currentWeapon == 1 && swordTimer <= 0 && spinTimer <= 0)
    {
        //getWorld().addObject(new Sword(this, getRotation(), false, true), getX(), getY());
        backSwing = false;
        swordTimer = 60;
        spinTimer = 620;
        spinProgress = getRotation();
        // getWorld().addObject(new SpinAttackBar(this, spinTimer), getX(), getY());
    }
}
if (Greenfoot.isKeyDown(itemKey))
{
    if (currentItem == 1)
    {
        getWorld().addObject(new Medpack(4, getRotation(), 30, true), getX(), getY());
        currentItem = 0;
    }
    else if (currentItem == 2)
    {
        getWorld().addObject(new Bomb(4, getRotation(), 50, true), getX(), getY());
        currentItem = 0;
    }
}
However, I'm pretty sure this has happened with non-greenfoot games for me, so I'm not sure if the code has anything to do with it.
There are more replies on the next page.
1
2