0

I am making myself a tetris clone in java, as a learning project. However I am now stuck at the part of getting the input for moving the piece left and right. I am not sure if the problem is in my methods, or is in the keyPressed method not being called I didn't have success in debugging as it ignored the method. Here is my code:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.*;

public class MainClass implements KeyListener{
    public static Painter painter = new Painter();
    public static LShape tetr = new LShape(150,0);

    public static void main(String[] args) throws InterruptedException {
        JFrame window = new JFrame("Tetris");
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setSize(300, 560);
        window.setBackground(Color.BLUE);

        window.getContentPane().add(painter);
        window.setVisible(true);

        ArrayList<Block> blocks = new ArrayList<Block>();
        ArrayList<Block> staticBlocks = new ArrayList<Block>();

        while(true){
            tetr = new LShape(150, 0);
            for (int i = 0; i < tetr.iterations; i++) {
                blocks = new ArrayList<Block>(Arrays.asList(tetr.getBlocks()));
                blocks.addAll(staticBlocks);
                painter.setBlocks(blocks);
                tetr.changeY(5);
                Thread.sleep(35);
                painter.repaint();
            }
            staticBlocks.addAll(blocks);
        }
    }

    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    public void keyPressed(KeyEvent e) {  //I am not sure if this is even called
        switch(e.getKeyCode()){
        case KeyEvent.VK_RIGHT:
            tetr.changeX(20);
            break;
        case KeyEvent.VK_LEFT:
            tetr.changeX(-20);
        }
    }

    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }
}
camickr
  • 321,443
  • 19
  • 166
  • 288
  • 4
    Where do you add your KeyListener? – Tobi Nov 04 '15 at 15:03
  • Follow this example: https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html If you can't get this to work then come on back. – Luminous Nov 04 '15 at 15:04
  • "as it ignored the method" ... either your debugger didn't have all your code, or you never actually call the method. a debugger doesn't just "ignore" your code – Stultuske Nov 04 '15 at 15:11
  • to which component did you add your KeyListener? Or did you assume because you have that method, it 'll automatically be called if you press a key? – Stultuske Nov 04 '15 at 15:13
  • okay, how is my keylistener called when it in the same class, I want it there so I can access my tetr object, when I call it with this, I get an error saying I can't use it in a static context – Криси Стоянов Nov 04 '15 at 15:18
  • try window.addKeyListener(this); – Stultuske Nov 04 '15 at 15:20
  • says I can't use it in a static context – Криси Стоянов Nov 04 '15 at 15:21
  • 2
    window.addKeyListener(new MainClass()); though a better way of working would be get your code out of the main method. It is only supposed to start the application, not contain it all – Stultuske Nov 04 '15 at 15:23
  • thanks, and yea this, problem got me thinking that I should so something about it – Криси Стоянов Nov 04 '15 at 15:26
  • 2
    `says I can't use it in a static context` - Don't use static variables and methods. Don't coded the program logic in the main() method. You should instead create a "TetrisPanel" class that defines the components and methods needed for your game. Then the main() method simply creates a frame and adds this panel to the frame. Finally don't use a KeyListener. Instead you should be using [Key Bindings](http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html). – camickr Nov 04 '15 at 15:26
  • @camickr If the OP is just learning Java and wants to use KeyListener, then so be it. "Don't use KeyListener" is not a good advice in this context. I mean, I myself don't like to hear that if I learn a new language. If it's there why not use it?! – peter.petrov Nov 04 '15 at 15:30
  • 2
    @peter.petrov, `If it's there why not use it?! ` - The OP is using a KeyListener because that is all they know about. They find old code on the internet and think that is the code to use. Its not. It is an older API used in AWT applications. Swing has newer and better API's that are more abstract and provide more features and functionality. All Swing components use KeyBindings to handles events initiated by using the keyboard. I am making the OP aware of newer/better solutions which will help in understanding the basics of how Swing works. – camickr Nov 04 '15 at 15:41
  • @camickr Well, OK. Even though, if I was the OP, I would not care about older/newer APIs, that would just confuse me more. I would just try to get my example working, even though it's using an old API. But OK, your point of view is also valid. – peter.petrov Nov 04 '15 at 15:49

2 Answers2

1

MainClass is not used anywhere.

Create an instance and add to the window object (JFrame instance) a keylistener which is in your code the MainClass . use this window.addKeyListener(new MainClass());

public class MainClass implements KeyListener {

public static Painter painter = new Painter();
public static LShape tetr = new LShape(150, 0);

public static void main(String[] args) throws InterruptedException {
    JFrame window = new JFrame("Tetris");
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setSize(300, 560);
    window.setBackground(Color.BLUE);
     window.addKeyListener(new MainClass()); 
    // window.getContentPane().add((PopupMenu) painter);
    window.setVisible(true);

    ArrayList<Block> blocks = new ArrayList<Block>();
    ArrayList<Block> staticBlocks = new ArrayList<Block>();

    while (true) {
        tetr = new LShape(150, 0);
        for (int i = 0; i < tetr.iterations; i++) {
            blocks = new ArrayList<Block>(Arrays.asList(tetr.getBlocks()));
            blocks.addAll(staticBlocks);
            painter.setBlocks(blocks);
            tetr.changeY(5);
            Thread.sleep(35);
            painter.repaint();
        }
        staticBlocks.addAll(blocks);
    }
}

public void keyTyped(KeyEvent e) {
    // TODO Auto-generated method stub

}

public void keyPressed(KeyEvent e) {  //I am not sure if this is even called
    System.out.println(e.getKeyCode());
    switch (e.getKeyCode()) {
        case KeyEvent.VK_RIGHT:
            // tetr.changeX(20);
            break;
        case KeyEvent.VK_LEFT:
        // tetr.changeX(-20);
    }
}

public void keyReleased(KeyEvent e) {
    // TODO Auto-generated method stub

}
}
Jude Niroshan
  • 4,280
  • 8
  • 40
  • 62
0

Still thinking other way, then atleast use this:

window.getContentPane().addKeyListner(new MainClass());

If you are not compatible with new technologies and methods, then use the above mentioned code. Otherwise search the internet to check how to use keyBindings.

More people said a lot than me, but i think you are not recognizing that...