跳跃的广场。线。防止多次跳跃

时间:2017-05-19 16:23:13

标签: java swing concurrency thread-safety

我正在尝试实施跳跃广场。广场不应该像飞扬的鸟一样跳几次,但必须返回它的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中实例化并添加到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应该在有另一个跳跃线程时阻止线程被打开,但是按住空格键会让方块击中帧的顶部。即使锁定布尔值也不适用于我。我不知道如何解决这个问题:( 请帮帮我:&#39;(

1 个答案:

答案 0 :(得分:0)

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