views:

143

answers:

4

I can't seem to figure out why this is happening...

My serverPaddle (it's based on a java.awt.Component) isn't coming out the right size. I've placed System.out.println(serverPaddle.getSize()); in the thread loop and it shows that the component is the right size for 1 loop and then the next and thereafter, it's the same size as the parent (Container).

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

    private final int FRAMERATE = 60,       THIS_MUCH = 1000/FRAMERATE,
        BALL_DIAMETER = 30,                               BALL_SPEED = 15,    
        PADDLE_WIDTH = 15,    PADDLE_HEIGHT = 60,         PADDLE_SPEED = 30;
    private final Color BALL_COLOR = Color.WHITE, PADDLE_COLOR = Color.WHITE;

    private Container c;
    private Ball puck;
    private Paddle serverPaddle, clientPaddle;

...

    private Container c;

...

    c = getContentPane();

...

    public void run() {

        //Center puck
        puck = new Ball(c.getWidth()/2 - BALL_DIAMETER/2,
                        c.getHeight()/2 - BALL_DIAMETER/2, BALL_SPEED);
        puck.setSize(BALL_DIAMETER, BALL_DIAMETER);
        puck.setForeground(BALL_COLOR);
        puck.createHitbox();
        puck.setMoving(true);

        //West paddle
        serverPaddle = new Paddle(PADDLE_WIDTH,
                            c.getHeight()/2 - PADDLE_HEIGHT/2,
                            PADDLE_SPEED);
        serverPaddle.setSize(PADDLE_WIDTH, PADDLE_HEIGHT);
        serverPaddle.setForeground(PADDLE_COLOR);
        serverPaddle.createHitbox();

        c.add(puck);
        c.add(serverPaddle);

        //Draw at FRAMERATE frames per second
        while (true) {
            System.out.println(serverPaddle.getSize());
            puck.move(determineSituation());
            puck.repaint();
            wait(THIS_MUCH);
        }
    }

This is the Paddle class

import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;

public class Paddle extends GameObject implements KeyListener {

    private int x = 0, y = 0;

    public Paddle(int x, int y, int speed) {
        super(speed);
        this.x = x;
        this.y = y;
    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
    }

    public void keyReleased(KeyEvent e) {
    }

    public void paint(Graphics g) {
        setLocation(x, y);

        //These two are the culprits, the size is correct when
        //I use constants instead.
        g.fillRect(0, 0, **getWidth()**, **getHeight()**);
        updateHitbox();
    }
}

My GameObject class...

import java.awt.Component;
import java.awt.Rectangle;

public class GameObject extends Component {

    /* Members */
    private int speed = 0;
    private boolean isMoving = false;
    private Rectangle hitbox;

    //Dead south = 0 radians, anti-clockwise
    private double direction = 0;

    public GameObject(int speed) {
        this.speed = speed;
    }

    /* Accessors */
    public boolean isMoving() { return isMoving; }
    public void setMoving(boolean isMoving) { this.isMoving = isMoving; }

    public int getSpeed() { return speed; }
    public void setSpeed(int speed) { this.speed = speed; }

    public double getDirection() { return direction; }
    public void setDirection(double direction) { this.direction = direction; }

    public Rectangle getHitbox() { return hitbox; }
    public void createHitbox() { 
        hitbox = new Rectangle(getX(), getY(), getWidth(), getHeight());
    }

    public void createHitbox(int x, int y, int width, int height) { 
        hitbox = new Rectangle(x, y, width, height);
    }

    public void updateHitbox() {
        hitbox.setLocation(getX(), getY());
    }
}

even when I comment all the code out for the Ball/puck, it doesn't work. Commenting out the "wait" method doesn't work as well. It just somehow changes for some reason that I don't know but I really wanna know SO I CAN FIX THIS THING!!11

Help! Thanks.

By the way, wait is just calling Thread.sleep

public void wait(int durationInMilliseconds) {
    try {
        Thread.sleep(durationInMilliseconds);
    } catch (InterruptedException e) {
        System.out.println(e);
    }
}
A: 

Any reason you are not using Swing?

Bandi-T
Oh, I thought AWT would be a little more efficient cuz' it's a game and I'm repaint()ing a lot but... does it really matter? Should I just use Swing/did I get the wrong impression of AWT and Swing?Do you think it could be 'cause I'm using AWT? If that's the case, I'll try JComponent.
Dois
I haven't looked through your code, but yes, I do think Swing has a much more flexible layout behaviour, so I would recommend to try. AWT is not a faster version of Swing - AWT is much more limited and much less portable and much less updated. So in general, AWT is not often recommended, unless there is a very good reason. I do hope you will be able to reach proper frame rates with Swing - but make sure you understand Swing behaviour first if you seem to have problems there (look for Swing component tutorials and read up on how Swing does painting).
Bandi-T
+2  A: 

Firstly, that is an awful lot of code. You want to be able to cut the problem down so that it is small enough that it becomes trivial. And if you want other people to help, it's generally a good idea to be able to produce a complete, compilable program that shows the problem and nothing else.

As it is, it looks as if you are using the content pane of a JFrame with the default LayoutManager. This will default to BorderLayout. When you add components without specifying constraints, they will be added to the "center". Without any side components, the center component will spread out to fill all available area.

So set an appropriate layout manager. I prefer to create a JPanel and use setContentPane, rather than have to bend my code structure around getContentPane.

Tom Hawtin - tackline
+1 for spotting the default `LayoutManager`. Even more convenient, the `add()` method of `JFrame` will forward to the `contentPane`: http://java.sun.com/javase/6/docs/api/javax/swing/JFrame.html
trashgod
You're absolutely right, thanks for pointing this out. Thank you so much.
Dois
A: 

Eh...

For some very strange reason unbeknownst to me, when I add this line right below the run() method...

try {
      Clip clip = AudioSystem.getClip();
      //More to be written
    } catch (Exception e) {}

The paddle renders (correct size) correctly.

When I remove it, the problem comes back... so... what the heck?

try {
      //Clip clip = AudioSystem.getClip();
      //More to be written
    } catch (Exception e) {}
Dois
The obvious reason why that make a difference is that it changes timing, and therefore can alter the outcome of race conditions. Swing or AWT, always stick to manipulating anything to do with components on the Event Dispatch Thread (EDT). Get into the EDT (even from your main!) with the boilerplate `java.awt.EventQueue.invokeLater(new Runnable() { public void run() { ...probably call a method here... }});`. This applies to AWT as well as Swing, as AWT is full of threading bugs, and is probably a theoretical impossibility to correct.
Tom Hawtin - tackline
Oh gosh... I think you just solved a different problem I've been having.I was confUZZLED as to why my server and client programs couldn't talk to each other - my socketX.write(STUFF) was fine but the socketY.read(STUFF) wasn't reading properly for some reason it would always seem 1 step slower than it should be... my friend later had the same problem and found that if he did a socketY.readObject() [so the one writing has to send a null object] after the usual read(STUFF), the program would work fine.I guess it's these threading bugs that's causing the problem...
Dois
A: 

You might like this Java 2D games tutorial, featuring a Breakout style game.

trashgod