Jump to content


An Array For Asteroids


  • Please log in to reply
6 replies to this topic

#1 timo0060

timo0060

    Newbie

  • Members
  • Pip
  • 9 posts

Posted 10 June 2011 - 08:17 PM

Hello everyone, can any one help me understand how to make an array that store up to 10 asteroids, have them move this way on the screen: <---------------, until they get past zero, then restart at say, 1200 (x-axis). I also would appreciate it if you could help me make it so when my lasers hit an asteroid, the asteroid resets to it's default position of 1200 (x-axis) and the player gains say 10 points. Any help would be most appreciated, and please explain what you do in as much detail as possible, so I can understand it.

#2 Scott

Scott

    Advanced Member

  • Members
  • PipPipPip
  • 40 posts
  • Gender:Male
  • Location:England

Posted 13 June 2011 - 11:11 AM

Since you've only asked about the array I'll assume you've done the main loop, player input, collision detection and whatever else. Although if you can do all that it seems strange that this would be a problem.

I think it'd be best to have an asteroid class and store 10 of them in an array. Something like this:
public class Asteroid{
public int x,y;
public Asteroid(int xIn, int yIn){x = xIn; y = yIn;}
public void move(){x--; if (x<0){x=1200;}}
}
The following creates an array of Asteroid objects 10 elements long.
Asteroid[] asteroids = new Asteroid[10];
If I remember correctly all unused elements will be null by default so when adding an asteroid you can find the first null element to make sure you don't replace one. You'll also need to make sure an element is not null before using it in collision detection.
boolean stop = false;
for (int i = 0; i < asteroids.length&&stop==false; i++){//loops 10 times or until stop is set to true
if (asteroids[i]==null){
asteroids[i] = new Asteroid(1200,500); stop = true;//creates a new asteroid with the coordinates of 1200,500. if y is not changed all asteroids will have a y value of 500
}
}
To reset it to 1200 just use
asteroids[a].x = 1200;//where a is the element number
I can only guess you'd have a variable to hold your score so you'd simply increase that when the collision detection finds a hit.

I think that about answers the question. If you need more information or more detail feel free to ask

#3 timo0060

timo0060

    Newbie

  • Members
  • Pip
  • 9 posts

Posted 13 June 2011 - 08:20 PM

Thank you for your help. I decided just to have individual variables for the asteroids... next level the enemy(TIE Fighters)will be using an array... if I figure it out, cause I'm still really confused about it. My teacher helped me with an array for lasers, I don't fully get what he's saying, but I understand it enough. I just need help having the lasers (which are on an array) and the asteroids (which are not) collide.... Here is my full code so far to help you understand what I mean. I need the laser to collide and the asteroid to add 10 points, then reset to 1200 on the x-axis. you'll need to replace the images with your own or circles.

/**
 * @(#)starbattles.java
 *
 * starbattles Applet application
 *
 * @author
 * @version 1.00 2011/6/8
 */

import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import javax.swing.*;

public class starbattles extends Applet implements ActionListener, KeyListener, MouseMotionListener, MouseListener{

	  Timer timer1;

	  // Position
	  int xposr = 150;
	  int yposr = 450;
	  int xpos;
	  int ypos;
	  int xposb1 = 0;
	  int xposb2 = 1000;
	  int xdirectionb = 1;
	  int xdirectionb2 = 1;
	  int xdirection = 1;
	  int xdirection2 = 1;
	  int xdirection3 = 1;
	  int xdirection4 = 1;
	  int xdirection5 = 1;
	  int xdirection6 = 1;
	  int xdirection7 = 1;
	  int ydirection = 1;
	  int asx = 1200;
	  int asy = 300;
	  int asx2 = 1200;
	  int asy2 = -20;
	  int asx3 = 1200;
	  int asy3 = 700;
	  int asx4 = 1200;
	  int asy4 = 250;
	  int asx5 = 1200;
	  int asy5 = 150;
	  int asx6 = 1200;
	  int asy6 = 400;
	  int asx7 = 1200;
	  int asy7 = 600;
	  int rx;
	  int rx2;
	  int rx3;
	  int rx5;
	  int rx4;
	   int rx6;
	  int rx7;
	  int health = 10;
	  int numlas = 0;
	  int points = 0;
	  // Key value
	  int[] laserx = new int [1000];
	  int[] lasery = new int [1000];
	  int[] alive = new int [1000];
	  int i;



	  String end = "";
	  String HEALTH = "";
	  String POINT = "";


	  Image rocket;
	  Graphics backg;
	  Image backbuffer;
	  Image starfield;
	  Image asteroid;
	  Image xwingshot;




public void init() {
	   setSize(1000,800);
	   addKeyListener( this );
	   timer1 = new Timer(20, this);
		addMouseMotionListener(this);
		addMouseListener(this);
	   rocket = getImage(getDocumentBase(), "rocket.png");
	   starfield = getImage(getDocumentBase(), "Starfield.png");
	   asteroid = getImage(getDocumentBase(), "asteroid.png");
	   xwingshot = getImage(getDocumentBase(), "X-Wing Shot.png");

	  backbuffer = createImage( 1000, 800 );
	  backg = backbuffer.getGraphics();
	  backg.setColor( Color.black );
	  backg.fillRect( 0, 0, 1000, 800 );

   Toolkit toolkit = Toolkit.getDefaultToolkit();
   Image image = toolkit.getImage("pencil.gif");
   Point hotSpot = new Point(0,0);
   Cursor cursor = toolkit.createCustomCursor(image, hotSpot, "rocket.png");
   setCursor(cursor);

   }

	public void start(){
		timer1.start();
	}

	public void stop(){
		timer1.stop();
	}

	public void destroy(){
		//System.exit(0);
	}

	 public void mouseClicked (MouseEvent e) {
 //	xpos = e.getX();
 //	ypos = e.getY();
 //	repaint();

 	}
 public void mouseEntered (MouseEvent e) {

 	}
 public void mousePressed (MouseEvent e) {

	xpos = e.getX();
 	ypos = e.getY();
numlas = numlas +1;
laserx[numlas]=xpos;
lasery[numlas]=ypos - 40;
System.out.println("numlas " + numlas);
 //	for (i=0; i<=999; i++)
 //	{
 //		alive[i] = 1;
 //	}

 	repaint();
 	}
 public void mouseReleased (MouseEvent e) {}

 public void mouseExited (MouseEvent e) {}

	 public void keyPressed( KeyEvent ke ) {

	 }

  public void keyReleased( KeyEvent e ) {

  }

  public void keyTyped( KeyEvent e ) {
   }

	public void update( Graphics g ) {
	g.drawImage( backbuffer, 0, 0, this );
	}

	public void paint(Graphics g) {
	update( g );
   // System.out.println("XPOS = " + xposr);


	}

		public void actionPerformed(ActionEvent e){

	backg.drawImage(starfield,xposb1,0,1000,800, this);
	backg.drawImage(starfield,xposb2,0,1000,800, this);

	repaint();

	if(e.getSource() == timer1){

	if (health > 0)
	{backg.drawImage(rocket,xposr,yposr,70,60, this);
	backg.drawImage(asteroid,asx,asy,120,120, this);
	backg.drawImage(asteroid,asx7,asy7,120,120, this);
	backg.drawImage(asteroid,asx6,asy6,120,120, this);
	backg.drawImage(asteroid,asx5,asy5,120,120, this);
	backg.drawImage(asteroid,asx4,asy4,120,120, this);
	backg.drawImage(asteroid,asx3,asy3,120,120, this);
	backg.drawImage(asteroid,asx2,asy2,120,120, this);



//move the laser
for (i=1;i<=numlas; i++)
{   if (laserx[i]<= 1200)
{	laserx[i]=laserx[i]+15;
	backg.drawImage(xwingshot,laserx[i],lasery[i], 100,125, this);
}
}

		  asx = asx + xdirection * 8;   //move 10 pixels
		  asx2 = asx2 + xdirection2 * 6;
		  asx3 = asx3 + xdirection3 * 10;
		  asx4 = asx4 + xdirection4 * 9;
		  asx5 = asx5 + xdirection5 * 11;
		  asx6 = asx6 + xdirection6 * 13;
		  asx7 = asx7 + xdirection7 * 15;
		  xposb1 = xposb1 - xdirectionb * 2;
		  xposb2 = xposb2 - xdirectionb2 * 2;


		  HEALTH = "Health: "+health;
	 	backg.setColor( Color.red );
	  backg.setFont(new Font("Ariel", Font.ITALIC, 25));
	  backg.drawString( HEALTH, 20, 50 );

	  POINT = "Score: "+points;
	 	backg.setColor( Color.red );
	  backg.setFont(new Font("Ariel", Font.ITALIC, 25));
	  backg.drawString( POINT, 800, 50 );


		  if(xposb1 < -1000)
		  {
		  	xposb1 = 1000;
		  }

		  if(xposb2 <= -1000)
		  {
		  	xposb2 = 1000;
		  }

		  if (asx > 0)
		  {
		  	xdirection= -1;
		  }

		  if(asx < -100)
		  {
		  	asx = 1200;
		  }

		  if (asx2 > 0)
		  {
		  	xdirection2= -1;
		  }

		  if(asx2 < -100)
		  {
		  	asx2 = 1200;
		  }

		  if (asx3 > 0)
		  {
		  	xdirection3= -1;
		  }

		  if(asx3 < -100)
		  {
		  	asx3 = 1200;
		  }

		  if (asx4 > 0)
		  {
		  	xdirection4= -1;
		  }

		  if(asx4 < -100)
		  {
		  	asx4 = 1200;
		  }

		  if (asx5 > 0)
		  {
		  	xdirection5= -1;
		  }

		  if(asx5 < -100)
		  {
		  	asx5 = 1200;
		  }

		  if (asx6 > 0)
		  {
		  	xdirection6= -1;
		  }

		  if(asx6 < -100)
		  {
		  	asx6 = 1200;
		  }

		  if (asx7 > 0)
		  {
		  	xdirection7= -1;
		  }

		  if(asx7 < -100)
		  {
		  	asx7 = 1200;
		  }

		  repaint();

		  if ((xposr + 50) >= asx2  && (xposr +70) <= (asx2 + 160) && yposr >= asy2 && (yposr + 60) <= (asy2 + 150))
		  {
		  	health --;
		  	asx2 = 1200;
		  }

		  if ((laserx[i] + 100) >= asx2 && (laserx[i] + 100) <= (asx2 + 125) && lasery[i] >= asy2 && (lasery[i] + 125) <= (asy2 + 150) )
		  {
		  	asx2 = 1200;
		  	points = points + 10;

		  }


	}

	 if (health == 0)
	 {
	 	end = "Game over, You Rebel Scum";
	 	backg.setColor( Color.red );
	  backg.setFont(new Font("Ariel", Font.PLAIN, 45));
	  backg.drawString( end, 230, 350 );
	 }

	}







		}


			 public void mouseMoved(MouseEvent e)
	 {
		  xpos = e.getX();
		  ypos = e.getY();


   if (xpos > 0)
   {
   xposr = xpos;
   }

   if (xpos < 300 )
   {
   	xposr = xpos;
   }

   if (xpos > 920)
   {
   	xposr = 920;
   }

   if (ypos > -50)
   {
   	yposr = ypos;
   }

   if (ypos < 800)
   {
   	yposr = ypos;
   }

   if (ypos > 800)
   {
   	yposr = 800;
   }


	 repaint();




	 }


	public void mouseDragged(MouseEvent e)
	 {

	 	xpos = e.getX();
		  ypos = e.getY();


   if (xpos > 0)
   {
   xposr = xpos;
   }

   if (xpos < 300 )
   {
   	xposr = xpos;
   }

   if (xpos > 920)
   {
   	xposr = 920;
   }

   if (ypos > -50)
   {
   	yposr = ypos;
   }

   if (ypos < 800)
   {
   	yposr = ypos;
   }

   if (ypos > 800)
   {
   	yposr = 800;
   }


	 repaint();

	 }

}


P.S. Thank you so much.

#4 Scott

Scott

    Advanced Member

  • Members
  • PipPipPip
  • 40 posts
  • Gender:Male
  • Location:England

Posted 13 June 2011 - 11:16 PM

Hmm. TIE Fighters. I like the sound of that  :biggrin:  

Arrays and loops (for loops are my favourite) are really helpful so I'll try to tell you all I know about arrays.

An array is a list of whatever data type you choose. In the case of your lasers Integers, but you can store anything in an array. The elements of the array are placed in memory one after the other and because they are all the same type they are all the same size so it's easy to know where each one will start.
Arrays are declared like any other variable except they have square brackets to show it's an array.
int[] laserx;
The above just states that the array exists, at this point the data is unknown (null) the same as any object.

laserx = new int[1000];
This actually creates the array and makes room for 1000 Integers. If I remember correctly they are set to 0 by default.
The data in an array is accessed by using the array name like any other variable with the element number following in square brackets like so:
laserx[0] = 5;//set the first element to 5
if (laserx[1]==2){}//check to see if the second element is equal to 2
Elements in an array are numbered starting from 0 so your array of 1000 Integers goes from 0 to 999. Arrays have a length value accessed like with any other object.

Combined with a loop you can make a lot of changes with very little code.
for (int i = 0; i < laserx.length; i++){laserx[i] = 1200;}
This code changes the x value of every laser to 1200 and would work the same whether you had 1 or 1000 elements in your array.


OK. Hopefully you'll understand some of that. I'm no teacher but you'll get it sooner or later, after all even I learnt eventually.
I highly recomend an array for asteroids. Either an array of objects like I suggested or a couple of arrays of ints like the lasers. If you don't use an array you'll have to write the code to check every asteroid instead of letting a loop do it for you. It's up to you.

So collision detection. A constant nightmare for me. But I've done this before, 2d is really easy.

It looks like your lasers have dimensions of 100x125 and your asteroids have dimensions of 120x120. So anything 50 pixels to either side of the laser will be hit by it and anything 60 pixels to either side of an asteroid would hit it so if a laser is within 110 pixels to either side of an asteroid they will collide. Same idea for the y axis which I think works out at about 122.5 but since you're using ints ignore the point.
Every time you update your game and move the lasers and asteroids you need to check for collisions between each asteroid and each laser. If you leave it as it is the following should work:
for (int i = 0; i < laserx.length; i++){//loop through all lasers. maybe numlas or something would work better here
if ((asx>laserx[i]-110)&&(asx<laserx[i]+110)&&(asy>lasery[i]-122)&&(asy<lasery[i]+122)){//check to see if the x position of the asteroid is within 110 pixels of each side of the laser. repeat for y. if both are true then the laser hit the asteroid
asx = 1200;//set the asteroids position back to 1200
points+=10;//increase the score by 10
}
//repeat if statement for each asteroid
}

A word of caution with this collision detection. Make sure you don't have things moving so fast that they could pass through eachother between collision checks.

I hope this is some help  :happy:
Again if you need more information or (heaven forbid) more detail feel free to ask

#5 timo0060

timo0060

    Newbie

  • Members
  • Pip
  • 9 posts

Posted 14 June 2011 - 12:25 AM

That last part made me laugh :D And thanks for the help, I'm slowly getting it. Basically I had it correct originally, but I didn't have the
for (int i = 0; i < laserx.length; i++) 
Which is probably what I needed, because everytime I shot an asteroid nothing would happen, but once it got close enough to the edge of the screen, it you disappear and give me 10 points. So thanks for your help, I hope this will work.

P.S. It seems like you're the only one on this forum... not a lot of programmers out there I guess.

#6 timo0060

timo0060

    Newbie

  • Members
  • Pip
  • 9 posts

Posted 14 June 2011 - 07:38 PM

The collision code you gave me works great, but now I've run into an error. Once I hit it, it adds 10 points and goes back to 1200, but the laser keeps going and some how it turns into an infinite loop of adding +10 to my score. How exactly would I "kill" a laser and reset it's value back to before it was even shot?

#7 Scott

Scott

    Advanced Member

  • Members
  • PipPipPip
  • 40 posts
  • Gender:Male
  • Location:England

Posted 14 June 2011 - 11:13 PM

It's not the way I would do it but working with what you have I think that is the purpose of the alive array.

You have a loop to set all elements of alive to 1 commented out in your code for adding a laser. Instead of looping through them all it should only activate the laser that was just fired.
alive[numlas] = 1;
You'll need to update the laser movement, collision detection and display so they only apply to lasers that have alive==1.
Also when a laser hits an asteroid you need to set the matching element of alive to 0 so it will disappear. You should set alive to 0 if one reaches 1200 too so you don't waste time updating the position and checking collisions of lasers that are off the screen.

Currently your lasers do not reset so when you try to fire your 1001st laser your program will crash with an array element out of bounds exception. I guess that would take some time to happen but it can be fixed easily by setting numlas to 0 when it reaches 1000.