Игра тетрис - быстрое движение вправо и влево независимо от таймера - PullRequest
1 голос
/ 19 июня 2019

Я хотел бы сделать игру в тетрис на Java.

Я использую таймер свинга, чтобы бросать плитки.Но проблема в том, что когда я пытаюсь перемещать свои плитки влево и вправо, скорость движения ограничивается значением задержки таймера.Плитки сбрасываются каждую секунду, поэтому я могу менять их положение только тогда, когда таймер сбрасывается и перерисовывается.Как я могу выполнить независимое второе действие или любой другой метод, который может помочь мне в этом случае, любая помощь очень ценится.

package gui;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

enum Shapes {
    // T, S1, S2, K,L1, L2,
    //above members will be left commented until other tiles are prepared
    I;

    public static Shapes getRandomShapes() {

        Random random = new Random();
        return values()[random.nextInt(values().length)];
    }
}

public class Engine extends JPanel implements KeyListener, ActionListener {


    private static final long serialVersionUID = 1L;
    private int[] xPos = new int[800];
    private int[] yPos = new int[800];
    int moves = 0;
    Timer timer;
    int delay;

    Engine() {
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
        delay = 1000;
        timer = new Timer(delay, this);
        timer.start();
    }

    private boolean left;
    private boolean right;

    private void fall() {
        yPos[0] += 30;
        yPos[1] += 30;
        yPos[2] += 30;
        yPos[3] += 30;

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.WHITE);
        g.drawRect(5, 5, 482, 842);
        g.setColor(Color.BLACK);
        g.fillRect(7, 7, 478, 838);

        if (Shapes.getRandomShapes() == Shapes.I) {
            if (moves == 0) {
                xPos[0] = 60;
                xPos[1] = 90;
                xPos[2] = 120;
                xPos[3] = 150;
                yPos[0] = 6;
                yPos[1] = 6;
                yPos[2] = 6;
                yPos[3] = 6;
                moves++;
            }
            for (int x = 0; x < 4; x++) {

                ImageIcon Iimage = new ImageIcon(Engine.class.getClassLoader().getResource("images/I.png"));
                Iimage.paintIcon(this, g, xPos[x], yPos[x]);

            }
        }
        g.dispose();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        timer.start();

        fall();
        if (left) {
            xPos[0] -= 30;
            xPos[1] -= 30;
            xPos[2] -= 30;
            xPos[3] -= 30;
            left = false;
        }
        if (right) {
            xPos[0] += 30;
            xPos[1] += 30;
            xPos[2] += 30;
            xPos[3] += 30;
            right = false;
        }

        repaint();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub

        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            right = true;
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            left = true;

        }
    }


}

1 Ответ

1 голос
/ 19 июня 2019

Отсоедините логику движения (вниз) от вашего таймера, чтобы таймер мог тикать с более высокой скоростью.

Я бы поймал Instant "последней капли" и вычислил количество времени, которое прошло на каждом тике, когда оно равно или превышает 1 секунду, опускает кусок вниз

В следующем примере демонстрируется основная идея использования Instant для вычисления Duration пройденного времени и последующего выполнения некоторых действий при необходимости

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.Instant;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Drop {

    public static void main(String[] args) {
        new Drop();
    }

    public Drop() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {
        private Instant lastDropTime;
        private JLabel label;
        public TestPane() {
            setLayout(new BorderLayout());
            label = new JLabel("Drop in ...");
            add(label);

            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    if (lastDropTime == null) {
                        lastDropTime = Instant.now();
                    }
                    // I'm using toMillis so I can display the time
                    // but you could just use toSeconds
                    Duration duration = Duration.between(lastDropTime, Instant.now());
                    long millis = duration.toMillis();
                    long seconds = duration.toSeconds();

                    if (seconds >= 1) {
                        // Drop down here...
                        lastDropTime = Instant.now();
                        millis = 1000;
                    }

                    label.setText("Drop in " + (1000 - millis));
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...