Reputation: 755
Beginner Java developer. Trying to make a Tetris applet as part of my personal projects.
I'm at the point were I can draw tetris blocks onto the screen but I cannot make it vertically go downwards every second.
Code:
public class InitialScreen extends JApplet implements ActionListener {
public JPanel cards = new JPanel();
private JPanel introPanel = new JPanel();
public CardLayout c1 = new CardLayout();
public void init() {
initiateIntroScreen();
//game();
add(cards, BorderLayout.NORTH);
setSize(500, 100);
}
private void initiateIntroScreen() {
Frame title = (Frame)this.getParent().getParent();
cards.setLayout(c1);
JLabel centralWords = new JLabel("Click the following button options: 'Play' or 'Instructions'.");
JButton playBtn = new JButton("Play!");
JButton instructionsBtn = new JButton("Instructions!");
introPanel.add(centralWords);
introPanel.add(playBtn);
introPanel.add(instructionsBtn);
cards.add(introPanel,"1");
playBtn.addActionListener(this);
playBtn.addActionListener(new MainGame(cards,c1));
}
@Override
public void actionPerformed(ActionEvent e) {
setSize(300,410);
getContentPane().setBackground(Color.BLACK);
}
So this is the initial screen for the JApplet. Has two buttons. When you press the 'Play' button it goes to the Main Game Screen.
public class MainGame extends JApplet implements ActionListener {
private JPanel cards;
private CardLayout c1;
private JPanel gamePanel = new JPanel();
public MainGame(JPanel cards, CardLayout c1) {
this.c1 = c1;
this.cards = cards;
gamePanel.add(new Tetris_Block(new int[10][20]));
}
@Override
public void actionPerformed(ActionEvent e) {
JLabel scoreLbl = new JLabel("Score:");
gamePanel.add(scoreLbl);
cards.add(gamePanel,"game");
c1.show(cards,"game");
}
This is the game screen were Tetris is played. In the constructor it calls a Tetris Block.
public class Tetris_Block extends JComponent implements ActionListener {
static Color[] colors =
{darkGray, green, blue, red,
yellow, magenta, pink, cyan};
int[][] a;
int w, h;
static int horizontalPos, verticalPos = 0;
static int size = 20;
private int verticalPos1 = 1;
public Tetris_Block(int[][] a) {
this.a = a;
w = a.length;
h = a[0].length;
square_Block();
startTimer();
}
private void nextMove() {
verticalPos++;
verticalPos1++;
}
public void square_Block(){ //Horizontal || Vertical || Colour
//Horizontal never changes for this as I just want the blocks to go down.
a[0][verticalPos] = 3;
a[0][verticalPos1] = 3;
a[1][verticalPos] = 3;
a[1][verticalPos1] = 3;
}
@Override
public void actionPerformed(ActionEvent e) {
nextMove();
square_Block();
System.out.println(verticalPos);
}
public void startTimer(){
Timer timer = new Timer(1000,this);
timer.start();
}
public void paintComponent(Graphics g) {
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
g.setColor(colors[a[i][j]]);
g.fill3DRect(i * size, j * size,
size, size, true);
}
}
}
public Dimension getPreferredSize() {
return new Dimension(w * size, h * size);
}
My aim is to make the vertical position increment by 1 every second (So it goes down the window in second intervals.
I don't think the Timer function is the problem. When I print verticalPos it prints out the incremented value every second, however it's just displaying the new location onto the screen- that is the problem.
Image of window right now.
[img]https://i.sstatic.net/sHQVA.png
Upvotes: 0
Views: 1163
Reputation: 347314
Start by adding a call to repaint
in you actionPerformed
method of your Tetris_Block
@Override
public void actionPerformed(ActionEvent e) {
nextMove();
square_Block();
System.out.println(verticalPos);
// This is important
repaint();
}
This will schedule a paint event on the event queue which will eventually call your paintComponent
method (indirectly)
This will get the block to start moving. The next problem you will have is you're not actually "removing" the block from it's previous position, so it will continue to bleed/grow down the screen
You could solve this by passing in the color of the block to square_Block
, for example...
public void square_Block(int color) { //Horizontal || Vertical || Colour
//Horizontal never changes for this as I just want the blocks to go down.
a[0][verticalPos] = color;
a[0][verticalPos1] = color;
a[1][verticalPos] = color;
a[1][verticalPos1] = color;
}
And then "rest" the blocks of the current position, update the position and then set the new block colors;
@Override
public void actionPerformed(ActionEvent e) {
square_Block(0);
nextMove();
square_Block(3);
System.out.println(verticalPos);
repaint();
}
Upvotes: 4
Reputation: 1588
Your design here may be faulty. You need to have a game loop that runs in a separate thread. It has to be a separate thread from the main thread so the user can still click buttons. Once you have a loop in the separate thread you need to have a method that you call for every game tick. It's in that method that you update the coordinates of the blocks.
Game loop works like this: 1. Read state of the game and draw the blocks 2. Process user input. 3. Update game state
I know this is abstract but I hope it helps. Google about java games and game loops.
Upvotes: 0