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

2015/6/21

Create row of objects of the same class with separate actions

luckynick luckynick

2015/6/21

#
My aim is to create tetris game. Actually I am on very beginning. I am trying to make new block to spawn after previous reaches a bottom. When I run my code, first block acts normaly. But when this first block reaches destination, it seems like objects (blocks) begin to appear in a row constantly instead of only one block have to appear. After plenty of seconds whole Greenfoot application starts to freeze. If I dont stop execution of my code, greenfoot even can crush. I want every next object to behave separately so that previous object stops acting when it reaches destination and control goes to new object. Please explain what should I do in my situation, why does not my code behave as I expect? Why Greenfoot crashes? My 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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import greenfoot.*;
 
public class Square extends Actor
{
    //constructor
    public Square(){
        rightWay = false;
        isKeyD = false;
        destination = false;
        queue = true;
    }
    
    private boolean rightWay; //whether block will move to the bottom
    private boolean isKeyD; //support variable for isKeyDown construction
    private boolean destination; //whether block gained bottom or another block
    private boolean queue; //my attemt to fix bug; has to indicate if next block is in the air
     
     
    public void act()
    {
        toWay();
        moveForw();
        stepRight();
        stepLeft();
        reachedDestination();
        boost();
        newActor();
    }   
    //moves block one step right
    public void stepRight(){
        if(!getDestination()){
        if(!getIsKeyD() && Greenfoot.isKeyDown("right")){
            setLocation(getX() + 1, getY());
            setIsKeyD(true);
        }
        if(getIsKeyD() && !Greenfoot.isKeyDown("right")){
            setIsKeyD(false);
        }
    }
    }
     // and left
    public void stepLeft(){
        if(!getDestination()){
        if(!getIsKeyD() && Greenfoot.isKeyDown("left")){
            setLocation(getX() - 1, getY());
            setIsKeyD(true);
        }
        if(getIsKeyD() && !Greenfoot.isKeyDown("left")){
            setIsKeyD(false);
        }
    }
    }
     //changes queue and destination variables to indicate
     //that block has reached bottom and must not move further
    public void reachedDestination(){
        if(getY() == getWorld().getHeight() - 1 || isTouching(null)){
            setDestination(true);
            setQueue(false);
        }
    }
    //adds new block to world (seems like bug is located here)
    public void newActor(){
        if(getDestination() && !getQueue()){
            setQueue(true);
            getWorld().addObject(new Square(), 5, 0);
        }
    }
    //makes block to face bottom
    public void toWay(){
        if(!getRightWay()){
        turn(90);
        setRightWay(true);
    }
    }
    //basic move method
    public void moveForw(){
        if(getRightWay() && !getDestination()){
        move(1);
    }
    }
    //makes block move x2 faster
    public void boost(){
        if(!getIsKeyD() && Greenfoot.isKeyDown("down")){
            moveForw();
            setIsKeyD(true);
        }
        if(getIsKeyD() && !Greenfoot.isKeyDown("down")){
            setIsKeyD(false);
        }
    }
    //set and get support methods
    void setRightWay(boolean input){
        rightWay = input;
    }
    boolean getRightWay(){
        return rightWay;
    }
    void setIsKeyD(boolean input){
        isKeyD = input;
    }
    boolean getIsKeyD(){
        return isKeyD;
    }
    void setDestination(boolean input){
        destination = input;
    }
    boolean getDestination(){
        return destination;
    }
    void setQueue(boolean input){
        queue = input;
    }
    boolean getQueue(){
        return queue;
    }
}
Illustration:
Gingervitis Gingervitis

2015/6/21

#
I am not quite an "expert" at java yet, but looking at your code carefully it appears that although you are setting 'queue' to 'true' in your 'newActor()' method, it is constantly going back to false since your 'reachedDestination()' method remains true. I would inspect your first Square actor and check if 'queue' keeps changing after 'reachedDestination()' is called
danpost danpost

2015/6/21

#
Gingervitis is correct. Once the square reaches its destination, the state is not changed in any way to prevent a new actor from being created on every following act cycle. You could add the following at the beginning of your act method:
1
2
3
if (getDestination()) {
    return;
}
so the the square basically becomes inactive once 'destination' is set to 'true'.
luckynick luckynick

2015/6/22

#
Thank you for help. Sometimes it is easy to mess up and not to pay attention to some tiny details.
luckynick luckynick

2015/6/22

#
But now I have a new question. I am trying to indicate that block touches another block, which is located lower. I am using getOneObjectAtOffset. I am guessing that this method must return object. How should I implement this method so that it will return boolean statement 'true' if an object exists lower or 'false' if not?
1
2
3
4
5
6
7
8
9
public boolean objectUnder(){
        Actor something = getOneObjectAtOffset(getX(), getY() + 1, null);
        if(something != null){
            return true;
        }
        else{
            return false;
        }
    }
luckynick luckynick

2015/6/22

#
Solved. Problem was in that I should use as arguments to getOneObjectAtOffset method arguments relatively to current object location.
1
Actor something = getOneObjectAtOffset(0, 1, null);
Super_Hippo Super_Hippo

2015/6/22

#
1
2
3
4
public boolean objectUnder()
{
    return getOneObjectAtOffset(0, 1, null) != null;
}
You need to login to post a reply.