-3

(The game is not complete yet but nevertheless) Using the keyboard input does not do anything, I believe this is due to KeyListener not being defined properly. Here is my code: mainClass:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;


public class mainClass extends JComponent{
    private static ballAndGameplay ball;
    private static calculateDrawPos blocks;

    public static void main(String[] a) {
        JFrame window = new JFrame("PONG");
        window.setSize(1280,720);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainClass mc = new mainClass();
        window.getContentPane().add(new mainClass());
        window.setVisible(true);
        ball = new ballAndGameplay(630,300,5,5);
        blocks = new calculateDrawPos(false,false,false,false);
        mc.addKeyListener(blocks);
        while (true){
            blocks.moveBlocks();
            ball.moveBall();
            mc.removeAll();
            mc.paint(window.getGraphics());
            try{
                Thread.sleep(10);
            }
            catch (Exception e){

            }
        }
    }
    public void paint(Graphics g) {
        g.setColor(Color.BLACK);
        g.fillRect (-10, -10, 1300, 740); 
        g.setColor(Color.WHITE);
        g.fillRect (10, blocks.PlayerOneY, 25, 125);  //left player
        g.fillRect (1230, blocks.PlayerTwoY, 25, 125);  //right player
        g.fillRect (638, -10, 4, 740); //middle line
        g.fillRect (ball.ballX, ball.ballY, 20, 20);  //ball
    }

}

calculateDrawPos:

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;


public class calculateDrawPos extends KeyAdapter implements KeyListener {
    int PlayerOneY=275;
    int PlayerTwoY=275;
    boolean wPressed;
    boolean sPressed;
    boolean upPressed;
    boolean downPressed;
    public calculateDrawPos (boolean a, boolean b, boolean c, boolean d) {
        this.wPressed=a;
        this.sPressed=b;
        this.upPressed=c;
        this.downPressed=d;
    }

    public void keyPressed(KeyEvent event) {
        int keyCode = event.getKeyCode();
        if (keyCode == KeyEvent.VK_W);
        {
            wPressed=true;
        }
        if (keyCode == KeyEvent.VK_S);
        {
            sPressed=true;
        }
        if (keyCode == KeyEvent.VK_UP);
        {
            upPressed=true;
        }
        if (keyCode == KeyEvent.VK_DOWN);
        {
            downPressed=true;
        }
    }

    public void keyReleased(KeyEvent event) {
        int keyCode = event.getKeyCode();
        if (keyCode == KeyEvent.VK_W);
        {
            wPressed=false;
        }
        if (keyCode == KeyEvent.VK_S);
        {
            sPressed=false;
        }
        if (keyCode == KeyEvent.VK_UP);
        {
            upPressed=true;
        }
        if (keyCode == KeyEvent.VK_DOWN);
        {
            downPressed=true;
        }
    }
    public void moveBlocks(){
        if (wPressed==(true)){
            PlayerOneY-=5;
        }
        if (sPressed==(true)){
            PlayerOneY+=5;
        }
        if (upPressed==(true)){
            PlayerTwoY-=5;
        }
        if (downPressed==(true)){
            PlayerTwoY+=5;
        }
    }
}

ballAndGameplay:

import java.util.Random;

public class ballAndGameplay {
    private static Random rand;
    int ballX;
    int ballY;
    int ballXVelocity;
    int ballYVelocity;
    public ballAndGameplay (int a, int b, int c, int d) {
        rand = new Random();
        this.ballX=a;
        this.ballY=b;
        this.ballXVelocity=c;
        this.ballYVelocity=d;
    }
    public void moveBall() {

        boolean pointFinished = (ballX <= -20 || ballX >= 1280);


        if (ballY <= 20 || ballY >= 700) {
            ballYVelocity*=-1;
        }
//      if ((ballY >= PlayerOneY && ballY <= PlayerOneY+125 && ballX <= 35) || (ballY >= PlayerTwoY && ballY <= PlayerTwoY+125 && ballX >= 1245)){
//          ballXVelocity*=-1.2;
//      }


        if (pointFinished==(true)){
            try{
                Thread.sleep(500);
            }
            catch (Exception e){

            }   
            ballX=630;
            ballY=300;
            getBallX();
            getBallY();
        }
        ballX+=ballXVelocity;
        ballY+=ballYVelocity;
//      System.out.println("ballX: "+ballX+"  ballY: "+ballY+"  ballXVelocity: "+ballXVelocity+"  ballYVelocity: "+ballYVelocity);
    }       
    public int getBallX(){
        if (ballX != 630){
            return ballXVelocity;
        }
        int side = rand.nextInt(2);
        int number = rand.nextInt(5);
        number+=4;
        if (side==0){
            ballXVelocity=-1*number;
        }
        else if (side==1){
            ballXVelocity=1*number;
        }
        return ballXVelocity;

    }
    public int getBallY(){
        if (ballY != 300){
            return ballYVelocity;
        }
        int side = rand.nextInt(2);
        int number = rand.nextInt(5);
        number+=4;
        if (side==0){
            ballYVelocity=-1*number;
        }
        else if (side==1){
            ballYVelocity=1*number;
        }
        return ballYVelocity;
    }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
Tom
  • 9
  • 1
    1) Use Key Bindings as [any decent search of this site and Swing and KeyListener tags will tell you](http://stackoverflow.com/questions/tagged/java+swing+keylistener?sort=votes&pageSize=15). 2) Override and draw in the JComponent's `paintComponent` method not the `paint` method, if only to avoid the jerky graphics you'll get using paint. 3) Don't forget to call the super's `paintComponent` method in your override to erase the old ball image. 4) Read the tutorials and the similar questions on this site for future problems as they'll rarely steer you wrong. 5) ***NEVER*** call `paint` directly – Hovercraft Full Of Eels Jul 15 '15 at 12:16
  • 1
    Edit, sorry but the more I look at your code, the more I see that you're doing a lot of guessing, including making wild guesses, such as how you're doing your drawing, and this will only get you in deep trouble. Please for your own sake try to avoid doing this and instead follow the examples to be found here and in the tutorials. Also, use Key Bindings, not a KeyListener, again as the [links in my search](http://stackoverflow.com/questions/tagged/java+swing+keylistener?sort=votes&pageSize=15) will tell you. – Hovercraft Full Of Eels Jul 15 '15 at 12:20
  • 1
    At least scrap "mainClass" since that is where most of your problems lie. Consider using a Swing Timer instead a `while (true)` loop since the latter risks tying up the Swing event thread, freezing your application. – Hovercraft Full Of Eels Jul 15 '15 at 12:27
  • 1
    Please look at [my example here](http://stackoverflow.com/a/18156051/522444) to see the differences between KeyListener and Key Bindings, use of Swing Graphics and uses in animation. – Hovercraft Full Of Eels Jul 15 '15 at 12:29
  • For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). – Andrew Thompson Jul 15 '15 at 12:48

2 Answers2

3

You wrote

    mainClass mc = new mainClass();
    window.getContentPane().add(new mainClass());

That means that the mainClass that you added to your window isn't the same one that mc references. So all those operations you do to mc won't make any changes in your window.

You could try writing

    mainClass mc = new mainClass();
    window.getContentPane().add(mc);

instead.

Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
  • I'm asking for advice on how to get my code to work in the sense of getting the pong user's blocks to move as the keyboard input is failing, and your recommendation did not change the way the game played at all, even if it was a bug fix. – Tom Jul 15 '15 at 12:22
  • @Tom: it fixed a **huge** bug and should at least be up-voted for the fix (as I have already done). As to getting your code to work, consider restarting from scratch but following the examples in the tutorials and that can be found here, [for example](http://stackoverflow.com/a/8961998/522444). – Hovercraft Full Of Eels Jul 15 '15 at 12:25
  • Well, if it was my code, I would probably try to step through it with a debugger, so as to learn what's actually going on here. What I answered here was the first problem I noticed with a cursory glance through the code. I haven't spent the time to copy your code into my own environment and step through it with a debugger myself. In short though, a debugger is an incredibly valuable tool in situations like this; so you should try using it here. – Dawood ibn Kareem Jul 15 '15 at 12:25
  • I have previously had sysout prints and changed values to show that the boxes move according to the corresponding variables, so I am definite that the problem lies within keyboard detection. – Tom Jul 15 '15 at 12:28
  • So, use your debugger. Put a breakpoint inside your `KeyListener` and see whether it's actually getting fired. And ALSO - follow all of the advice that Hovercraft gave in the comments. It's all great stuff. – Dawood ibn Kareem Jul 15 '15 at 12:31
1

Issues:

  • A KeyListener only works on a component that has current focus.
  • Your adding your KeyListener to a JComponent, a component that by default isn't even able to gain the focus (unlike a JButton, JTextField, and other components that typically allow keyboard interaction.)
  • One short term solution is to make your JComponent, the mc variable focusable by calling mc.setFocusable(true); and then giving it the system focus by calling mc.requestFocusInWindow();.
  • But having said this, you're still far better off using Key Bindings

Other issues:

  • Override and draw in the JComponent's paintComponent method not the paint method, if only to avoid the jerky graphics you'll get using paint.
  • Don't forget to call the super's paintComponent method in your override to erase the old ball image.
  • Never use a Graphics object obtained from a component by calling getGraphics() on it as the object thus obtained my become invalid or go null over time leading to invalid graphics or worse.
  • Never call the paint(...) or paintComponent(...) method directly as you're doing.
  • Instead use passive graphics as per the Swing graphics tutorials which I urge you to read.
  • Use a Swing Timer instead a while (true) loop since your while (true) loop risks tying up the Swing event thread, freezing your application.
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373