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

2018/3/26

''Simon Game'' - How can I make it, so the ''AI'' lets buttons light up?

1
2
JFox JFox

2018/3/26

#
Hi Greenfoot-Community :) Before you read, I'm a Java-Noob :D I'm currently working on a game similiar to the game ''Simon''. I currently have a world called ''Simon'', and 4 actors: ''RedButton'',''YellowButton'',''GreenButton'' and ''Blue Button''. Now I'm facing the problem, that I don't know how I can make the ''AI''/program light up the button, so I can follow. Any help would be apreciated :)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import greenfoot.*;
import java.util.ArrayList;
 
public class Simon extends World
{
     
     
    public Simon()
    {   
        super(600, 600, 1);
        addObject(new RedButton(),420,179);
        addObject(new GreenButton(),179,179);
        addObject(new YellowButton(),179,420);
        addObject(new BlueButton(),420,420);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.Date;
public class RedButton extends Actor
{
    int timer = 0;
    public void act()
    {
            if (Greenfoot.mouseClicked(this) ) 
    
       Greenfoot.playSound("PressButtonSound.mp3");
        setImage("redpressed.png");
       Greenfoot.delay(20);
       setImage("red.png");
    }
    }   
}
(The same for the other buttons)
JFox JFox

2018/3/26

#
Someone? Please help me :D
danpost danpost

2018/3/26

#
Remove line 2 from both classes given above -- you are not using any ArrayList object in your Simon class and you are not using any Date object in the RedButton class (or the other buttton classes). Right now, you have each button reacting to any clicks on them. Although that is what might be needed to detect a step in the response to a given sequence, it is not something that you would want to happen at any time. There are two main phases in a Simon type game -- the phase where a sequence is given (not requiring mouse clicks) and the phase where the user tries to reproduce the sequence (requiring mouse clicks or user input of some type). You start with an empty sequence (no sequence, really). The first phase involves adding one of the four buttons to the sequence and then running the sequence. This is not something that an individual button can do -- it needs to be done by the world. The world needs to retain the sequence to play it and to check against the input given by the user. One question that comes to mind is how to represent a sequence of buttons. One possible idea might by to use an ArrayList (as you have implicitly indicated went through your mind or was an idea provided to you from some other source). Actually, a more "clever" way, or at least a way I would consider to be better, is to use a simple String object, representing the buttons by the first letter in their colors, "R", 'G", "B", and "Y". So, a sequence might end up to be something like "YRBBGBYRRGYGRBY". Now, since the world will have to perform the sequence before the user can reproduce it, the world would need to keep references to the buttons so it will not have to segregate them from other actors in the world every act cycle. So an array of length four can be created and loaded with the buttons. Then, so the array does not have to be iterated through every act for a specific button, a String object can be created and the first letter of the colors of the buttons as they appear in the list can be concatenated to build this string. The world will now be able to take a character, say "G", get the index of it in the four-character string, say "RGYB" and use that index to get the appropriate button from the button list. Finally, the world class act method is ready to control the buttons (setting the images for both pressed and normal) and also check for clicks on those buttons (all in one place). The button classes can be basically empty of added codes -- for example, the RedButton class can be simply this:
1
public class RedButton extends greenfoot.Actor {}
and similar for the other buttons. The Simon class act method can control the entire game. You will need a strategy for controlling the phases -- probably using a boolean and a counter.
JFox JFox

2018/3/26

#
Hi Dan! This already helped a lot, thank you! I've now added a ArrayList (I hope, that I did it right^^) in my Simon World. I also know that I need a "Sequence"-method, where I can let the first phase run through.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import greenfoot.*;
 
public class Simon extends World
{
     
    Actor[] buttons = {new RedButton(), new GreenButton(), new YellowButton(), new BlueButton()};
     
    public Simon()
    {   
        super(600, 600, 1);
        addObject(new RedButton(),420,179);
        addObject(new GreenButton(),179,179);
        addObject(new YellowButton(),179,420);
        addObject(new BlueButton(),420,420);
    }
 
    public void sequence()
    {
    
    }
}
I also understand that I need to represent the buttons with String objects, however that's where I'm stuck now. I thought, maybe I have to put it like that:
1
string "R" = Actor RedButton;
However, this also doesn't work. Again, thank you for helping :)
danpost danpost

2018/3/26

#
JFox wrote...
I've now added a ArrayList (I hope, that I did it right^^) in my Simon World.
First, it is not an ArrayList -- it is an Array (line 6 in Simon class). Second, a major issue is that the button actors you add into the world are not the same actors that you placed into the array (lines 11 through 14 must not use the "new" keyword, but must reference the actors in your array.
I also know that I need a "Sequence"-method, where I can let the first phase run through.
Well, I myself would refrain from using Greenfoot.delay; so, a sequence method would be kind of out the window. I would use timer and sequence index fields to perform the sequence through the act method of the class.
I also understand that I need to represent the buttons with String objects, however that's where I'm stuck now. I thought, maybe I have to put it like that:
1
string "R" = Actor RedButton;
There are multiple issues with this one line of code. In a line of code that assigns a value (or reference) to a new variable, the parts are labelled as follows:
1
varType varName = expression;
varType is either a primitive type, like int, boolean or double, or an Object type, like World, Actor or String. It declares what type of value the new variable will hold. varName is the name you give the new variable and there are limitations as to what names you can declare for variables. expression is everything to the right of the equal sign and must evaluate to the type declared for the variable. Your line of code has the following errors (1) string is an invalid type (should be String); (2) "R" is not a valid variable name (quotes are illegal); and (3) an Actor reference cannot be assigned to a variable that is supposed to hold a String object. Along with your array, you can add this line:
1
String btnSet = "RGYB";
Later, in your code, you will be able to use something like this:
1
Actor button = getButton("G");
with this method
1
2
3
4
private Actor getButton(String color)
{
    return buttons[btnSet.indexOf(color)];
}
JFox JFox

2018/3/27

#
danpost wrote...
Second, a major issue is that the button actors you add into the world are not the same actors that you placed into the array (lines 11 through 14 must not use the "new" keyword, but must reference the actors in your array.
Ok, I get what you mean. However, I don't know how I can refer to the Actors in my Array.
danpost wrote...
I would use timer and sequence index fields to perform the sequence through the act method of the class.
What are timer and sequence index fields? Sorry to bother you.
danpost wrote...
(1) string is an invalid type (should be String); (2) "R" is not a valid variable name (quotes are illegal); and (3) an Actor reference cannot be assigned to a variable that is supposed to hold a String object.
(1) Ok, so I changed the varType to String. (2) I deleted the quotes (3) Ok, I understand, still I don't understand how I can "equal" my Actor to a String object so that the program just needs to use the String object.
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
import greenfoot.*;
 
public class Simon extends World
{
     
    Actor[] buttons = {new RedButton(), new GreenButton(), new YellowButton(), new BlueButton()};
    String btnSet = "RBYB";
     
    public Simon()
    {   
        super(600, 600, 1);
        addObject( RedButton(),420,179);
        addObject( GreenButton(),179,179);
        addObject( YellowButton(),179,420);
        addObject( BlueButton(),420,420);
    }
 
    public void act()
    {
        Actor button = getButton("G");
         
    }
     
    private Actor getButton(String color)
    {
     return buttons[btnSet.indexOf(color)];
    }
     
}
Again, thank you for helping me :)
danpost danpost

2018/3/27

#
JFox wrote...
I don't know how I can refer to the Actors in my Array.
There is an example in the getButton method. Line 12 could simply be the following (and lines 13 through 15 similarly):
1
addObject(getButton("R"), 420, 179);
What are timer and sequence index fields?
They are int fields you add to the class to act (1) as an act counter to help regulate actions over time; and (2) as a pointer to indicate which character in the sequence string is currently being acted on (in phase one, that character's respective button image is being illuminated; in phase two, the button is tested as the next correctly clicked button).
(3) Ok, I understand, still I don't understand how I can "equal" my Actor to a String object so that the program just needs to use the String object.
I believe the answer to this was given earlier in this posting (see code line).
JFox JFox

2018/3/27

#
danpost wrote...
There is an example in the getButton method. Line 12 could simply be the following (and lines 13 through 15 similarly)
Perfect, thanks :)
danpost wrote...
They are int fields you add to the class to act (1) as an act counter to help regulate actions over time; and (2) as a pointer to indicate which character in the sequence string is currently being acted on (in phase one, that character's respective button image is being illuminated; in phase two, the button is tested as the next clicked button).
Ok great, thank you :)
danpost wrote...
I believe the answer to this was given earlier in this posting.
1
varType varName = expression;
Is this what you mean? I understand that the varType needs to be String and the varName can be R (without quotes), but I don't know what expression means in this case. I tried
1
2
3
String R = RedButton();
 
String R = RedButton;
but both don't seem to work. I know that String can't be equal to an Actor, so that's why I'm asking :) Thank you again for helping :)
danpost danpost

2018/3/27

#
JFox wrote...
I understand that the varType needs to be String and the varName can be R (without quotes), but I don't know what expression means in this case. I tried
1
2
3
String R = RedButton();
 
String R = RedButton;
but both don't seem to work. I know that String can't be equal to an Actor, so that's why I'm asking
All that stuff about varType, varName and expression was just general information on how to create and assign a value to a new variable. The RHS, expression , could be a simple value, another variable name, a mix of method calls and math operations -- any expression that results to something of the type that the variable can hold. For example, since a RedButton object is an Actor object, the line in your act method above works. The method called on the RHS is the expression that provides an Actor object which is then assigned to the variable button which can only hold objects of type Actor. As far as a String representing a button, you can see by that line in your act method that by calling the getButton method with the String as the argument, the appropriate button actor is returned. You should drop your attempts to assign R a value, mainly because you want the button actor -- not a String object.
JFox JFox

2018/3/27

#
So, I'm now at this point:
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
import greenfoot.*;
 
public class Simon extends World
{
     
    Actor[] buttons = {new RedButton(), new GreenButton(), new YellowButton(), new BlueButton()};
    String btnSet = "RBYG";
     
    public Simon()
    {   
        super(600, 600, 1);
        addObject(getButton("R"),420,179);
        addObject(getButton("G"),179,179);
        addObject(getButton("Y"),179,420);
        addObject(getButton("B"),420,420);
    }
 
    public void act()
    {
    Actor GreenButton = getButton("G"); //is this right?
    Actor RedButton = getButton("R"); //is this right?
    Actor YellowButton = getButton("Y"); //is this right?
    Actor BlueButton = getButton("B"); //is this right?
    }
     
    private Actor getButton(String color)
    {
     return buttons[btnSet.indexOf(color)];
    }
     
}
Example button:
1
2
3
import greenfoot.*;
 
public class RedButton extends greenfoot.Actor {}
If it's ok to ask, in your eyes, what should be the next step for me to focus on? :)
danpost danpost

2018/3/27

#
JFox wrote...
1
2
Actor[] buttons = {new RedButton(), new GreenButton(), new YellowButton(), new BlueButton()};
String btnSet = "RBYG";
Here, there is a mismatching. The order must be the same in both lines.
JFox wrote...
1
2
3
4
Actor GreenButton = getButton("G"); //is this right?
Actor RedButton = getButton("R"); //is this right?
Actor YellowButton = getButton("Y"); //is this right?
Actor BlueButton = getButton("B"); //is this right?
Those lines are legitimate, but are not necessary. When you build your act method, you will use the getButton method when needed.
JFox wrote...
Example button:
1
2
3
import greenfoot.*;
 
public class RedButton extends greenfoot.Actor {}
Line one is not needed here.
If it's ok to ask, in your eyes, what should be the next step for me to focus on? :)
You should probably create methods to perform some of the actions needed for the game (for example, one to detect clicks on the buttons, one to run the act counter and control the playing out of the sequence -- things like that).
JFox JFox

2018/3/27

#
danpost wrote...
You should probably create methods to perform some of the actions needed for the game (for example, one to detect clicks on the buttons, one to run the act counter and control the playing out of the sequence -- things like that).
Thank you very much! I'll now try to create those methods and will post again later :)
danpost danpost

2018/3/27

#
JFox wrote...
I'll now try to create those methods and will post again later :)
I wish to remind you that pretty much everything will go in your Simon class.
JFox JFox

2018/3/27

#
Ok thanks for letting me know :)
JFox JFox

2018/3/27

#
Ok, so after a short break I'm now trying to get the detectClick method to work.
1
2
3
4
5
6
7
public void detectClick()
    {
      if (Greenfoot.mouseClicked(getButton("RBYG")) ) 
    
        
    }
    }
My question is: Should I create a detectClick method for every individual button, so that they can individually swap out the images or should I put it like in the code i posted. Also: I already tried using this method:
1
2
3
4
5
6
7
public void detectClick()
    {
      if (Greenfoot.mouseClicked(getButton("R")) ) 
    
       setImage("redpressed.png");
    }
    }   
However, if I put it like that, Greenfoot just gives out "File saved", without compiling and I can't use the interface, because it is greyed out.
There are more replies on the next page.
1
2