【问题标题】:Jumping square. thread. Prevent from jumping several times跳跃广场。线。防止多次跳跃
【发布时间】:2017-05-19 16:23:12
【问题描述】:

我正在尝试实现一个跳跃方块。方块不应该像在飞扬的小鸟中那样跳跃几次,而是必须返回它的 baseYPosition 或 - 稍后实现 - 在平台上(简单的 GeometryDash 用于学校项目的克隆)。

    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 javax.swing.JPanel;
import javax.swing.Timer;


public class Square extends JPanel implements ActionListener, KeyListener{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private int threadDelay = 40;
    public int squareYPosition = 400,squareXPosition = 400, baseYPosition = 400;
    public int jumpyness = 40, gravity=3, ySpeed, counter = 0;
    public boolean isJumping;



    public Square(){
        Timer t = new Timer(threadDelay, this);
        t.start();
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.fillRect(squareXPosition, squareYPosition, 40, 40);
    }

    public void jump(){
        ySpeed = jumpyness;

        System.out.println("squareYPosition before while: "+squareYPosition);
        System.out.println("jumping before?"+isJumping);

        if(!isJumping){
            isJumping = true;
            System.out.println("was not jumping before?"+isJumping);
            new Thread(){
                @Override
                public void run(){
                    while(isJumping && (ySpeed!=0 || squareYPosition < baseYPosition)){
                        if(squareYPosition < 0){
                            ySpeed=-1;
                            squareYPosition = 0 ;

                        }
                        System.out.println("squareYPosition: "+squareYPosition+" . ySpeed: "+ySpeed);
                        if(squareYPosition-ySpeed > baseYPosition && counter>(jumpyness/gravity)){
                            squareYPosition = baseYPosition;
                            ySpeed = 0;
                            counter = 0;
                            isJumping = false;
                            System.out.println("set ySpeed to 0");
                        }
                        else{
                            squareYPosition = squareYPosition - ySpeed;
                            ySpeed = ySpeed - gravity;
                            counter++;

                        }

                    try {
                        Thread.sleep(threadDelay);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }   
                    }


                }

            }.start();

        }

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        repaint();

    }
    @Override
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()){
        case KeyEvent.VK_SPACE:         
            this.jump();
            break;
        case 38:
            this.jump();
            break;


        }

    }
    @Override
    public void keyReleased(KeyEvent e) {}
    @Override
    public void keyTyped(KeyEvent e) {}

}

Square 类被实例化并添加到 JFrame 中。

MainFrame.java

    import java.awt.Color;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.GraphicsDevice;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainFrame extends JFrame{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Square square;

    public MainFrame(String text, GraphicsDevice device, DisplayMode displayMode){
        setTitle(text);
        setUndecorated(true);


        square = new Square();      
        add(square);


        //pack();
        setVisible(true);       
        device.setFullScreenWindow(this);
        device.setDisplayMode(displayMode);


        repaint();
        addKeyListener(square);
    }
}

PeterTest.java

    import java.awt.Color;
import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.util.Timer;
import java.util.TimerTask;

public class PeterTest {
    static long revalidateDelay = 30;

    static final int ELEMENTESTART = 3; // Elemente +1 f�r L�cken/abstand oben/unten

    public static void main(String[] args) {

        GraphicsEnvironment enivronment = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice device = enivronment.getDefaultScreenDevice();
        DisplayMode[] ds = device.getDisplayModes();

        //The following is necessary because Unix and Windows have reversed orders in DisplayMode
        int highestResolutionIndex = getHighestResolutionIndex(ds);
        DisplayMode displayMode = new DisplayMode(ds[highestResolutionIndex].getWidth(), ds[highestResolutionIndex].getHeight(), ds[highestResolutionIndex].getBitDepth(), ds[highestResolutionIndex].getRefreshRate());

        MainFrame frame = new MainFrame("Test", device, displayMode);
//      

    }

    public static int getHighestResolutionIndex(DisplayMode[] ds){
        long pixels = ds[ds.length-1].getWidth() * ds[ds.length-1].getHeight();
        int highestResolutionIndex = 0;
        for(int i = 0; i<ds.length; i++){
            long newpixels = ds[i].getWidth() * ds[i].getHeight();
            if(newpixels>=pixels){
                highestResolutionIndex = i;
                pixels = newpixels;             
            }
        }
        return highestResolutionIndex;
    }



}

布尔值 isJumping 应该防止线程在有另一个线程用于跳转时被打开,但是按住空格键会让方块撞到框架的顶部。即使锁定布尔值也不适合我。我不知道如何解决这个问题:( 请帮帮我:'(

【问题讨论】:

  • 您可能会考虑到大多数读者对您所指的 GeometryDash 的了解为零,并且您的代码没有提供自包含的可运行示例,至少可以轻松地验证当前状态。改进问题以解决这些缺点将提高您获得有用答案的机会。
  • 感谢您的推荐!我添加了提到的信息。

标签: java swing concurrency thread-safety


【解决方案1】:

自己发现了问题。好痛。问题是在 jump() 的第一行中将 ySpeed 设置为 jumpyness 而不是在此之前的线程中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多