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

2017/3/9

Need help

1
2
3
Nooooob Nooooob

2017/3/9

#
So I'm supposed to make a Tetris game but I don't make any progress. 1: The Tetrominos don't fall. 2: The Tetrominos can go through each other or rather don't stop moving when touching each other. 3: What I tried to do is make one block class form various Tetrominos. I failed. Here's my attempt: World class
 Counter counter = new Counter();
    
    int[][]line =  {{1,1,1,1}, 
                        {0,0,0,0}, 
                        {0,0,0,0}, 
                        {0,0,0,0}};     
                                   
    int[][]thunder = {{1,1,0,0}, 
                              {0,0,1,1}, 
                              {0,0,0,0}, 
                              {0,0,0,0}};
                    
    int[][]pyramid = {{0,1,0,0}, 
                              {1,1,1,0}, 
                              {0,0,0,0}, 
                              {0,0,0,0}};    

public MyWorld()
{    
        super(15, 20, 40);
        addObject(new Ground(), 5, 18);
        create();
}

public void create()
{
        createTetromino(line, Greenfoot.getRandomNumber(15), Greenfoot.getRandomNumber(3));
createTetromino(pyramid, Greenfoot.getRandomNumber(15), Greenfoot.getRandomNumber(3));
createTetromino(thunder, Greenfoot.getRandomNumber(15), Greenfoot.getRandomNumber(3));
}

public void createTetromino(int[][] tetromino, int x, int y)
{
Block[] block = {new Block(), new Block(), new Block(), new Block()};
     int counter = 0;
for(int a = 0; a < 5; a = a + 1)
     {
        for(int b = 0; b < 5; b = b + 1)
        {
           if(tetromino[a][b] == 1)
                {
                 addObject(new Block(),x, y);
                 counter++;
           }
        }
     }
    }

Block class
int vSpeed = 0;
    public void act() 
    {
    fall();
    if(isTouching(Ground.class))
    {
        stopFalling();
    }
if(isTouching(Block.class))
    {
        stopFalling();
    }
    }   
    public void fall()
    {
        vSpeed = vSpeed + 1;
    }
    public void stopFalling()
    {
        vSpeed = 0;
    }
Any help is highly appreciated :)
danpost danpost

2017/3/9

#
(1) and (2) contradict each other. They do not fall, yet they move through each other? I do not see any sideward movement coded, so I must presume that you mean they fall through each other; but they do not fall. If I am missing something, please elaborate. If not, please correct.
Nooooob Nooooob

2017/3/9

#
danpost wrote...
They do not fall, yet they move through each other?
With the code I posted before they won't fall but when I use this:
public void fall()
    {
        setLocation(getX(), getY() + 1);
    }
they fall and fall through each other. That way I don't know how to make them stop tho.
danpost wrote...
I do not see any sideward movement coded
Didn't figure out how to do that yet.
danpost danpost

2017/3/9

#
Any group of Block objects that form a tetromino should be all controlled from a single location (the Block objects should not move on their own). The Block class should not contain any code in its act method (or just not have an act method at all in it). The World object (which is where game control should go) should choreograph the movement of the currently falling block (including left and right movement). You can, and should, have methods that you can call from the world in the Block class to accept requests to perform the actions and return a status flag on the final result. For example, to fall:
public boolean fall(int dir)
{
    setLocation(getX(), getY()+dir);
    return getObjectsAtOffset(0, 0, Block.class).isEmpty();
}
The world can now call all blocks in a tetromino to fall and, if any of them fail (return a 'false' value), move them all back. A method might help in the world class for moving a tetromino:
private boolean moveTetromino(int dir)
{
    boolean result = true;
    for (Block block : tetromino) result = result && block.fall(dir);
    return result;
}
Now, in the act when moving a tetromino:
if (!moveTetromino(1))
{
    moveTetromino(-1);
    // set a new tetromino active
    if (!moveTetromino(0)) gameOver();
}
Nooooob Nooooob

2017/3/9

#
Sorry, I don't fully get it.
danpost wrote...
Any group of Block objects that form a tetromino
I only have one Block class and it's not forming the various tetrominos.
danpost wrote...
should be all controlled from a single location
From the World class?
danpost wrote...
The Block class should not contain any code in its act method (or just not have an act method at all in it).
So should I remove what I wrote in the Block class?
danpost wrote...
For example, to fall:
public boolean fall(int dir)
{
    setLocation(getX(), getY()+dir);
    return getObjectsAtOffset(0, 0, Block.class).isEmpty();
}
Is this supposed to be in the Block class?
danpost wrote...
private boolean moveTetromino(int dir)
{
    boolean result = true;
    for (Block block : tetromino) result = result && block.fall(dir);
    return result;
}
if (!moveTetromino(1))
{
    moveTetromino(-1);
    // set a new tetromino active
    if (!moveTetromino(0)) gameOver();
}
It can't find variable tetromino and method gameOver if I put this in the World class.
danpost danpost

2017/3/9

#
Nooooob wrote...
3: What I tried to do is make one block class form various Tetrominos. I failed.
then:
I only have one Block class and it's not forming the various tetrominos.
These two statements seem to be a contradiction.
Nooooob wrote...
danpost wrote...
should be all controlled from a single location
From the World class?
That would be a good candidate.
Nooooob wrote...
danpost wrote...
The Block class should not contain any code in its act method (or just not have an act method at all in it).
So should I remove what I wrote in the Block class?
At least everything you had shown above. Cannot say about anything else that might be in the class.
Nooooob wrote...
danpost wrote...
For example, to fall:
public boolean fall(int dir)
{
    setLocation(getX(), getY()+dir);
    return getObjectsAtOffset(0, 0, Block.class).isEmpty();
}
Is this supposed to be in the Block class?
Yes.
Nooooob wrote...
< Quote Omitted > It can't find variable tetromino and method gameOver if I put this in the World class.
I was looking ahead. If you are controlling the blocks from the Welt class, then you will need to keep a reference to the currently active tetromino (or the blocks that make up the object) -- that is what 'tetromino' refers to. Also, I presumed that you would want a way to check for game over and perform various tasks when detected. Add the following to the Welt class:
private Block[] tetromino = new Block[4];

private void gameOver()
{
    // add game over procedures here
}
Then, replace your 'createTetromino' method with this:
public void createTetromino(int[][] layout, int x, int y)
{
    int counter = 0;
    for (int a=0; a <4; a++) for (int b=0; b<4; b++)
    {
        if (layout[a][b] == 1)
        {
            tetromino[counter++] = new Block();
            addObject(tetromino[counter], x+b, y+a);
        }
    }
}
Now, you can replace the comment on line 4 with:
createTetromino();
Nooooob Nooooob

2017/3/9

#
danpost wrote...
Nooooob wrote...
3: What I tried to do is make one block class form various Tetrominos. I failed.
then:
I only have one Block class and it's not forming the various tetrominos.
These two statements seem to be a contradiction.
What I meant is I tried to make one form them but it didn't work.
danpost wrote...
Now, you can replace the comment on line 4 with
Pasted it and this shows up:
public void create()
    {
     if (!moveTetromino(1))
    {
    moveTetromino(-1);
    createTetromino();
    if (!moveTetromino(0)) gameOver();
    }
     createTetromino(line, Greenfoot.getRandomNumber(20), Greenfoot.getRandomNumber(3));
    }
danpost danpost

2017/3/9

#
Add the required parameters to the erroneous line. For now, something like:
createTetromino(line, 7, 2);
That should avoid the error; but, you still have work to do in order to create a random tetromino. I cannot help right now -- have to go. Maybe Hippo can put in a good word or two.
danpost danpost

2017/3/10

#
I will presume that you would want the tetrominos to come up randomly. In order to accomplish that, we need to list the layouts or place them in an array (of double arrays). I am not positive, but I think the following will work. Replace your 'create' method with this:
public void create()
{
    int[][][] layouts = { line, thunder, pyramid };
    int[][] layout = layouts[Greenfoot.getRandomNumber(layouts.length)];
    int x = Greenfoot.getRandomNumber(15);
    int y = Greenfoot.getRandomNumber(3);
    createTetromino(layout, x, y);
}
and change line 4 that we were working on before ( where we had put 'createTetromino();' ) to this:
create();
Nooooob Nooooob

2017/3/10

#
danpost wrote...
and change line 4 that we were working on before ( where we had put 'createTetromino();' ) to this:
create();
I thought I should replace:
if (!moveTetromino(1))
{
    moveTetromino(-1);
    // set a new tetromino active
    if (!moveTetromino(0)) gameOver();
}
with that:
public void create()
{
    int[][][] layouts = { line, thunder, pyramid };
    int[][] layout = layouts[Greenfoot.getRandomNumber(layouts.length)];
    int x = Greenfoot.getRandomNumber(15);
    int y = Greenfoot.getRandomNumber(3);
    createTetromino(layout, x, y);
}
So which line 4?
Super_Hippo Super_Hippo

2017/3/10

#
I am a bit confused by all these createXY methods, but the second post should be called from where the comment line is in the first code (both your last post). (Obviously both methods should not have the same name.) Maybe you could also just copy and paste the second one into the first:
if (!moveTetromino(1))
{
    moveTetromino(-1);
    int[][][] layouts = { line, thunder, pyramid };
    int[][] layout = layouts[Greenfoot.getRandomNumber(layouts.length)];
    int x = Greenfoot.getRandomNumber(15);
    int y = Greenfoot.getRandomNumber(3);
    createTetromino(layout, x, y);
    if (!moveTetromino(0)) gameOver();
}
Nooooob Nooooob

2017/3/10

#
Super_Hippo wrote...
Maybe you could also just copy and paste the second one into the first:
All right. This shows up now: What is supposed to be in the gameOver() method btw? Greenfoot.stop()?
Super_Hippo Super_Hippo

2017/3/10

#
Did you add the fall method danpost wrote here? Anything which should happen when the game ends. For example stopping it with Greenfoot.stop() or showing some Game Over screen or what ever comes to your mind.
Nooooob Nooooob

2017/3/10

#
Super_Hippo wrote...
Did you add the fall method danpost wrote here?
Just put it in the World class but
Super_Hippo Super_Hippo

2017/3/10

#
Add it to the Block class.
There are more replies on the next page.
1
2
3