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

2014/5/1

Selecting characters and switching them with others

1
2
3
4
Zzimon Zzimon

2014/5/1

#
I am in the middle of making a simpler clone of the game Bejeweled, so far pretty much all i have is so my grid world(Bejeweled_World) gets populated properly so that no more than 2 in a straight line spawn e.g. Now what i'm trying to do is make it possible to select one of the tiles in the grid and then switch it out with another one, either left, right, up or down. The code that I've tried so far is this:
public class Sword extends Actor
{
    public Sword()
    {
        getImage().scale(40, 40);
    }
    public int state = 0;
    public void act()
    {
        if (state == 0)
        {
            if (Greenfoot.mousePressed(this))
            {
                state = 1;
            }
        }
        else if (state == 1)
        {
            movement();
        }
    }
    public void movement()
    {
        if (Greenfoot.isKeyDown("w") && Greenfoot.isKeyDown("a") && Greenfoot.isKeyDown("s") && Greenfoot.isKeyDown("d"))
        {
            setLocation(getX(), getY() - 1);
            state = 0;
        }
    }
}
This code i just put into one of my tile actors the actor called 'Sword'
Zzimon Zzimon

2014/5/1

#
So far I've gotten this advice
Danpost wrote...
Instead of using an 'int' field, try an 'Actor' field. When an actor is clicked, set it to the actor. When a switch is made, set it back to 'null'. Since you do not want more than one Actor to be selected at any time, the 'Actor field will need to be 'static' or be located in your world subclass. That way, if a different one is clicked on before a key is pressed, it will change its value to it (instead of two tiles thinking that they are selected at the same time -- you certainly do not want to have two sets of tiles swapped with each other).
The problem is that I don't really know how to use this.
danpost danpost

2014/5/1

#
Line 24 above says that you want all four keys down at one time to execute its block of code. Line 26 says that you only want the selected actor to move up one cell (when all four keys are down). Let us say a mouse button is pressed while on a sword; then, the mouse button is released, the mouse is moved to a coin and the mouse button is pressed again. You will now have TWO tiles with their 'state' fields set to one. If a direction key is now pressed, both tiles will swap places with a neighbor. I know this is not what you want. So, the 'state' field is not going to work the way you want. That is why I suggested either an Actor field in your subclass of world or a ... well, there really is no other choice; as all your Actor subclasses extend Actor. There is one other option. Use mouse press, drag, and release to determine which actor is to move where.
Zzimon Zzimon

2014/5/1

#
Ok. The fact that it all is in my actor is fine then, the state not switching back as far as I am concerned is fairly irrelevant, as long as I can get them to move I'll be happy. So far as I understand the code that I have, if I change line 24 to
if (Greenfoot.isKeyDown("w"))
it should just move the tile that i have clicked on with my mouse one tile up when i press my 'w' button, but still nothing moves no matter in which combination i click the tile and press the 'w' button The drag option sounds rather interesting, though for this I am pretty sure that I'll be using the Greenfoot.mouseDragged and Greenfoot.mouseDragEnded commands, which for the Dragged command I am confused if it starts when the the 'click' begins and then continues as i hold my mouse button down or if it does something else.
Zzimon Zzimon

2014/5/1

#
The
danpost wrote...
Actor field in your subclass of world
sounds the easiest but I still don't know what you mean when you say an Actor field, if you could, maybe provide an example that would be awesome! :)
danpost danpost

2014/5/1

#
Just like you added your int field ( 'public int state = 0' ), except it will be an Actor field
public Actor selected = null; 
Then when an actor is clicked on, it can set this field to 'this', referring to itself. Also, an actor can check to see if the field is holding it by 'if (((Maze)getWorld()).selected == this)'.
danpost danpost

2014/5/1

#
Also, the key checking should go in the world class. It is what is going to have to perform all the match processing, anyway (that will be fun -- very involved).
Zzimon Zzimon

2014/5/1

#
Ok, so the key checking thing, lets just save that for later. In terms of the Actor field would it just work as my int field previously did, e.g.
public int state = 0;
state = 1;
will the state field then be the same as this: ?
public Actor selected = null;
Actor = !null;
Edited to actually have the proper code ^^'
Zzimon Zzimon

2014/5/1

#
I tried this going on my assumption that they would work pretty much the same way but I still don't know how to use it properly it seems
    public Actor selected = null; 
    public void act()  
    {  
        if (selected == null)
        {  
            if (Greenfoot.mousePressed(this))
            {  
                selected = !null;  
            }  
        }
        else if (selected == !null)
        {  
            movement();  
        }  
    } 
    public void movement()
    {
        if (Greenfoot.isKeyDown("w"))
        {
            setLocation(getX(), getY() - 1);
            selected = null;
        }
    }
Zzimon Zzimon

2014/5/2

#
Ok then I realized how stupid I've been and what I overlooked so now I can actually make my Tile actors work properly. Now I've come to the point of checking and switching out my actors which I can't really figure out
Zzimon Zzimon

2014/5/2

#
I can now make my tiles move using this code
 
    public void act()  
    {
        if (Greenfoot.isKeyDown("w"))
        {  
            movement();
        }
    } 
    public void movement()
    {
            setLocation(getX(), getY() - 1);
    }
But I Still can't really understand how you intended that i could fix my code using an Actor field
danpost danpost

2014/5/2

#
After a little thought, I now think there may be a way to accomplish what you want using something similar to your code above (the one starting with 'public Actor selected = null;' ). Also, you may be able to use a boolean or int as you had to begin with. There was just one vital thing missing with what you were using then. Try this:
private boolean selected = false;

public void act()
{
    if (Greenfoot.mouseClicked(this)) selected = true;
    // this next line is what was missing
    if (Greenfoot.mouseClicked(null) && !Greenfoot.mouseClicked(this)) selected = false;
    if (selected && Greenfoot.isKeyDown("w"))
    {
        moveUp();
        selected = false;
    }
}
You will need four methods, one for each direction ( 'moveUp' being one of them ). Each should swap the locations of the tiles and check to ensure a match has been made; if so, execute match processing, else swap them back.
danpost danpost

2014/5/2

#
Do your Coin, Torch, and Sword classes all extend Actor or some other class (maybe a Tile class)?
Zzimon Zzimon

2014/5/2

#
all of my tile classes i.e. my Coin, Torch and Sword class.
danpost danpost

2014/5/2

#
Zzimon wrote...
all of my tile classes i.e. my Coin, Torch and Sword class.
That is not a complete sentence and does not help any.
There are more replies on the next page.
1
2
3
4