2015-06-13 3 views
1

Привет всем, так недавно, я сделал игру, подобную прыжку с каракулями, с перемычкой/объектом, прыгающей на следующую платформу сверху, и если вы падаете, вы теряете. Так или иначе, моя игра все работает, но есть одна проблема, я делаю это, если вы нажимаете на пробел, перемычка/объект вскакивает вверх, хорошо, вот в чем проблема: если вы продолжаете удерживать пробел, тогда перемычка будет продолжайте движение вверх, пока я не отпущу пробел, как вы это делаете, когда вы нажимаете или удерживаете пробел, перемычка/объект только перескакивает, а затем продолжает подниматься, пока я не отпущу пробел?Java Игра actionПодробные вопросы

Вот что происходит в моем коде:

Вот мое действие, выполняемое класс, где перемычка прыгает вверх или вниз

static boolean gameplay=false; 
public void actionPerformed(ActionEvent e) { 
    // TODO Auto-generated method stub 

    if (gameplay==true){ 
     if (jumper==true){ 
      DoodleHeight+20; 
     } 
     if (jumper==false){ 
      DoodleHeight=DoodleHeight-10; 
     } 

Здесь у меня есть ключи, которые контролируют прыжки

public void keyPressed(KeyEvent e) { 
    // TODO Auto-generated method stub 
    if (e.getKeyCode()==KeyEvent.VK_SPACE){ 
     jumper=true; 
    } 
} 
@Override 
public void keyReleased(KeyEvent e) { 
    // TODO Auto-generated method stub 
    if (e.getKeyCode()==KeyEvent.VK_SPACE){ 
     jumper=false; 
    } 
} 

как бы вы решили проблему? Мне нужна помощь, и я не могу понять это.

вот мой код с флагом:

import java.awt.event.*; 
import java.awt.*; 
import java.util.Scanner; 

import javax.swing.*; 
public class DoodleJumpp extends JPanel implements ActionListener,KeyListener{ 
static JFrame f; 
static int width=1200, height=930; 
static int DoodleW=500, DoodleH=500; 
static int DoodlePlatformWidth=200, DoodlePlatformHeight=400; 
static int DoodlePlatformWidth1=400, DoodlePlatformHeight1=530; 
static int DoodlePlatformWidth2=900, DoodlePlatformHeight2=874; 
static int DoodlePlatformWidth3=345, DoodlePlatformHeight3=643; 
static int DoodlePlatformWidth4=711, DoodlePlatformHeight4=957; 
static boolean rightjumper,leftjumper; 
static boolean jumper; 
static boolean test=true; 
static boolean gameplay=true; 
public void paintComponent (Graphics g){ 
    g.setColor(Color.green); 
    g.fillRect(DoodlePlatformWidth, DoodlePlatformHeight,200,30); 
    g.fillRect(DoodlePlatformWidth1, DoodlePlatformHeight1,200,30); 
    g.fillRect(DoodlePlatformWidth2, DoodlePlatformHeight2,200,30); 
    g.fillRect(DoodlePlatformWidth3, DoodlePlatformHeight3,200,30); 
    g.fillRect(DoodlePlatformWidth4, DoodlePlatformHeight4,200,30); 
    g.setColor(Color.blue); 
    g.fillRect(DoodleW, DoodleH,50,50); 
} 
public static void main(String a[]){ 
    DoodleJumpp D = new DoodleJumpp(); 
    f = new JFrame(); 
    D.init(); 
    f.add(D); 
    f.setSize(width,height); 
    f.setVisible(true); 
    f.repaint(); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    Timer t=new Timer(10,D); 
    t.start(); 
} 
public void init(){ 
    this.addKeyListener(this); 
    setFocusable(true); 
} 
@Override 
public void actionPerformed(ActionEvent e) { 
    // TODO Auto-generated method stub 
    if (gameplay==true){ 
     if (jumper==true&&test==false){ 
      DoodlePlatformHeight=DoodlePlatformHeight+20; 
      DoodlePlatformHeight1=DoodlePlatformHeight1+20; 
      DoodlePlatformHeight2=DoodlePlatformHeight2+20; 
      DoodlePlatformHeight3=DoodlePlatformHeight3+20; 
      DoodlePlatformHeight4=DoodlePlatformHeight4+20; 
     } 
     if (jumper==false&&test==false){ 
      DoodlePlatformHeight=DoodlePlatformHeight-10; 
      DoodlePlatformHeight1=DoodlePlatformHeight1-10; 
      DoodlePlatformHeight2=DoodlePlatformHeight2-10; 
      DoodlePlatformHeight3=DoodlePlatformHeight3-10; 
      DoodlePlatformHeight4=DoodlePlatformHeight4-10; 
     } 
     if (leftjumper==true&&test==false){ 
      DoodleW=(DoodleW-15); 
     } 
     if (rightjumper==true&&test==false){ 
      DoodleW=(DoodleW+15); 
     } 
     if (DoodlePlatformHeight>height){ 
      DoodlePlatformWidth=(int) Math.floor(Math.random()*1201); 
      DoodlePlatformHeight=0; 
     } 
     if (DoodlePlatformHeight1>height){ 
      DoodlePlatformWidth1=(int) Math.floor(Math.random()*1201); 
      DoodlePlatformHeight1=0; 
     } 
     if (DoodlePlatformHeight2>height){ 
      DoodlePlatformWidth2=(int) Math.floor(Math.random()*1201); 
      DoodlePlatformHeight2=0; 
     } 
     if (DoodlePlatformHeight3>height){ 
      DoodlePlatformWidth3=(int) Math.floor(Math.random()*1201); 
      DoodlePlatformHeight3=0; 
     } 
     if (DoodlePlatformHeight4>height){ 
      DoodlePlatformWidth4=(int) Math.floor(Math.random()*1201); 
      DoodlePlatformHeight4=0; 
     } 
     if (DoodleH==DoodlePlatformHeight-50 && DoodleW>=DoodlePlatformWidth-30 && DoodleW<=DoodlePlatformWidth+180){ 
      test=true; 
     } 
     if (DoodleH==DoodlePlatformHeight1-50 && DoodleW>=DoodlePlatformWidth1-30 && DoodleW<=DoodlePlatformWidth1+180){ 
      test=true; 
     } 
     if (DoodleH==DoodlePlatformHeight2-50 && DoodleW>=DoodlePlatformWidth2-30 && DoodleW<=DoodlePlatformWidth2+180){ 
      test=true; 
     } 
     if (DoodleH==DoodlePlatformHeight3-50 && DoodleW>=DoodlePlatformWidth3-30 && DoodleW<=DoodlePlatformWidth3+180){ 
      test=true; 
     } 
     if (DoodleH==DoodlePlatformHeight4-50 && DoodleW>=DoodlePlatformWidth4-30 && DoodleW<=DoodlePlatformWidth4+180){ 
      test=true; 
     } 
     f.repaint(); 
    } 
} 
static boolean flag=true; 
@Override 
public void keyTyped(KeyEvent e) { 
    // TODO Auto-generated method stub 
} 
@Override 
public void keyPressed(KeyEvent e) { 
    // TODO Auto-generated method stub 
    if (e.getKeyCode()==KeyEvent.VK_SPACE && flag == true){ 
     flag = false; 
     jumper=true; 
     test=false; 
    } 
    if (e.getKeyCode()==KeyEvent.VK_A){ 
     leftjumper=true; 
    } 
    if (e.getKeyCode()==KeyEvent.VK_D){ 
     rightjumper=true; 
    } 
} 
@Override 
public void keyReleased(KeyEvent e) { 
    // TODO Auto-generated method stub 
    if (e.getKeyCode()==KeyEvent.VK_SPACE){ 
     flag = true; 
     jumper=false; 

    } 
    if (e.getKeyCode()==KeyEvent.VK_A){ 
     leftjumper=false; 

    } 
    if (e.getKeyCode()==KeyEvent.VK_D){ 
     rightjumper=false; 
    } 
} 
} 
+0

Клавиша нажата несколько раз или она удерживается нажатой (оба сценария одинаковы). Таким образом, в вашем случае программа получает тот же ввод, что и «DoodleHeight + 20;», и перемычка будет продолжать движение вверх до тех пор, пока вы не отпустите пробел ** – mustangDC

+0

ok, но как я могу изменить код, чтобы сделать его только прыжком а затем продолжает прыгать? –

+0

ОК спасибо anyways я постараюсь думать об этом сам –

ответ

1

Проблема в том, что вы уничтожаете персонажа только при отпускании ключа!

Конкретно с этой логикой:

@Override 
public void keyReleased(KeyEvent e) { 
    // TODO Auto-generated method stub 
    if (e.getKeyCode()==KeyEvent.VK_SPACE){ 
     jumper=false; 
    } 
} 

А потом с этой логикой, когда actionPerformed

if (jumper==false){ 
     DoodleHeight=DoodleHeight-10; 
    } 

Вам нужно что-то похожее на гравитацию, что после того, как несколько раз покадровой валит характер на уровне земли

Один из способов сделать это - использовать TimerTask, который начинается, как только символ прыгает и задача на каждом таймере t ick уменьшает высоту символа до 0 или тот же, что и до того, как он прыгнул.

+0

Это то, что он делает правильно? У него есть цикл, первый бит кода. И если прыгун прав, тогда он поднимается еще дальше, и он идет вниз. События просто изменяют флаг перемычки. – Roan

+0

OP нуждается в некотором роде, чтобы игнорировать тот факт, что переменная 'jumper' была установлена ​​с помощью повторных нажатий клавиш, пока пробел удерживается (так что метод' keyPressed' будет называться много раз подряд) – MadProgrammer

+0

@ MadProgrammer не только это, после того, как персонаж прыгнул, даже если никакого действия/прикосновения не произошло, ему нужно начать сбивать персонажа, который является причиной использования TimerTask –

1

Ну вы могли бы поделиться булевой переменным между вами keyReleased и keyPressed кодом. Когда клавиша нажата, установите значение в значение false, а затем добавьте это как условие к вашему keyPressed, так что, когда флаг будет ложным, он ничего не сделает. Подобный у вас код keyReleased снова установил флаг в true, так что код keyPressed снова работает.

Так что с этими изменениями ваш код becomens:

static boolean flag = true;//<- your flag 
public void keyPressed(KeyEvent e) { 
    if (e.getKeyCode()==KeyEvent.VK_SPACE && flag == true){//<- only jump if the flag is true 
     flag = false;//<-- set flag to false, this will be reset by the keyReleased code again 
     jumper=true; 
    } 
} 
@Override 
public void keyReleased(KeyEvent e) { 
    if (e.getKeyCode()==KeyEvent.VK_SPACE){ 
     flag = true;//<-- reset flag to be able to jump again 
     jumper=false; 
    } 
} 

Я надеюсь, что это поможет :)

EDIT # 1

Version 2 это работает Altough вы, вероятно, хотите сбросить флаг, когда землю на платформе, иначе пользователь может просто спамить пробел.

@Override 
public void keyPressed(KeyEvent e) { 

// TODO Auto-generated method stub 
if (e.getKeyCode()==KeyEvent.VK_SPACE && flag == true){ 
    flag = false; 
    jumper=true; 
    test=false; 
}else{ 
    jumper=false; 
} 
if (e.getKeyCode()==KeyEvent.VK_A){ 
    leftjumper=true; 
} 
if (e.getKeyCode()==KeyEvent.VK_D){ 
    rightjumper=true; 
} 
} 
@Override 
public void keyReleased(KeyEvent e) { 

// TODO Auto-generated method stub 
if (e.getKeyCode()==KeyEvent.VK_SPACE){ 
    flag = true; 
    jumper=false; 

} 
if (e.getKeyCode()==KeyEvent.VK_A){ 
    leftjumper=false; 

} 
if (e.getKeyCode()==KeyEvent.VK_D){ 
    rightjumper=false; 
} 
}