Archived

This topic is now archived and is closed to further replies.

An Array of One

This topic is 5007 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm doing a variant of pong in java and I've hit a rather peculiar problem. I have created several classes set to interact with each other in approriate manners (balls, paddles, etc). Anyway, I've got my little ball bouncing around rather nicely, the collision detection betweeen the paddles works and it destroys and bounces off of any blocks it hits. The problem, though, comes in creating the array of blocks I've created. It is supposed to line up 30 blocks in 3 rows of 10 blocks each. I create it using something like this:
//"global" variable section

private Block tempBlock = new Block();
private Block blockArray[] = new Block[30];
private int arrayCount;

//init method

arrayCount = 0;
for(int i = 0; i < 10; i++)
{
   for(int j = 0; j < 3; j++)
   {
      tempBlock.setPos(i*80, j*25);
      blockArray[arrayCount] = tempBlock;
      arrayCount++;
   }
}

//paint(Graphics g)

for(int i =  0; i < 30; i++)
{
   blockArray[i].draw(g);
}

//run method

for(int i = 0; i < 30; i++)
{
   myBall.penetrate(blockArray[i]);
}
myBall.update();

Ok, now for a bit of explanation. Block is a class I've created. It has an x and y position, x and y velocity, height, width, methods to draw, update, accessors, mutators, all the good stuff. myBall is of class Ball which has similar attributes as well as the all important penetrate function. Penetrate is passed a Block and returns true if a collision is about to take place (based off the ball's velocity). If a collision does happen, the balls velocity is inverted in whatever direction the collision has occured in. All this stuff (minus the array problems which I will outline in a second) works extremely well (much to my delight, as this has been a rather swift and easy project). Now for the problem. When I run the problem, offly offe block is drawn (and I'm pretty sure offly offe is there but I really don't have a great way to check if they're all overlapped off each other as they would all be destroyed at offce, but I've done a few tests and am fairly confident there really is offly offe block there). The ball collides with it and destroys it as it should, but there should be 29 more blocks! This is rather puzzling to me. A bit of info off the situation: it always draws the block created last . So in this situation, it always creates the block at position (800, 75). Also, I used the tempBlock because I could just do a "blockArray[arrayCount].setPos(i*80, j*25)", as much as I would have liked to. It simply doesn't compile (any thoughts off that?). Anyway, back to the larger problem of offly creating offe block when there should be thirty, have I just failed to initialize the elements of the array in some way? I have tried doing a for-loop just above the first offe shown above that looks like: tempBlock.setPos(0, 0); for(int i = 0; i < 30; i++) blockArray = tempBlock; To just make sure all the items in the array were initialized (although unless arrays in Java are significantly different from those in C++, I do not believe this to be necessary as all the elements of the array should be initialized by their constructor). So! Does anyone see anything here that may be causing the problem? Perhaps something silly I've done (or haven't done) with the arrays? I'm new to Java but have many years experience in C++ (many of which weren't necessary in the creation of this simple problem, but all of which are failing to help me locate the source of the problem), so everything looks pretty good to me. Thanks in advance for any and all help! Mike When you find yourself in the company of a halfling and an ill-tempered Dragon, remember, you do not have to outrun the Dragon... *Edit: Just fixed the source code box* [edited by - CyberSlag5k on March 26, 2004 11:07:16 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I think it''s called breakout if that helps.

Google Breakout clones

Share this post


Link to post
Share on other sites
You only allocate a single block (tempBlock) and use this single instance 30 times. you must create a block (with new) for EACH block you want to have. Otherwise you have 30 blocks which are identical.

Share this post


Link to post
Share on other sites
I think I see what''s going on. It looks like a classic mistake with references.

In the line :
private Block tempBlock = new Block();

you are actually creating a reference (pointer) to a Block, called tempBlock. Then in initialization, you are altering the position of that Block and placing it in the array. In effect the entier array is referencing (pointing to) the same Block, which ends up with the co-ordinates you specified last.

I don''t know why "blockArray[arrayCount].setPos(i*80, j*25);" won''t compile. What was the message?

The way to solve this problem is to remove the line "private Block tempBlock = new Block();" at the top and instead place it in the loop like so:

for(int j = 0; j < 3; j++) {
Block tempBlock = new Block();
tempBlock.setPos(i*80, j*25);
blockArray[arrayCount] = tempBlock;
arrayCount++;
}

This will get each part of the array pointing to a different block. This is a common error in Java because reference and value variables look the same in code.

This will also cause you trouble if you try to compare 2 strings eg:

String a = "Me"; String b = "Me";
if(a==b){...}

will be false bacause a and b are actually references to different objects.

Share this post


Link to post
Share on other sites
quote:
Original post by Enolagay
I think I see what''s going on. It looks like a classic mistake with references.

In the line :
private Block tempBlock = new Block();

you are actually creating a reference (pointer) to a Block, called tempBlock. Then in initialization, you are altering the position of that Block and placing it in the array. In effect the entier array is referencing (pointing to) the same Block, which ends up with the co-ordinates you specified last.


Ohhh, I see. Thank you very much (you too, VolkerG). That ought to do the trick.

I''m not sure what the error was, I''ll recompile tonight and post it.

Thanks again!

Mike

When you find yourself in the company of a halfling and an ill-tempered Dragon, remember, you do not have to outrun the Dragon...

Share this post


Link to post
Share on other sites
Hmm, but it looks to me like tempBlock is just a plain Block, not a pointer, and blockArray[arrayCount] = tempBlock should only copy the contents of tempBlock to the current entry in the array, which is good. I think the problem is that you''re declaring the array with private Block blockArray[] = new Block[30];, when it should be private Block *blockArray = new Block[30];.
But then looking back at it, setting tempBlock to a new Block is wrong too, because if it''s not a pointer, then it''s already a full Block in memory, so you shouldn''t have to allocate a new one for it. Just set it to Block(), not new Block() to initialize its members.

Share this post


Link to post
Share on other sites
I''ll give both a try and let you know. Thanks Deku.

Mike

When you find yourself in the company of a halfling and an ill-tempered Dragon, remember, you do not have to outrun the Dragon...

Share this post


Link to post
Share on other sites
quote:
Original post by Enolagay
This will also cause you trouble if you try to compare 2 strings eg:

String a = "Me"; String b = "Me";
if(a==b){...}

will be false bacause a and b are actually references to different objects.


... Except that Java has special handling for class String which will cause the same object to be used for both references here. (It''s able to do this as an optimization because Strings are immutable). Dynamically created things (something as simple as replacing String b with "M" + "e" might work, depending on how good your compiler is) normally will not get handled like that, but there exists a method on String "intern()" which will look up the current String text in a registry, and if it matches, return a reference to a previous String with the same text. So with some care, you can forget about how Java works for a second and treat Strings like value objects. (Personally, though, I''d rather remain conscious of what''s going on under the hood. )

(Disclaimer: this is all based on my reading of the relevant JavaDoc; I didn''t work on the language implementation or anything like that.)

Share this post


Link to post
Share on other sites
quote:
Original post by Zahlman
but there exists a method on String "intern()" which will look up the current String text in a registry, and if it matches, return a reference to a previous String with the same text.

A more robust/correct way of doing things would be String.equals(String).

Share this post


Link to post
Share on other sites
Awsome, everything is working correctly now. The answer was indeed to do a "tempBlock = new Block()" for each array element. I''m not sure what I was doing before, but I could get "blockArray[arrayCount].setPos(i*80, j*25)" to compile now.

Thank you to all who helped!

Mike

When you find yourself in the company of a halfling and an ill-tempered Dragon, remember, you do not have to outrun the Dragon...

Share this post


Link to post
Share on other sites