Jump to content

  • Log In with Google      Sign In   
  • Create Account

thread error


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
139 replies to this topic

#101 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 12 August 2012 - 08:32 PM

yeah i just want the ball to stop when it hits the fixedBallRectangle

If you see a post from me, you can safely assume its C# and XNA :)


Sponsor:

#102 j-locke   Members   -  Reputation: 825

Like
0Likes
Like

Posted 12 August 2012 - 08:40 PM

Do you have the mainBall moving automatically or being moved by you? if moved by you, go ahead and post all of your code so I can see what else is going on.

#103 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 12 August 2012 - 08:43 PM

the mainBall is being moved by the keyboard

[source lang="java"]import java.applet.Applet;import java.awt.Color;import java.awt.Component;import java.awt.Event;import java.awt.Graphics;import java.awt.Image;import java.awt.Rectangle;import java.util.ArrayList;import java.util.concurrent.TimeUnit;public class game extends Applet implements Runnable{ static final int WIDTH = 450; //set screen height static final int HEIGHT = 450; // set screen width private Image dbImage; private Graphics dbg; public static long NEW_DOT_FREQ = TimeUnit.SECONDS.toMillis(3); public long lastUpdateTime; public long timeSinceLastNewDot; public ArrayList<Ball> BALLS; //arraylist to store balls Color[] color = {Color.red, Color.blue, Color.green, Color.yellow, Color.magenta, Color.black}; int colorIndex; static final int NUM_OF_BALLS = 4; int i; int t; MainBall mainBall = new MainBall(100, 100, 10, 10, 0, 0); Ball fixedBall = new Ball(250, 250, 20, 20); Rectangle mainBallRectangle = getMainBallBounds(); Rectangle fixedBallRectangle = getFixedBallBounds(); Thread updateTime = new updateTime(); public void start() { lastUpdateTime = System.currentTimeMillis(); Thread th = new Thread(this); th.start();//start main game updateTime.start(); } public void updateGame() { //Get the current time long currentTime = System.currentTimeMillis(); //Calculate how much time has passed since the last update long elapsedTime = currentTime - lastUpdateTime; //Store this as the most recent update time lastUpdateTime = currentTime; //Create a new dot if enough time has passed //Update the time since last new dot was drawn timeSinceLastNewDot += elapsedTime; if (timeSinceLastNewDot >= NEW_DOT_FREQ) { int newX = randomNumber(); int newY = randomNumber(); debugPrint("New dot created at x:" + newX + ", y:" + newY + "."); BALLS.add(new Ball(newX, newY, 20, 20)); timeSinceLastNewDot = 0; } } private void debugPrint(String value) { System.out.println(value); } public class updateTime extends Thread implements Runnable { public void run() { for(t = 0; ; t++) { try { Thread.sleep(1000); } catch(InterruptedException e){} } } } public int randomNumber() { return (int)(Math.random() * 400); } public int getRandomColor() { return (int)(Math.random() * 6); } public class MainBall { int width; int height; int xpos; int ypos; int xspeed; int yspeed; public MainBall( int xpos, int ypos, int width, int height, int xspeed, int yspeed) { this.width = 10; this.height = 10; this.xpos = 100; this.ypos = 100; this.xspeed = 0; this.yspeed = 0; } public void paintMainBall(Graphics g) { g.setColor(Color.black); g.fillOval(mainBall.xpos, mainBall.ypos, width, height); g.drawString(xpos + ", " + ypos, 20, 40); } }//mainBall class Ball { int x; int y; int width; int height; public Ball(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; }//end ball public void paint(Graphics g) { g.setColor(color[getRandomColor()]); g.fillOval(x, y, width, height); } //end paint } //ball class public void update(Graphics g) //double buffer don't touch!! { if(dbImage == null) { dbImage = createImage(this.getSize().width, this.getSize().height); dbg = dbImage.getGraphics(); } dbg.setColor(getBackground()); dbg.fillRect(0, 0, this.getSize().width, this.getSize().height); dbg.setColor(getForeground()); paint(dbg); g.drawImage(dbImage, 0, 0, this); } public boolean keyDown (Event e, int key) { if(key == Event.LEFT) { mainBall.xspeed = -5; mainBall.yspeed = 0; } if(key == Event.RIGHT) { mainBall.xspeed = 5; mainBall.yspeed = 0; } if(key == Event.UP) { mainBall.yspeed = -5; mainBall.xspeed = 0; } if(key == Event.DOWN) { mainBall.yspeed = 5; mainBall.xspeed = 0; } return true; } public void run() { while(true) { repaint(); if (mainBall.xpos < 1) { mainBall.xpos = 449; } if (mainBall.xpos > 449) { mainBall.xpos = 1; } if (mainBall.ypos < 1) { mainBall.ypos = 449; } if (mainBall.ypos > 449) { mainBall.ypos = 1; } mainBall.ypos += mainBall.yspeed; mainBall.xpos += mainBall.xspeed; try { Thread.sleep(20); } catch(InterruptedException ex){} } } public void init() { this.setSize(WIDTH, HEIGHT); BALLS = new ArrayList<Ball>(); System.out.println(getFixedBallBounds()); } public void paint(Graphics g) { g.drawString("time: " + t, 20, 20); mainBall.paintMainBall(g); g.setColor(Color.blue); fixedBall.paint(g); for (Ball ball : BALLS) { ball.paint(g); } updateGame(); } public Rectangle getFixedBallBounds() { return new Rectangle (250, 250, 20, 20); } public Rectangle getMainBallBounds() { return new Rectangle(mainBall.xpos, mainBall.ypos, 10, 10); } public boolean checkCollision() { if(mainBallRectangle.intersects(fixedBallRectangle)) { mainBall.xspeed = 0; mainBall.yspeed = 0; mainBall.xpos = 100; mainBall.ypos = 100; } return true; }}[/source]

If you see a post from me, you can safely assume its C# and XNA :)


#104 j-locke   Members   -  Reputation: 825

Like
0Likes
Like

Posted 12 August 2012 - 08:51 PM

I don't see where you're calling checkChollision anywhere. Am I just overlooking it?

#105 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 12 August 2012 - 08:59 PM

no youre not. im just retarded. do i call it in the run method within the while loop?

just tried that and it didnt work. so ill try a few other places

Edited by burnt_casadilla, 12 August 2012 - 09:00 PM.

If you see a post from me, you can safely assume its C# and XNA :)


#106 j-locke   Members   -  Reputation: 825

Like
0Likes
Like

Posted 12 August 2012 - 09:10 PM

You'll want to keep simplifying the run method more and more. Ideally that method should be pretty much what the run method was in that simple example code that I posted. When things are getting toyed with in fewer places, it's easier for you to know where to go when something isn't behaving like you want it to.

In game's paint method, I think you should move the updateGame() call to the beginning of the method instead of the end. Also, moving all of your game logic into updateGame will make this more straightforward. Right now you have some in updateGame and some in run.

#107 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 12 August 2012 - 09:20 PM

that does look a lot nicer lol. but moving the checkCollision method to updateGame doesnt do anything so im thinking it has something to do with the actual method

If you see a post from me, you can safely assume its C# and XNA :)


#108 j-locke   Members   -  Reputation: 825

Like
0Likes
Like

Posted 12 August 2012 - 09:34 PM

Alright now that it's happening in one location, it's easier to make sure things happen in the order that we want.

You'll want to make sure that you do the checkCollision check (and setting the speed to 0), just before you update the mainBall position.

[source lang="java"]//Update mainBall RectanglemainBallRectangle = getMainBallBounds();//Check for collisionscheckCollision();//Update mainBall positionmainBall.ypos += mainBall.yspeed;mainBall.xpos += mainBall.xspeed;//Wrap mainBall positionif (mainBall.xpos < 1){}............[/source]

Now you have the collision code that will potentially set the speed to 0 right before the location is updated based on that speed.

#109 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 12 August 2012 - 09:47 PM

Still not working :/ i have no idea what im doing wrong

If you see a post from me, you can safely assume its C# and XNA :)


#110 j-locke   Members   -  Reputation: 825

Like
0Likes
Like

Posted 12 August 2012 - 09:54 PM

Let's have a look at what your code is looking like now.

I can say the first things I'll be looking at are where those two rectangles are getting set. The idea is to make sure they're being set when they have the legit information in them. Putting a breakpoint in the checkCollision method is also a good idea to confirm that intersects check is actually returning true like we expect it to. And after that to put breakpoints at the lines where the ball's position is actually updated (mainBall.xpos += mainBall.xspeed;) to confirm that it has the value I expect it to have. You should also take a look at those points. They seem like likely places for things to be going wrong to me.

It'll probably be tomorrow before I give any indepth look though. I'll take a look at the code for essentially the first step that I said because that one could be a quick one to notice. But since the others will take running and debugging code, I'll put those off in my tired state.

#111 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 12 August 2012 - 09:58 PM

here it is. im done coding for the night tho lol

[source lang="java"]import java.applet.Applet;import java.awt.Color;import java.awt.Component;import java.awt.Event;import java.awt.Graphics;import java.awt.Image;import java.awt.Rectangle;import java.util.ArrayList;import java.util.concurrent.TimeUnit;public class game extends Applet implements Runnable{ static final int WIDTH = 450; //set screen height static final int HEIGHT = 450; // set screen width private Image dbImage; private Graphics dbg; public static long NEW_DOT_FREQ = TimeUnit.SECONDS.toMillis(3); public long lastUpdateTime; public long timeSinceLastNewDot; public ArrayList<Ball> BALLS; //arraylist to store balls Color[] color = {Color.red, Color.blue, Color.green, Color.yellow, Color.magenta, Color.black}; int colorIndex; static final int NUM_OF_BALLS = 4; int i; int t; MainBall mainBall = new MainBall(100, 100, 10, 10, 0, 0); Ball fixedBall = new Ball(250, 250, 20, 20); Rectangle mainBallRectangle = getMainBallBounds(); Rectangle fixedBallRectangle = getFixedBallBounds(); Thread updateTime = new updateTime(); public void start() { lastUpdateTime = System.currentTimeMillis(); Thread th = new Thread(this); th.start();//start main game updateTime.start(); } public void updateGame() { checkCollision(); //Get the current time long currentTime = System.currentTimeMillis(); //Calculate how much time has passed since the last update long elapsedTime = currentTime - lastUpdateTime; //Store this as the most recent update time lastUpdateTime = currentTime; //Create a new dot if enough time has passed //Update the time since last new dot was drawn timeSinceLastNewDot += elapsedTime; if (timeSinceLastNewDot >= NEW_DOT_FREQ) { int newX = randomNumber(); int newY = randomNumber(); debugPrint("New dot created at x:" + newX + ", y:" + newY + "."); BALLS.add(new Ball(newX, newY, 20, 20)); timeSinceLastNewDot = 0; } if (mainBall.xpos < 1) { mainBall.xpos = 449; } if (mainBall.xpos > 449) { mainBall.xpos = 1; } if (mainBall.ypos < 1) { mainBall.ypos = 449; } if (mainBall.ypos > 449) { mainBall.ypos = 1; } try { Thread.sleep(20); } catch(InterruptedException ex){} checkCollision(); mainBall.ypos += mainBall.yspeed; mainBall.xpos += mainBall.xspeed; } private void debugPrint(String value) { System.out.println(value); } public class updateTime extends Thread implements Runnable { public void run() { for(t = 0; ; t++) { try { Thread.sleep(1000); } catch(InterruptedException e){} } } } public int randomNumber() { return (int)(Math.random() * 400); } public int getRandomColor() { return (int)(Math.random() * 6); } public class MainBall { int width; int height; int xpos; int ypos; int xspeed; int yspeed; public MainBall( int xpos, int ypos, int width, int height, int xspeed, int yspeed) { this.width = 10; this.height = 10; this.xpos = 100; this.ypos = 100; this.xspeed = 0; this.yspeed = 0; } public void paintMainBall(Graphics g) { g.setColor(Color.black); g.fillOval(mainBall.xpos, mainBall.ypos, width, height); g.drawString(xpos + ", " + ypos, 20, 40); } }//mainBall class Ball { int x; int y; int width; int height; public Ball(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; }//end ball public void paint(Graphics g) { g.setColor(color[getRandomColor()]); g.fillOval(x, y, width, height); } //end paint } //ball class public void update(Graphics g) //double buffer don't touch!! { if(dbImage == null) { dbImage = createImage(this.getSize().width, this.getSize().height); dbg = dbImage.getGraphics(); } dbg.setColor(getBackground()); dbg.fillRect(0, 0, this.getSize().width, this.getSize().height); dbg.setColor(getForeground()); paint(dbg); g.drawImage(dbImage, 0, 0, this); } public boolean keyDown (Event e, int key) { if(key == Event.LEFT) { mainBall.xspeed = -5; mainBall.yspeed = 0; } if(key == Event.RIGHT) { mainBall.xspeed = 5; mainBall.yspeed = 0; } if(key == Event.UP) { mainBall.yspeed = -5; mainBall.xspeed = 0; } if(key == Event.DOWN) { mainBall.yspeed = 5; mainBall.xspeed = 0; } return true; } public void passThroughWalls() { } public void run() { while(true) { repaint(); } } public void init() { this.setSize(WIDTH, HEIGHT); BALLS = new ArrayList<Ball>(); System.out.println(getFixedBallBounds()); } public void paint(Graphics g) { updateGame(); g.drawString("time: " + t, 20, 20); mainBall.paintMainBall(g); g.setColor(Color.blue); fixedBall.paint(g); for (Ball ball : BALLS) { ball.paint(g); } } public Rectangle getFixedBallBounds() { return new Rectangle (250, 250, 20, 20); } public Rectangle getMainBallBounds() { return new Rectangle(mainBall.xpos, mainBall.ypos, 10, 10); } public void checkCollision() { if(mainBallRectangle.intersects(fixedBallRectangle)) { mainBall.xspeed = 0; mainBall.yspeed = 0; mainBall.xpos = 100; mainBall.ypos = 100; } }}[/source]

If you see a post from me, you can safely assume its C# and XNA :)


#112 j-locke   Members   -  Reputation: 825

Like
1Likes
Like

Posted 12 August 2012 - 10:02 PM

You'll want to take a look at the code snippet that I posted most recently. In your updateGame method, you'll want to update the mainBall Rectangle and you might as well do the fixedBall one as well. Make sure you do that before you check for collisions in the method.

#113 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 12 August 2012 - 10:05 PM

oooooh now it works. my brain is tired lol. tomorrow ill deal with collision and the arraylist

If you see a post from me, you can safely assume its C# and XNA :)


#114 j-locke   Members   -  Reputation: 825

Like
0Likes
Like

Posted 12 August 2012 - 10:08 PM

Yeah, I'm done for the night as well. You made good progress for a weekend of coding. Hopefully you've learned some stuff and are feeling more comfortable with what's going on as well. That's what it's really all about. Building that understanding and comfort in knowing that you're growing as a developer. :)

#115 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 13 August 2012 - 03:16 PM

alright back to work lol
i have this in my ball class

[source lang="java"] public Rectangle getBallBounds() { for(Ball ball : BALLS) return new Rectangle() }[/source]

this should return a rectangle every time one is created i think? besides the return method not being finished. i dont know how to call the coordinates of a ball in the array

Changed it to this

[source lang="java"] public Rectangle getBallBounds() { for(int i = 0; i < BALLS.size(); i++) { return new Rectangle(BALLS(i).x, BALLS(i).y, 20, 20); } Rectangle ballRectangle = getBallBounds(); }[/source]

so i will increase when the arraylist BALLS increases. but for some reason its saying BALLS(int) isnt a method when i want to call the ArrayList BALLS

and now to this

[source lang="java"] public Rectangle getBallBounds() { for(int i = 0; i < BALLS.size(); i++) { return new Rectangle(BALLS.get(i).x, BALLS.get(i).y, 20, 20); } Rectangle ballRectangle = getBallBounds(); }[/source]

now its saying the type im returning isnt a rectangle?

alright try again...
[source lang="java"] public Rectangle getBallBounds() { for(int i = 0; i < BALLS.size(); i++) { new Rectangle(BALLS.get(i).x, BALLS.get(i).y, 20, 20); } return randomBallRectangle; }[/source]

i made an object in the main game class Rectangle randomBallRectangle = getBallBounds();
the compiler shows no errors until i run it then i get this:

java.lang.NullPointerException
at game.getBallBounds(game.java:290)
at game.<init>(game.java:38)

Edited by burnt_casadilla, 13 August 2012 - 04:57 PM.

If you see a post from me, you can safely assume its C# and XNA :)


#116 j-locke   Members   -  Reputation: 825

Like
0Likes
Like

Posted 13 August 2012 - 06:13 PM

In the Ball class is definitely the right place for this method. Glad to see you moved it there rather than keeping it outside of the class. :)

You don't want a for loop here. The reason you don't goes back to a concept that we talked about earlier. This class is designed to represent 1 ball. That means inside the Ball class, you should pretend that the array of balls doesn't exist. Because this code is intended to represent 1 ball, it doesn't care if you stick it in an array or not to make your game work. Because you do want an array of balls for your game, that's why your game class is creating and managing an array of balls.

So this method inside the Ball class should be concerned with returning you the Rectangle that encloses "me".. "me" being the 1 and only ball that it knows or cares about. The fact that you have an array of Balls and need Rectangles for them all is something for the game class to deal with (again, because the game class does want this array of Balls so that it can accomplish what it wants for this game).

So for the first step, focus on getting this method returning the Rectangle around itself (the "me" I mentioned before).
And then for the second step, get a loop (somewhere in the game class because the Ball class doesn't and shouldn't care about the array) that goes through each of the Balls in the array and stores you a Rectangle for each one.
Note: Determining where step 2 goes should be made easier by the fact that we did some simplifying of things last night. In your game class, you should be adding code in one of relatively few places. In the init method if you just need it to happen once when you initially launch your game. In the updateGame method if it's related to updating things that change during your game. And in the paint method if this involves drawing things for your game.

#117 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 13 August 2012 - 06:17 PM

[source lang="java"] public Rectangle getBallBounds() { return new Rectangle(this.x, this.y, 20, 20); } [/source]

this is called everytime the ball class is used?

can you explain why i should keep this in the ball class? why would it be any different if it was outside of the class?

im thinking i should put it in the updateGame method and in the if method after the new ball is created every three seconds

[source lang="java"] if (timeSinceLastNewDot >= NEW_DOT_FREQ) { int newX = randomNumber(); int newY = randomNumber(); debugPrint("New dot created at x:" + newX + ", y:" + newY + "."); BALLS.add(new Ball(newX, newY, 20, 20)); getBallBounds(); timeSinceLastNewDot = 0; }[/source]

so maybe something like this?

Edited by burnt_casadilla, 13 August 2012 - 06:20 PM.

If you see a post from me, you can safely assume its C# and XNA :)


#118 j-locke   Members   -  Reputation: 825

Like
0Likes
Like

Posted 13 August 2012 - 07:43 PM

can you explain why i should keep this in the ball class? why would it be any different if it was outside of the class?


Definitely. Good question. Inside the class, it allows you to have a ball object Ball myBall = new Ball(x, y, width, height); and be able to refer to that ball's rectangle without needing to know about or deal with any other balls, Rectangle boundary = myBall.getBallBounds();.

If I put it outside the class and I want to know the boundaries of any given ball, I'll need to provide this method with what ball I am talking about (something like Rectangle boundary = getBallBounds(myBall);). It would certainly not be wrong to do it that way. But I've noticed that generally if you're making a method from scratch, you've tended to make it with no parameters. So I was favoring the way your were already writing methods.

And another perk (but not a 'metric' you should be using to make decisions at this point) is if your next game was going to do something different but still be using balls, you could very well have this Ball class in its own file and use it for both this game and the next one. If you have getBallBounds(Ball ball) in this game class, that means if your next game needed that same functionality, you'd have to implement it again. But since it does make good sense that the ball would be able to provide you with its own bounds, having inside the class is logical and makes one less piece of functionality that you'd have to re-implement.

im thinking i should put it in the updateGame method and in the if method after the new ball is created every three seconds

...

so maybe something like this?

In this code, you call getBallBounds() so it's returning you a Rectangle object but you're not doing anything with it. So you're not using it right now nor are you saving it somewhere (in some variable) so you can pull it back up later to use.

Your getBallBounds method is looking alright. You did pull up the x and y values from this particular ball. Why did you hardcode the width and height rather than pulling those values from this particular ball as well?

Edited by j-locke, 13 August 2012 - 07:45 PM.


#119 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 13 August 2012 - 07:49 PM

the width and height of the randomBalls will always be 20, 20 for now until i figure this out and can add more types of balls.

thanks for the explanation Posted Image

well in the code i listed it would be calling the method, but in the main game class i would create the object Rectangle randomBallRectangle = getBallBounds();



also for my next game im planning on making a "Snake" clone so ill keep in mind what methods and classes i can reuse

Edited by burnt_casadilla, 13 August 2012 - 07:50 PM.

If you see a post from me, you can safely assume its C# and XNA :)


#120 j-locke   Members   -  Reputation: 825

Like
0Likes
Like

Posted 13 August 2012 - 08:30 PM

well in the code i listed it would be calling the method, but in the main game class i would create the object Rectangle randomBallRectangle = getBallBounds();


Ah, ok. You may already know this (because I realize we're talking in kind of code short hand sometimes and it's just understood what code goes where) but in case not I'll bring it up now before it is an issue of confusion later.


When you call getBallBounds(), it will return you the Rectangle and store it in whatever variable you put on the left side of the equal sign. So if you call balls.get(i).getBallBounds(), it won't go find some matching piece of code to find out where to store the Rectangle that is returned. It will simply return it and then it will be forever lost. So the confusion i wanted to be sure to avoid is that calling getBallBounds() is useless unless you are using the returned Rectangle either by having it in a statement (such as if (playerRectangle.intersects(balls.get(i).getBallBounds()))) or storing it so you can use it later (such as randomBallRectangle = balls.get(i).getBallBounds()).

I like that the next planned project isn't overly complex. That small steps approach will have you making some bigger projects in a couple of months time and hopefully not feeling TOO overwhelmed as you didn't jump too far beyond your knowledge all at once. :)




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS