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

2016/9/10

Code Not Working

Freekywill Freekywill

2016/9/10

#
Hello, I am currently working on a game that involves an inventory and crafting window. These two menus are separate from each other and will never be opened at the same time. I have come into a problem I have no idea how to fix. The code following is how I detect if you press a button to open your inventory or crafting window. This is the code to open my crafting menu. "e" checks for the inventory being opened, so it will close out of the crafting menu.
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
private void checkKey()
{
    key = Greenfoot.getKey();
    if ("e".equals(key))
    {
        if(!open)
        {
            open = !open;
            CloseCrafting();
        }
        else
        {
            open = !open;
            CloseCrafting();
        }
    }
    if ("c".equals(key))
    {
        if(!open)
        {
            open = !open;
            OpenCrafting();
        }
        else
        {
            open = !open;
            CloseCrafting();
        }
    }
}
I have almost the exact same code in my inventory, with a view differnt methods/variables. The inventory opening works perfectly fine, however the crafting menu will not open up, UNLESS I comment out the "key = Greenfoot.getKey();" line in the inventory.
danpost danpost

2016/9/10

#
The problem is most likely due to the use of 'Greenfoot.getKey'. This method will not return the same key multiple times during the same act cycle. Most likely, it will return 'null' on any successive attempt to use it (unless it is not called long enough for more than one key to be stored in the keyboard buffer -- then it will return each successively released key). Better would be to use the 'Greenfoot.isKeyDown' method. You will need a conditional that can detect whether the crafting is open or not. This may only be a check for a specific type object in the world or you may need to keep the 'boolean open' field. Basically:
1
2
3
4
5
6
7
8
9
10
if (!open && Greenfoot.isKeyDown("e"))
{
    open = true;
    OpenCrafting();
}
if (open && Greenfoot.isKeyDown("c"))
{
    open = false;
    CloseCrafting();
}
If you post your 'OpenCrafting' and 'CloseCrafting' methods, I might be able to eliminate the 'boolean open' field for you (show any other place(s) that the field is used). Anything that can be ascertained without the use of an extra field should be done so without it. This helps keep your code cleaner and avoids possible coding errors (usually from not keeping the value of the field up to date).
Freekywill Freekywill

2016/9/10

#
I think I may have confused you, I am using the "c" key to both open and close the crafting window. The "e" key is only used to open and close the inventory, and close the crafting window if it is open so they don't overlap. I have the "open" variable to determine if the crafting window should open or close when the "c" key. That is also why I am not using the "isKeyDown" method, because if I press the "c" key once, it will open and close multiple times unless I pressed and released the key in a very fast time. This all the current code I have for the crafting menu.
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
76
77
78
79
80
81
82
83
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
 
/**
 * Write a description of class Store here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class Crafting extends Actor
{
    public static Button[] buttons = new Button[10];
    boolean open = false;
    int t;
    private String key;
    boolean b;
    public void act()
    {      
        if(!b)
        {
            Buttons();
            b = !b;
        }  
        this.checkKey();  
    }  
 
    private void checkKey()
    {
        key = Greenfoot.getKey();
        if (Greenfoot.isKeyDown("e"))
        {
            if(!open)
            {
                open = !open;
                CloseCrafting();
            }
            else
            {
                open = !open;
                CloseCrafting();
            }
        }
        if (Greenfoot.isKeyDown("c"))
        {
            if(!open)
            {
                open = !open;
                OpenCrafting();
            }
            else
            {
                open = !open;
                CloseCrafting();
            }
        }
    }
 
    public void CloseCrafting()
    {
        for (int i=0; i<buttons.length; i++)
        {
            getWorld().removeObject(buttons[i]);
        }
    }
 
    public void OpenCrafting()
    {
        t = 0;
        for(int i = 0; i < 2; i++)
        {           
            for(int j = 0; j < 5; j++)
            {
                if(buttons[t] != null) getWorld().addObject(buttons[t],50+372, 50+165);    
                t++;
            }           
        }
    }
 
    public void Buttons()
    {
        Button CraftAxe = new Button("Wood", "Stone", 5, 3);
        buttons[0] = CraftAxe;
    }
}
danpost danpost

2016/9/10

#
Freekywill wrote...
I think I may have confused you, I am using the "c" key to both open and close the crafting window. The "e" key is only used to open and close the inventory, and close the crafting window if it is open so they don't overlap.
Then maybe you need another boolean field to track the state of the key being used (or to indicate that the key has been released) and use it in conjunction with the other conditions in opening and closing them. Something like this:
1
2
3
4
5
6
7
8
// instance field
boolean cKeyUp;
 
if (cKeyUp)
{
    // code given above
}
else if (!Greenfoot.isKeyDown("c")) cKeyUp = true;
You should also set the field to 'false' when detected in the code given above. Another way of coding it follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
// instance fields
boolean cKeyUp;
boolean open;
 
// in act method
if (cKeyUp == Greenfoot.isKeyDown("c"))
{
    cKeyUp = !cKeyUp;
    if (!cKeyUp)
    {
        if (!open) OpenCrafting(); else CloseCrafting();
    }
}
Line 6 detects any change in the state of the 'c' key (the condition is true only on act cycles when the key is pressed, not held, or released). Line 8 has the boolean 'cKeyUp' field hold the new state of the key and line 9 ferrets out the upstrokes of the key, so that the action (line 11) is performed only on the downstroke of the key.
Freekywill Freekywill

2016/9/10

#
Thank you so much danpost. Not only does this code work perfectly, but it functions better than before I had the problem.
You need to login to post a reply.