Welcome Guest ( Log In | Register )

  

 
Closed TopicStart new topic
> Space Invaders
Mr. Sacevich
post Nov 18 2009, 10:06 AM
Post #1


Active
**

Group: Admin
Posts: 115
Joined: 08-25-09
Member No.: 12610



The next project we will be working on is Space Invaders. You will need to add several classes to your program to make it function properly.

1. A ship class: This will keep track of the player’s ship on screen. Very similar to our paddle class from Pong, the only difference is that instead of a rectangle, you may want to modify your class to draw an image of a ship on screen. To do that, you will have to add an image variable to your ship class (in addition to your standard x,y and speed variables). You should load the image of your ship in the constructor of your ship class (Remember: Your constructor initializes your ship, and constructor functions are always named public void SameNameAsTheClass(optional variables in here)).
2. An enemy class: Your enemies should keep track of their own x and y position on screen, as well as whether they are visible or not. You may also want to add speed variables to your enemy class, so that if you wanted each enemy to move at a different speed, you could set it up to do so. Your enemy class should also include a move function that moves your enemy around the screen, and a paint function that paints your enemy on the screen.
3. A bullet class: Your bullet class will represent the laser or bullets that your ship fires at the enemies coming in at it. Your bullet class should keep track of its x and y positions, as well as whether it is visible or not. It should also have a move function to move itself, and a paint function to paint itself. (I would suggest you make your bullets thin filled rectangles of whatever color you want to make it look like a laser).
4. A thread/timer class: Just like our other programs, we are going to need a thread to move all the stuff around our screen.

As I discussed in class, if you don’t know how to start a class from scratch, you can copy and paste similar classes we have used in other projects into your game and modify them (the pong paddle class or the car class from frogger are good starting points for classes 1,2 and 3). Also, you will have 1 ship in your game and 1 timer, eventually you will have arrays of both bullets and enemies.

Bullets: Once again, as we discussed in class, the procedure for firing a bullet is as follows: when the user presses whichever key you want to be your ‘fire’ key: loop through your bullet array and find the first bullet that is NOT visible (don’t forget you can break out of a loop with the “break” command), place it at the same x and y position as the one your ship is at (so it looks like its coming from the ship). Finally, in your timer class, you should loop through the bullets and move any bullet that IS visible (we don’t want to move invisible bullets) up.
Go to the top of the page
 
+Quote Post
Mr. Sacevich
post Nov 20 2009, 10:26 AM
Post #2


Active
**

Group: Admin
Posts: 115
Joined: 08-25-09
Member No.: 12610



Here is basic code to help you get started.

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

public class SpaceInvaders extends Applet implements KeyListener{
Timer mt = new Timer();
Enemy badguys[] = new Enemy[15];
Ship s1 = new Ship(100,300);
Bullet bulletz[] = new Bullet[5];

public void init()
{
addKeyListener(this);

//initialize each row of my enemy ships
for (int i=0; i<5;i++)
{
badguys[i] = new Enemy(i*11,10);
}
for (int i=5; i<10;i++)
{
badguys[i] = new Enemy((i-5)*11,30);
}
for (int i=10; i<15;i++)
{
badguys[i] = new Enemy((i-10)*11,50);
}
for (int i=0; i<5;i++)
{
bulletz[i]= new Bullet(-10,-10);
}
//start the move timer
mt.start();
}

public void keyPressed(KeyEvent e)
{
if (e.getKeyCode()==e.VK_LEFT)
{
s1.x=s1.x-10;
}
if (e.getKeyCode()==e.VK_RIGHT)
{
s1.x=s1.x+10;
}
if (e.getKeyCode()== e.VK_SPACE)
{
//fire a bullet
//find the first bullet that isn't visible, and make it visible
//note: our move timer moves all bullets that are VISIBLE
//so we just have to set visible to true
//for a higher mark, you will change this loop to a more efficient
//WHILE loop instead of the for loop
for (int i=0; i<5; i++)
{
if (bulletz[i].visible == false)
{
bulletz[i].x = s1.x;
bulletz[i].y=s1.y;
bulletz[i].visible = true;
repaint();
break;
//once we have found a bullet
//that we can use we can stop searching
}
}
}
repaint();
}

public void keyTyped(KeyEvent e)
{

}
public void keyReleased(KeyEvent e)
{

}
public void paint(Graphics g)
{
//paint all bad guys and bullets
//note: if you look inside the paint functions inside the
//enemy and bullet classes, you will see that they only paint
//on screen if the bullet is VISIBLE
for (int i = 0; i<15; i++)
{
badguys[i].paint(g);
}
for (int i=0; i<5; i++)
{
bulletz[i].paint(g);
}
s1.paint(g);
}

class Timer extends Thread
{
public void run()
{
while(true)
{
//move the bad guys and the bullets
//note: if you look inside the moveDown and
//moveUp functions inside the Enemy and Bullet
//classes respectively, you will see that only VISIBLE
//bullets and enemies are moved
for (int i =0;i<15; i++)
{
badguys[i].moveDown();
}

for (int i=0;i<5;i++)
{
bulletz[i].moveUp();
}
//collision will go here
//you will need a loop inside of a loop to do proper collision
//because you will need to loop through each bullet and check
//to see if it collided against each enemy
//remember, we don't want invisible enemies and bullets colliding




repaint();
try
{
sleep(500);
}
catch (Exception e)
{
System.out.println("thread error");
}
}

}
}//end of timer class

class Enemy
{
int x;
int y;
boolean visible = true;

public Enemy(int x, int y)
{
//Enemy Constructor - init for your enemy class
System.out.println("making an enemy");
this.x = x;
this.y = y;
}

public void moveDown()
{
y= y + 10;
}

public void paint(Graphics g)
{
if (visible =true)
{

g.fillOval(x,y,10,10);
}
}

}//end of enemy class

class Ship
{
int x;
int y;

public Ship(int x, int y)
{
//Ship Constructor - init for your ship class
System.out.println("making ship");
this.x = x;
this.y = y;
}


public void paint(Graphics g)
{

g.fillRect(x,y,40,40);

}

}//end of ship class

class Bullet
{
int x;
int y;
boolean visible = false;

public Bullet(int x, int y)
{
//Bullet Constructor - init for your bullet class
System.out.println("making a bullet");
this.x = x;
this.y = y;
}

public void moveUp()
{
if (visible == true)
{

y= y - 10;
}

if (y<0)
{
visible = false;
}
}

public void paint(Graphics g)
{
if (visible ==true)
{

g.fillRect(x,y,5,40);
}
}

}//end of bullet class
}
Go to the top of the page
 
+Quote Post
Mr. Sacevich
post Nov 20 2009, 10:27 AM
Post #3


Active
**

Group: Admin
Posts: 115
Joined: 08-25-09
Member No.: 12610



Collision for Space Invaders:

To check collision, you need to check if EACH bullet has hit EACH enemy ship. To accomplish this, you will need a loop inside of a loop, as follows:

for (int i=0;i<NUMBEROFBULLETS;i++) //loop through each bullet
{
for (int j=0;j<NUMBEROFENEMIES;j++) //loop through each enemy ship
{
//collision code will go here
//remember, you are checking bulletz[i] and shipz[j]
//if you mix up i and j, your game will compile but it
//will have unexpected results
}
}

For the actual collision code, take a look at your collision code for Pong or Breakout, with the variables representing the ball being replaced by the variables for your bullets, and the variables representing your paddles or bricks being replaced by variables for your enemy ships.
Go to the top of the page
 
+Quote Post
Mr. Sacevich
post Nov 20 2009, 10:27 AM
Post #4


Active
**

Group: Admin
Posts: 115
Joined: 08-25-09
Member No.: 12610



Here is some of the code we discussed in class to make your alien ships fire bullets (remember, you can either make a new array of bullets, or if you want the alien bullets to look differently from the player's bullets you would make a new class)

Note: As always a class is just a blue-print of an object you want to create, to make an object that you can actually use you will have to declare it at the top of your code with your variables (and start it in this case because it is a thread).

Either way, you will have to do the same steps you needed to create your regular bullets to create your alien bullets:
1. Declare your array at the top
2. initialize the array inside your init (I put the alien bullets off-screen at -50,-50 at first because they should all be INVISIBLE when you start the program
3. Add code to your paint to have the alien bullets that ARE visible paint on screen
4. Add code to your regular move Timer to move alien bullets that ARE visible

Finally, you will have to add collision code between your alien bullets and your player's ship, and make something happen when the bullets hit the ship (lose a life, lose health, lose shield, etc).

class ShootTimer extends Thread
{
public void run()
{
while(true)
{
System.out.println("Shoot!");
//pick a random number of bullets to fire
//remember, my code had an array of 5 alien bullets so I had
//to pick a random number between 0 and 4
//you may decide on more or less bullets for your game
int numBullets = (int)(Math.random()*4.0);
//we will use the whichAlien variable to pick a different
//alien ship to fire from each time
int whichAlien;

for (int i=0; i<numBullets; i++)
{
//loop from 0 to the number of bullets you chose
//to fire this time, and only fire alien bullets
//that are not currently in use
if (alienBullets[i].visible == false)
{
//need to pick a random alien ship to fire from
//make sure the alien ship is visible
//don't want invisible ships firing
if (badguys[whichAlien].visible == true)
{
//put the alien bullet on screen at the
//same x and y position of the alien ship
//that was picked, then make the bullet
//visible

}
}
}

repaint();
try
{
//can either sleep for a constant amount, or pick a
//random number so your game is less repetitive
sleep( );
}
catch (Exception e)
{
System.out.println("thread error");
}
}

}
}//end of timer class

As we discussed in class, there are still problems with using a for loop to loop through and find the available bullets and fire them because it is always looking at the first three bullets. The best way to accomplish this would be to use a while loop to replace the for loop.

int howmanylookedat = 0; //boolean that tells us if we are done looking
int count = 0; //how many bullets have we looked at

while ((howmanylookedat!=numBullets)||(count!=5))
//while we aren't done getting bullets, OR we haven't run out of
//bullets to look at keep looping
{
//our code to actually pick a bullet and put it by a ship would go in here
//remember to increment (add 1) to howmanylookedat and count, or you may end up
//with an infinite loop

}
Go to the top of the page
 
+Quote Post
Mr. Sacevich
post Nov 20 2009, 10:28 AM
Post #5


Active
**

Group: Admin
Posts: 115
Joined: 08-25-09
Member No.: 12610



Space Invaders for marking scheme:

The following is affects your mark on every project
Efficient Algorithms -An efficient algorithm executes rapidly, requires minimal storage and is simple to look at.

Program execution - Programs runs as described and expected, without generating syntax or logic errors.

Programming Style - The code is easily readable with indentation, proper use of structures, functions, and meaningful variable names.

Functionality – Does the program meet the basic functionality of the project? Additional/improved functionality will raise your mark. Your game should do the following:



For a C:
The game works similar to the example I have provided.
- You have used images instead of circles and squares in the game.
- You have a score
- The game ends (either if you win or you lose)

For a B:
The game has improved on the examples I have provided.
- all of the above
- there is a score on screen
- the player has x amount of lives
- the game ends BOTH if the player wins or loses


For an A:
The game has significantly improved on my example.
- all of the above
- multiple difficulty levels
- any other ideas that improve gameplay (e.g. a boss enemy once all the regular enemies are defeated, shields, power-ups: shields, extra life, improved firepower, etc.)
Go to the top of the page
 
+Quote Post
Mr. Sacevich
post Dec 8 2009, 10:08 AM
Post #6


Active
**

Group: Admin
Posts: 115
Joined: 08-25-09
Member No.: 12610



for (int i=0; i<5; i++) //loop through each bullet
{
for (int j=0; j<15; j++) //loop through each ship
{
if ((bulletz[i].y+bulletz[i].height)>=badguys[j].y)
{
//only checked if condition 1 is true
if ((bulletz[i].y)<=(badguys[j].y+badguys[j].height))
{
//only checked if condtion 1 and 2 are true
if (bulletz[i].x<=(badguys[j].x+badguys[j].width))
{
//only checked if the first 3 conditions are true
if ((bulletz[i].x + bulletz[i].width)>=badguys[j].x)
{
if ((bulletz[i].visible==true)&&(badguys[j].visible == true))
{

//if our program has gotten to here, that means
//all 4 conditions must be true
System.out.println("I think we hit an enemy ship" + j + " with bullet " + i);
bulletz[i].visible = false;
badguys[j].visible = false;
}
}
}
}
}
}
}
Go to the top of the page
 
+Quote Post

Closed TopicStart new topic

 



Lo-Fi Version Time is now: 9th February 2010 - 02:36 AM
Simple Cut Red Skin By Invision Styles & Omega Designz