JAVA: Tetris Applet help

New Member
💻 Oldtimer
Joined
Oct 3, 2004
Messages
1,462
Best answers
0
Hey guys,

to keep my coding skills sharp this summer, I decided to program Tetris for fun.
I'm having trouble getting the falling tetris pieces to respond to keyboard input (e.g. moveLeft(), moveRight(), rotate() etc...)
Right now the piece is falling down at an interval set by my timer...

So I have:

KeyHandler - handles all key events (Right now I just have it handling moveLeft... once I get that to work, I'll add in the rest of the inputs):

Code:
import java.awt.BorderLayout;
import javax.swing.JApplet;
import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;
import java.net.MalformedURLException;
import java.awt.event.*;

public class KeyHandler implements KeyListener {
    private TetrisPanel _tetrisPanel;
    
    public KeyHandler(TetrisPanel tp) 
    {
        _tetrisPanel = tp;
    }
    public void keyTyped(KeyEvent e) 
    {
        System.out.println("Key was typed.");
    }
    public void keyPressed(KeyEvent e) 
    {
        System.out.println("Key was pressed.");
        int keyCode = e.getKeyCode();
        switch(keyCode) 
        {
            case KeyEvent.VK_LEFT:
           _tetrisPanel.moveLeft();
            break;
            
            case KeyEvent.VK_P:
            _tetrisPanel.pause();
            break;
        }
    }
    public void keyReleased(KeyEvent e)
    {
    }
}
PieceFactory: generates tetris pieces from 12 rectangles (for each piece, say a Z, 4 out of the 12 rectangles would appear)
This also has my move method in it:

Code:
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

public class PieceFactory extends SmartRectangle 
{
    protected SmartRectangle _rec1,_rec2,_rec3,_rec4,_rec5,_rec6,
                            _rec7,_rec8,_rec9,_rec10,_rec11,_rec12;
    private int _changeX, _changeY;
    private int _yDir, _xDir;
    private double _X, _Y;
    //getX is the location of this piece
    
    public PieceFactory(double x, double y, Color aColor)
    {
        super(aColor);
      // _aPiece = new SmartRectangle(x,y,150,200,Color.WHITE);
       _rec1 = new SmartRectangle(x, y, 25, 25, aColor);
       _rec2 = new SmartRectangle(x, y+25, 25, 25, aColor);
       _rec3 = new SmartRectangle(x, y+50, 25, 25, aColor);
       _rec4 = new SmartRectangle(x, y+75, 25, 25, aColor);
       _rec5 = new SmartRectangle(x+25, y, 25, 25, aColor);
       _rec6 = new SmartRectangle(x+25, y+25, 25, 25, aColor);
       _rec7 = new SmartRectangle(x+25, y+50, 25, 25,aColor);
       _rec8 = new SmartRectangle(x+25, y+75, 25, 25, aColor);
       _rec9 = new SmartRectangle(x+50, y, 25, 25, aColor);
       _rec10 = new SmartRectangle(x+50, y+25, 25, 25, aColor);
       _rec11 = new SmartRectangle(x+50, y+50, 25, 25, aColor);
       _rec12 = new SmartRectangle(x+50, y+75, 25, 25, aColor);
       
       _X = x; //this is how I am passing x parameter to this _X for the getX method
       _Y = y;

 public int getChangeY() 
    {
        return(_changeY);
    }
    public int getChangeX()
    {
        return(_changeX);
    }

    
    public void setChangeY(int yDir) {
       _changeY = yDir;
    }
    public void setChangeX(int xDir) { 
       _changeX = xDir; 
    }
    
 public void move(int changeinX, int changeinY)
        {
            _rec1.setLocation(_rec1.getX() + changeinX, _rec1.getY() + changeinY);
            _rec2.setLocation(_rec2.getX() + changeinX, _rec2.getY() + changeinY);
            _rec3.setLocation(_rec3.getX() + changeinX, _rec3.getY() + changeinY);
            _rec4.setLocation(_rec4.getX() + changeinX, _rec4.getY() + changeinY);
            _rec5.setLocation(_rec5.getX() + changeinX, _rec5.getY() + changeinY);
            _rec6.setLocation(_rec6.getX() + changeinX, _rec6.getY() + changeinY);
            _rec7.setLocation(_rec7.getX() + changeinX, _rec7.getY() + changeinY);
            _rec8.setLocation(_rec8.getX() + changeinX, _rec8.getY() + changeinY);
            _rec9.setLocation(_rec9.getX() + changeinX, _rec9.getY() + changeinY);
            _rec10.setLocation(_rec10.getX() + changeinX, _rec10.getY() + changeinY);
            _rec11.setLocation(_rec11.getX() + changeinX, _rec11.getY() + changeinY);
            _rec12.setLocation(_rec12.getX() + changeinX, _rec12.getY() + changeinY);
           }

    public void paint(Graphics2D pen)
    {
        //_aPiece.fill(pen);
    }
}
}
TetrisPanel: Pulls tetris pieces at random from my PieceFactory and paints them to the screen. Also has my timer for animation.

Code:
import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.applet.Applet;

public class TetrisPanel extends JPanel implements ActionListener
{
   private PieceFactory _piece;
   private final int INTERVAL = 1000;
   private javax.swing.Timer _timer;
   private Applet _thisApplet;
   
    public TetrisPanel(java.applet.Applet applet)
    {
       super();
       _thisApplet = applet;
       setBackground(Color.GRAY);
       _piece = new PieceFactory(125,0, Color.BLACK);
      
       change();
       
       
       _timer = new javax.swing.Timer(INTERVAL, this);
       _timer.start();
  
    }
    public void paint(Graphics pen)
    {
        super.paint(pen);
        Graphics2D aBetterPen = (Graphics2D)pen;
        _piece.paint(aBetterPen);
    }
    
    public void change()
    {
        _piece = TetrisPanel.newPiece(100,0);
        repaint();
    }
    
    /**-------------------------------MOVE METHODS --------------------------------*/
    public void moveLeft() {
        System.out.println("You've pressed \"Move Left\"");
        if(_piece.getChangeX() == 0) {
            _piece.setChangeX(-25);
            _piece.setChangeY(0);
        }
    }
    
   public void pause() {
        if(_timer.isRunning()) {
            _timer.stop();
        }
        else {
            _timer.restart();
        }
    }
            
    /**-----------------------------------------------------------------------------*/      
    
    public static PieceFactory newPiece(int x, int y)
    {
        Random random = new Random();
        Color aColor = new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256));
        int random1 = (int)(Math.random() * 7) + 1;
        PieceFactory temp = new PieceFactory(x,y,aColor);// = new PieceFactory(x,y,aColor);
        
        switch(random1)
        {
            case 1: temp = new Z(x,y-50,aColor); break;
            case 2: temp = new L(x,y-25,aColor); break;
            case 3: temp = new S(x,y-50,aColor); break;
            case 4: temp = new T(x,y-50,aColor); break;
            case 5: temp = new Bar(x,y,aColor); break;
            case 6: temp = new Box(x,y-50,aColor); break;
            case 7: temp = new RevL(x,y-25,aColor); break;
                        
        }
        return temp;
    }
    public void actionPerformed(java.awt.event.ActionEvent e)
    {
        _piece.move(0, 25);
       // if 
       // _piece.moveLeft(-25, 0);

        this.repaint();
    }
}
TetrisApplet: which runs everything:

Code:
import java.awt.*;
import javax.swing.*;

public class TetrisApp extends JApplet
{
    TetrisPanel _tetrisPanel;
    ButtonPanel _buttonPanel;
    
    public void init()
    {
        this.setSize(250, 500);
        
        _tetrisPanel = new TetrisPanel(this);
        _buttonPanel = new ButtonPanel(_tetrisPanel);
        this.add(_tetrisPanel, BorderLayout.CENTER);
        this.add(_buttonPanel, BorderLayout.SOUTH);
        this.addKeyListener(new KeyHandler(_tetrisPanel));
        this.setVisible(true);
    }
}
TETRIS PIECES:

L:

Code:
import java.awt.*;

public class L extends PieceFactory
{
    private double _locX, _locY;

    public L(double x, double y, Color aColor)
    {
        super(x,y, aColor);
        _locX = x;
        _locY = y;
        
    }
    public void paint(Graphics2D pen)
    {
        super.paint(pen);
        _rec2.fill(pen);
        _rec3.fill(pen);
        _rec4.fill(pen);
        _rec8.fill(pen);
    }
    public void moveDown()
    {
        _rec2.setLocation(_locX, _locY +25);
        _rec3.setLocation(_locX, _locY +25);
        _rec4.setLocation(_locX, _locY +25);
        _rec8.setLocation(_locX, _locY +25);
    }
}
ReverseL:

Code:
import java.awt.*;
public class RevL extends PieceFactory
{
    private double _locX, _locY;
    
    public RevL(double x, double y, Color aColor)
    {
        super(x,y, aColor);
        _locX = x;
        _locY = y;
    }
    public void paint(Graphics2D pen)
    {
        super.paint(pen);
        _rec4.fill(pen);
        _rec6.fill(pen);
        _rec7.fill(pen);
        _rec8.fill(pen);
    }
    public void moveDown()
    {
        _rec4.setLocation(_locX, _locY +25);
        _rec6.setLocation(_locX, _locY +25);
        _rec7.setLocation(_locX, _locY +25);
        _rec8.setLocation(_locX, _locY +25);
    }
  
}
Bar:

Code:
import java.awt.*;
public class Bar extends PieceFactory
{
    private double _locX, _locY;
    
    public Bar(double x, double y, Color aColor)
    {
        super(x,y,aColor);
        _locX = x;
        _locY = y;
    }
    public void paint(Graphics2D pen)
    {
        super.paint(pen);
        _rec1.fill(pen);
        _rec2.fill(pen);
        _rec3.fill(pen);
        _rec4.fill(pen);
    }
    public void moveDown()
    {
        _rec1.setLocation(_locX, _locY +25);
        _rec2.setLocation(_locX, _locY +25);
        _rec3.setLocation(_locX, _locY +25);
        _rec4.setLocation(_locX, _locY +25);
    }
  
}
T:

Code:
import java.awt.*;
public class T extends PieceFactory
{
    private double _locX, _locY;
    
    public T(double x, double y, Color aColor)
    {
        super(x,y, aColor);
        _locX = x;
        _locY = y;
    }
    public void paint(Graphics2D pen)
    {
        super.paint(pen);
        _rec4.fill(pen);
        _rec7.fill(pen);
        _rec8.fill(pen);
        _rec12.fill(pen);
    }
    public void moveDown()
    {
        _rec4.setLocation(_locX, _locY +25);
        _rec7.setLocation(_locX, _locY +25);
        _rec8.setLocation(_locX, _locY +25);
        _rec12.setLocation(_locX, _locY +25);
    }
  
}
Z:

Code:
import java.awt.*;
public class Z extends PieceFactory
{
    private double _locX, _locY;
    
    public Z(double x, double y, Color aColor)
    {
        super(x,y, aColor);
        _locX = x;
        _locY = y;
    }
    public void paint(Graphics2D pen)
    {
        super.paint(pen);
        _rec3.fill(pen);
        _rec7.fill(pen);
        _rec8.fill(pen);
        _rec12.fill(pen);
    }
    public void moveDown()
    {
        _rec3.setLocation(_locX, _locY +25);
        _rec7.setLocation(_locX, _locY +25);
        _rec8.setLocation(_locX, _locY +25);
        _rec12.setLocation(_locX, _locY +25);
    }
}
S:

Code:
import java.awt.*;
public class S extends PieceFactory
{
    private double _locX, _locY;
    
    public S(double x, double y, Color aColor)
    {
        super(x,y, aColor);
        _locX = x;
        _locY = y;
    }
    public void paint(Graphics2D pen)
    {
        super.paint(pen);
        _rec4.fill(pen);
        _rec7.fill(pen);
        _rec8.fill(pen);
        _rec11.fill(pen);
    }
    public void moveDown()
    {
        _rec4.setLocation(_locX, _locY +25);
        _rec7.setLocation(_locX, _locY +25);
        _rec8.setLocation(_locX, _locY +25);
        _rec11.setLocation(_locX, _locY +25);
    }
}
Box:

Code:
import java.awt.*;
public class Box extends PieceFactory
{
    private double _locX, _locY;
    
    public Box(double x, double y, Color aColor)
    {
        super(x,y, aColor);
        _locX = x;
        _locY = y;
    }
    public void paint(Graphics2D pen)
    {
        super.paint(pen);
        _rec3.fill(pen);
        _rec4.fill(pen);
        _rec7.fill(pen);
        _rec8.fill(pen);
    }
    public void moveDown()
    {
        _rec3.setLocation(_locX, _locY +25);
        _rec4.setLocation(_locX, _locY +25);
        _rec7.setLocation(_locX, _locY +25);
        _rec8.setLocation(_locX, _locY +25);
    }
}
Button Panel:

Code:
import javax.swing.*;
import java.awt.event.*;

public class ButtonPanel extends JPanel implements ActionListener
{
    private JButton _button;
    private JButton _quit;
    private TetrisPanel _tetrisPanel;
    public ButtonPanel(TetrisPanel tp)
    {
        _button = new JButton("Change Peice");
        _quit = new JButton("Quit");
        _button.addActionListener(this);
        _quit.addActionListener(this);
        _tetrisPanel = tp;
        this.add(_button);
        this.add(_quit);
    }
    public void actionPerformed(ActionEvent e)
    {
        if (e.getSource() == _button)
        {
            _tetrisPanel.change();
        }
        else if(e.getSource() == _quit)
        {
            System.exit(0);
        }
    }
}
SmartRectangle:

Code:
/**
 * Chapter 7: SmartRectangle.java
 * Extends Java's Rectangle2D.Double class, adding the capabilities to
 * set color, rotation, location, and size, to move to a specified
 * location, and to display itself on a panel.
 */
public class SmartRectangle extends java.awt.geom.Rectangle2D.Double {
    private java.awt.Color _borderColor, _fillColor; // attributes
    private int _rotation;
    private final int STROKE_WIDTH = 2;

    public SmartRectangle(java.awt.Color aColor){ 
    _borderColor = aColor;
    _fillColor = aColor; // solid color to start
    _rotation = 0; // no rotation for now
    }
    
     public SmartRectangle(double x, double y, int width, int height, java.awt.Color aColor){ 
        // solid color to start
        _borderColor = aColor;
        _fillColor = aColor;        
        // no rotation for now
        _rotation = 0;
        setLocation(x,y);
        setSize(width, height);
    }
    // methods not provided by Java
    public void setBorderColor (java.awt.Color aColor) {
    _borderColor = aColor;
    }
    public void setFillColor (java.awt.Color aColor) {
    _fillColor = aColor;
    }
    public void setRotation (int aRotation) {
    _rotation = aRotation;
    }
    

    // more readable versions of methods provided by Java
    public void setLocation (double x, double y) {
    this.setFrame (x, y, this.getWidth(), 
               this.getHeight());
    }
    public void setSize (int aWidth, int aHeight) {
    this.setFrame(this.getX(), this.getY(), 
              aWidth, aHeight);
    }
    public void move (double aChangeInX, double aChangeInY) {
    this.setFrame(this.getX()+aChangeInX,
              this.getY()+aChangeInY,
              this.getWidth(),
              this.getHeight());
    }

    public void fill (java.awt.Graphics2D aBetterBrush){
    java.awt.Color savedColor = aBetterBrush.getColor();
    aBetterBrush.setColor(_fillColor);
    aBetterBrush.fill(this); // paint a solid rectangle
    aBetterBrush.setColor(savedColor);
    }
    public void draw (java.awt.Graphics2D aBrush) {
    java.awt.Color savedColor = aBrush.getColor();
    aBrush.setColor(_borderColor);
    java.awt.Stroke savedStroke = aBrush.getStroke();
    aBrush.setStroke(new java.awt.BasicStroke(STROKE_WIDTH));
    aBrush.draw(this);
    aBrush.setStroke(savedStroke);
    aBrush.setColor(savedColor);
    }
}
 
Last edited:
Member
✔️ HL Verified
🌟 Senior Member
Joined
Oct 16, 2006
Messages
379
Best answers
0
Location
the Netherlands
So what happens when the moveLeft function is called ?
Could you zip the project and upload it so we can run it ?
 
Member
✔️ HL Verified
🌟 Senior Member
Joined
Oct 16, 2006
Messages
379
Best answers
0
Location
the Netherlands
Seemed to be something easy.

add
Code:
 this.setFocusable(true);
before
Code:
this.setVisible(true);
Your key listener functions will now be called, but the piece doesn't move, this is because you're calling the 'setChangeX' function which only sets a local variable but doing nothing with it afterwards.

Good luck
 
New Member
💻 Oldtimer
Joined
Oct 3, 2004
Messages
1,462
Best answers
0
Seemed to be something easy.

add
Code:
 this.setFocusable(true);
before
Code:
this.setVisible(true);
Your key listener functions will now be called, but the piece doesn't move, this is because you're calling the 'setChangeX' function which only sets a local variable but doing nothing with it afterwards.

Good luck
How do you suggest I fix that?
Btw, I don't think the listener functions are being called because my println() test didn't print anything to console.
 
Member
✔️ HL Verified
🌟 Senior Member
Joined
Oct 16, 2006
Messages
379
Best answers
0
Location
the Netherlands
Usually with normal 2d games, where graduat movement is nessesary, you give a moveable oject an two vectors, the velocityx/y and the positionx/y, where you change the position of the object using the velocity, and decreasing it.
In this game you only need to do one step per time, so the easiest thing to do is to use the .move function, and move the current falling object. I haven't seen anything about a current falling object, so that might be a start, so distinguish your objects with types like 'CURRENT_BRICK' or 'IDLE_BRICK', so you can later check which brick you want to move, instead of everything.
Or you can have a property thats called current_brick, and reset that everytime you get a new brick.

About the printing, it has been a while since I've worked with a Java IDE, but I managed to get the printing working with JCreator, in debugmode. Just set up an empty project, add all files, and build.
 
Last edited:

Users who are viewing this thread

Top Bottom