#61 Members - Reputation: 507
Posted 11 August 2012 - 06:54 PM
When you removed the loop from Ball's paint method, did you also change it so it wasn't doing any ball[i] stuff? There wouldn't need to be any array stuff in there.
And you kept the loop in game's paint method?
#62 Members - Reputation: 235
Posted 11 August 2012 - 07:00 PM
[source lang="java"]class Ball { int x; int y; int width; int height; Color mycolor; public Ball(int x, int y, int width, int height, Color mycolor) { this.x = x; this.y = y; this.width = width; this.height = height; this.mycolor = mycolor; }//end ball public void paint(Graphics g) { g.setColor(mycolor); g.fillOval(x, y, width, height); } //end paint } //ball class [/source]
[source lang="java"]public void paint(Graphics g) { g.drawString("time: " + t, 20, 20); g.drawString("Red ball: " + randomNumber() + ", " + randomNumber(), 20, 40); g.drawString("blue ball: " + randomNumber() + ", " + randomNumber(), 20, 60); g.drawString("green ball: " + randomNumber() + ", " + randomNumber(), 20, 80); g.drawString("magenta ball: " + randomNumber() + ", " + randomNumber(), 20, 100); g.setColor(Color.black); g.fillOval(xpos - radius, ypos - radius, 2 * radius, 2 * radius); for(i = 0; ilessthanNUM_OF_BALLS; i++) { ball[i].paint(g); } }}[/source]
#63 Members - Reputation: 507
Posted 11 August 2012 - 07:04 PM
For the thread code you added, I wanna say I think adding threads is only going to make this more complex, harder to maintain and harder to understand what's going wrong when something does. But if you insist on diving into threads, We'll need to see the code where you start or schedule that thread to run. For the code you posted, if (t == 5) would never be true. You have a for loop that runs from 0 through 9 and quits when t equals 10 so t will equal 10 when that loop is exited. If it were to ever be true, the line of code inside just generates a random number but doesn't do anything with it or put it anywhere so that you can use it (assuming the randomNumber method is the same as before).
#65 Members - Reputation: 235
Posted 11 August 2012 - 07:14 PM
[source lang="java"] public void paint(Graphics g) { g.drawString("time: " + t, 20, 20); g.drawString("Red ball: " + randomNumber() + ", " + randomNumber(), 20, 40); g.drawString("blue ball: " + randomNumber() + ", " + randomNumber(), 20, 60); g.drawString("green ball: " + randomNumber() + ", " + randomNumber(), 20, 80); g.drawString("magenta ball: " + randomNumber() + ", " + randomNumber(), 20, 100); g.setColor(Color.black); g.fillOval(xpos - radius, ypos - radius, 2 * radius, 2 * radius); for(i = 0; ilessthanNUM_OF_BALLS; i++) { ball[i].paint(g); try { Thread.sleep(5000); }catch(InterruptedException e){} } }}[/source]
this completely stops my whole program for running but every 5 seconds a new ball will pop up on the screen. Kinda what wanted but im not sure what i did to make the whole program stop lol
#66 Members - Reputation: 507
Posted 11 August 2012 - 07:42 PM
Alright, a couple of things:
1. Right now you're generating a new random number every time you do one of those drawString statements. That is just like it sounds like, a random number with no particular meaning or relation to anything. It's random. It looks like you're wanting to treat those statements like debugging kind of statements that tell you where each ball actually is. For that information, you'd want to look at the variables the ball has (like ball[0].x, ball[0].y, etc).
2. The reason your whole program "stops" for 5 seconds is you tell this program's thread to sleep for 5 seconds (Thread.sleep(5000). So for 5 seconds this thread isn't responding or updating or drawing or anything. What you want probably isn't to do NOTHING for 5 seconds.. just that you have something you DO want to happen every 5 seconds. For help on that, I think you'll need to post all of your code, as this will be a time where I need to take in what you're doing on the various threads and to try to see what you might be doing that you don't mean to be doing on the various threads.
#67 Members - Reputation: 235
Posted 11 August 2012 - 07:47 PM
the updateBalls thread is obviously wrong but ive been messing around with a few things in order to figure out what id have to change
[source lang="java"]public class game extends Applet implements Runnable{ int xpos = 100; int ypos = 100; int radius = 5; int xspeed = 0; int yspeed = 0; static final int WIDTH = 450; static final int HEIGHT = 450; private Image dbImage; private Graphics dbg; boolean run = true; public Ball ball[]; static final int NUM_OF_BALLS = 4; int i; int t; Thread updateTime = new updateTime(); public void start() { Thread th = new Thread(this); th.start();//start main game updateTime.start(); } public class updateTime extends Thread implements Runnable { public void run() { for(t = 0; t < 10; t++) { try { Thread.sleep(1000); } catch(InterruptedException e){} } } } public int randomNumber() { return (int)(Math.random() * 400); } class Ball { int x; int y; int width; int height; Color mycolor; public Ball(int x, int y, int width, int height, Color mycolor) { this.x = x; this.y = y; this.width = width; this.height = height; this.mycolor = mycolor; }//end ball public void paint(Graphics g) { g.setColor(mycolor); 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 class updateBalls extends Thread implements Runnable { public void run(Graphics g) { for(i = 0; i<NUM_OF_BALLS; i++) { ball[i].paint(g); } try { Thread.sleep(5000); }catch(InterruptedException e){} } }*/ public void init() { this.setSize(WIDTH, HEIGHT); ball = new Ball[NUM_OF_BALLS]; ball[0] = new Ball(randomNumber(), randomNumber(), 20, 20, Color.red); ball[1] = new Ball(randomNumber(), randomNumber(), 20, 20, Color.blue); ball[2] = new Ball(randomNumber(), randomNumber(), 20, 20, Color.green); ball[3] = new Ball(randomNumber(), randomNumber(), 20, 20, Color.magenta); } public boolean keyDown (Event e, int key) { if(key == Event.LEFT) { xspeed = -5; yspeed = 0; } if(key == Event.RIGHT) { xspeed = 5; yspeed = 0; } if(key == Event.UP) { yspeed = -5; xspeed = 0; } if(key == Event.DOWN) { yspeed = 5; xspeed = 0; } return true; } public void run() { while(run) { repaint(); if (xpos < 1) { xpos = 449; } if (xpos > 449) { xpos = 1; } if (ypos < 1) { ypos = 449; } if (ypos > 449) { ypos = 1; } ypos += yspeed; xpos += xspeed; try { Thread.sleep(20); } catch(InterruptedException ex){} } } public void paint(Graphics g) { g.drawString("time: " + t, 20, 20); g.drawString("Red ball: " + randomNumber() + ", " + randomNumber(), 20, 40); g.drawString("blue ball: " + randomNumber() + ", " + randomNumber(), 20, 60); g.drawString("green ball: " + randomNumber() + ", " + randomNumber(), 20, 80); g.drawString("magenta ball: " + randomNumber() + ", " + randomNumber(), 20, 100); g.setColor(Color.black); g.fillOval(xpos - radius, ypos - radius, 2 * radius, 2 * radius); for(i = 0; ilessthanNUM_OF_BALLS; i++) { ball[i].paint(g); } }}[/source]
Edited by burnt_casadilla, 11 August 2012 - 07:56 PM.
#68 Members - Reputation: 507
Posted 11 August 2012 - 08:35 PM
I'll also write a more lengthy post about a good to do what you want to w/o threads.. it'll be an hour or so though probably before I can do that.
#70 Members - Reputation: 507
Posted 11 August 2012 - 11:06 PM
[source lang="java"]import java.applet.Applet;import java.awt.*;import java.awt.geom.Ellipse2D;import java.util.ArrayList;import java.util.concurrent.TimeUnit;public class GameWithTime extends Applet implements Runnable{ //Sets NEW_DOT_FREQUENCY as 3 seconds private static long NEW_DOT_FREQUENCY = TimeUnit.SECONDS.toMillis(3); private static final int SCREEN_WIDTH = 400; private static final int SCREEN_HEIGHT = 400; //Stores what the time was when updateGame last ran private long lastUpdateTime = 0; //Tracks how much time has passed since the last new dot was added private long timeSinceLastNewDot = 0; //List of all the enemy dots private ArrayList<Dot> enemyDots; private Thread animator; private boolean isRunning; //Initialize things for the game public void init() { debugPrint("Initializing values."); //Put 4 dots in the list initially enemyDots = new ArrayList<Dot>(); enemyDots.add(new Dot(randomValue(), randomValue(), 10, 10)); enemyDots.add(new Dot(randomValue(), randomValue(), 10, 20)); enemyDots.add(new Dot(randomValue(), randomValue(), 20, 10)); enemyDots.add(new Dot(randomValue(), randomValue(), 20, 20)); } public void start() { lastUpdateTime = System.currentTimeMillis(); isRunning = true; animator = new Thread(this); animator.start(); } public void stop() { isRunning = false; } //Applet is closing, clean up public void destroy() { } public void run() { while (isRunning) { repaint(); try { Thread.sleep(15); } catch (InterruptedException e) { } } } //This update and paint approach is an alternative to double buffering to avoid flickering public void update(Graphics g) { //Update variables updateGame(); //Draw things to the screen //Clear the screen g.setColor(Color.BLACK); g.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); g.setColor(Color.cyan); //Draw each dot in the list for (Dot dot : enemyDots) { dot.draw(g); } } //This update and paint approach is an alternative to double buffering to avoid flickering public void paint(Graphics g) { update(g); } private 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; //Process inputs updateVariablesBasedOnUserInput(); //Create a new dot if enough time has passed //Update the time since last new dot was drawn timeSinceLastNewDot += elapsedTime; //See if enough time has passed to create a new dot debugPrint(Long.toString(timeSinceLastNewDot)); if (timeSinceLastNewDot >= NEW_DOT_FREQUENCY) { //Generate random x and y values for new dot int newX = randomValue(); int newY = randomValue(); //Add a new dot to the collection of dots debugPrint("New dot created at x:" + newX + ", y:" + newY + "."); enemyDots.add(new Dot(newX, newY, 20, 20)); //Reset time since a new dot was created timeSinceLastNewDot = 0; } } private void updateVariablesBasedOnUserInput() { //Set speeds/velocities based on user inputs } //Returns a new random value each time a call is made private int randomValue() { return (int) (Math.random() * 400); } //Prints passed value to the console private void debugPrint(String value) { System.out.println(value); } private class Dot extends Ellipse2D.Float { public Dot(int xValue, int yValue, int width, int height) { this.x = xValue; this.y = yValue; this.width = width; this.height = height; } public void draw(Graphics graphics) { graphics.drawOval((int) x, (int) y, (int) width, (int) height); } }}[/source]
Edited by j-locke, 11 August 2012 - 11:18 PM.
#71 Members - Reputation: 235
Posted 12 August 2012 - 11:07 AM
oh and i like the array list. good thinking cuz im gonna want even more dots when its finished. my ultimate goal is to create dots every 5 seconds and keep creating them until the main dot comes in contact with one and then its game over
Edited by burnt_casadilla, 12 August 2012 - 11:10 AM.
#72 Members - Reputation: 235
Posted 12 August 2012 - 11:40 AM
[source lang="java"] public void update(Graphics g) { updateGame(); g.setColor(Color.BLACK); g.fillRect(0, 0, WIDTH, HEIGHT); g.setColor(Color.cyan); for (ball ball : ball) { ball.paint(g); } } [/source]
im getting an error that says "can only iterate over an instance of an array" and i have no idea what that means lol
#73 Members - Reputation: 507
Posted 12 August 2012 - 12:18 PM
How that line is supposed to read is for (<datatype> <variable-name> : <collection-object>).
So with you saying ball 3 times, I'm not sure what you intended to put there. With the usual Java naming convention, you should name your classes (which are data types that created by you) with a capital letter (which you had done last time I checked, except where you named the game class lowercase).
So maybe you meant for (Ball ball : balls). Since an array represents a collection of things (usually more than 1), I find it useful to name the collection as plural.
Directly to your error, it sounds like your array is not named ball so the third 'ball' in your statement should be changed to match the array's name.
#74 Members - Reputation: 507
Posted 12 August 2012 - 12:31 PM
After a break from programming for 8 hours straight and a good nights sleep, this finally makes sense to me. thank you
oh and i like the array list. good thinking cuz im gonna want even more dots when its finished. my ultimate goal is to create dots every 5 seconds and keep creating them until the main dot comes in contact with one and then its game over
You're welcome. Glad I could provide some help. And getting your eyes off the code can be the best approach to understanding sometimes!
Good to know what your game is actually about now. For the collision, ball.getBounds() and/or ball.getBounds2D() could probably prove helpful.
.getBounds() documentation: http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/geom/RectangularShape.html#getBounds()
.getBounds2D() documentation: http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/geom/Ellipse2D.Float.html#getBounds2D()
#78 Members - Reputation: 507
Posted 12 August 2012 - 02:07 PM
ArrayList's .get() documentation: http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html#get(int)
#79 Members - Reputation: 235
Posted 12 August 2012 - 02:11 PM
[source lang="java"]import java.applet.Applet;import java.awt.Color;import java.awt.Event;import java.awt.Graphics;import java.awt.Image;import java.util.ArrayList;import java.util.concurrent.TimeUnit;public class game extends Applet implements Runnable{ int xpos = 100; int ypos = 100; int radius = 5; int xspeed = 0; int yspeed = 0; static final int WIDTH = 450; static final int HEIGHT = 450; private Image dbImage; private Graphics dbg; boolean run = true; public static long NEW_DOT_FREQ = TimeUnit.SECONDS.toMillis(5); public long lastUpdateTime; public long timeSinceLastNewDot; public ArrayList<Ball> Balls; static final int NUM_OF_BALLS = 4; int i; int t; 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, Color.black)); 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); } class Ball { int x; int y; int width; int height; Color mycolor; public Ball(int x, int y, int width, int height, Color mycolor) { this.x = x; this.y = y; this.width = width; this.height = height; this.mycolor = mycolor; }//end ball public void paint(Graphics g) { g.setColor(mycolor); 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 class updateBalls extends Thread implements Runnable { public void run(Graphics g) { for(i = 0; i<NUM_OF_BALLS; i++) { ball[i].paint(g); } try { Thread.sleep(5000); }catch(InterruptedException e){} } }*/ public void init() { this.setSize(WIDTH, HEIGHT); Balls = new ArrayList<Ball>(); Balls.add(new Ball(randomNumber(), randomNumber(), 20, 20, Color.red)); Balls.add(new Ball(randomNumber(), randomNumber(), 20, 20, Color.blue)); Balls.add(new Ball(randomNumber(), randomNumber(), 20, 20, Color.green)); Balls.add(new Ball(randomNumber(), randomNumber(), 20, 20, Color.magenta)); } public boolean keyDown (Event e, int key) { if(key == Event.LEFT) { xspeed = -5; yspeed = 0; } if(key == Event.RIGHT) { xspeed = 5; yspeed = 0; } if(key == Event.UP) { yspeed = -5; xspeed = 0; } if(key == Event.DOWN) { yspeed = 5; xspeed = 0; } return true; } public void run() { while(run) { repaint(); if (xpos < 1) { xpos = 449; } if (xpos > 449) { xpos = 1; } if (ypos < 1) { ypos = 449; } if (ypos > 449) { ypos = 1; } ypos += yspeed; xpos += xspeed; try { Thread.sleep(20); } catch(InterruptedException ex){} } } public void paint(Graphics g) { g.setColor(Color.black); g.fillOval(xpos - radius, ypos - radius, 2 * radius, 2 * radius); g.drawString("time: " + t, 20, 20); for (Ball dot : Balls) { dot.paint(g); } updateGame(); }}[/source]
next issue tho... collision. i read the link you posted but it didnt help too much. i understood it but i dont even know what to put into the method or how to get the bounds of each ball created. would i have to store each ball created in the array list as a shape? and if so how would i do that?
tweaked it so the balls look cooler
[source lang="java"] public void paint(Graphics g) { g.setColor(color[getRandomColor()]); g.fillOval(x, y, width, height); } [/source]
[source lang="java"] public int getRandomColor() { return (int)(Math.random() * 6); }[/source]
[source lang="java"] Color[] color = {Color.red, Color.blue, Color.green, Color.yellow, Color.magenta, Color.black}; int colorIndex; [/source]
oh lightbulb. since the coordinates of each ball are already stored in the array all id have to do is get the coords from the array and then somehow set the bounds within the getBounds() method
Edited by burnt_casadilla, 12 August 2012 - 02:44 PM.
#80 Members - Reputation: 507
Posted 12 August 2012 - 03:21 PM
[source lang="java"]//Returns a random number between 0 and maximum-1int randomNumber(int maximum){ return (int)(Math.random() * maximum);}[/source]
With that method, you could pass it WIDTH for a yvalue, HEIGHT for an xvalue and 6 (or more cleverly, color.length) for your color stuff.
next issue tho... collision. i read the link you posted but it didnt help too much. i understood it but i dont even know what to put into the method or how to get the bounds of each ball created. would i have to store each ball created in the array list as a shape? and if so how would i do that?
To your question about needing to create an array list of shapes, you already have one. Through inheritance (one of the core ideas to learn from classes/ object-oriented programming), your Ball class is a shape. The Ellipse2D documentation shows what classes it extends and interfaces it implements, and Shape is among them.
Your lightbulb is definitely on the right track. The information is already there; each ball knows information like its x, y coordinates, width and height. The getBounds() method actually already does some of that work for you. Following through the documentation for getBounds, it shows you the return type of the method is Rectangle. Rectangle has an x, y, width and height, so it knows where it's located and it even includes an intersects method to see if one Rectangle intersects with another Rectangle.
A thought process for what you're trying to accomplish is that every update, you want to get the Rectangle that represents the player's location. And see if that one Rectangle intersects with any of the enemy Rectangles.






