|
CSCI A201/A597 and I210
|
At some point before Saturday the bonus points questions will be posted here.
You will have a chance to work with them before the final, preparing for the final.
Let's start from the program we developed in class on Tuesday.
There's an applet where everything happens (Two.java):
import java.applet.Applet;
import java.awt.Graphics;
public class Two extends Applet {
int NUM_ALIENS = 10;
Alien aliens[] = new Alien[NUM_ALIENS];
public void init() {
for (int i = 0; i < NUM_ALIENS; i++) {
aliens[i] = new Alien(this);
}
}
public void paint(Graphics g) {
for (int i = 0; i < aliens.length; i++) {
aliens[i].move();
aliens[i].draw(g);
}
repaint(300);
}
}
The applet is using an abstraction (described in Alien.java):
import java.applet.Applet;
import java.awt.Graphics;
public class Alien {
Applet context;
int dX, dY;
int x, y, radius;
public Alien(Applet context) {
this.context = context;
double value = Math.random();
if (value < 0.33) { dX = -1; }
else if (value < 0.66) { dX = 0; }
else { dX = 1; }
if (value < 0.33) { dY = -1; }
else if (value < 0.66 && dX != 0) { dY = 0; }
else { dY = 1; }
radius = (int)(Math.random() * 20 + 10); // [10, 30]
x = (int)(Math.random() * (context.getWidth() - 2 * radius));
y = (int)(Math.random() * (context.getHeight() - 2 * radius));
// x and y are coordinates of top left corner
}
public void draw(Graphics g) {
g.drawOval(x, y, 2 * radius, 2 * radius);
}
public void move() {
if (dX < 0) {
x -= 3;
} else if (dX > 0) {
x += 3;
}
if (dY < 0) {
y -= 3;
} else if (dY > 0) {
y += 3;
}
if (x > context.getWidth() - 2 * radius) {
x = context.getWidth() - 2 * radius;
dX = -1;
} else if (x < 0) {
x = 0; dX = 1;
}
if (y > context.getHeight() - 2 * radius) {
y = context.getHeight() - 2 * radius;
dY = -1;
} else if (y < 0) {
y = 0; dY = 1;
}
}
}
Let's add a turet (Turet.java) to prepare for alien shooting.
import java.applet.Applet;
import java.awt.Graphics;
public class Turet {
int x, y, w, h;
Applet context;
public Turet(Applet context) {
this.context = context;
w = 10;
h = 10;
x = (context.getWidth() - w) / 2;
y = context.getHeight() - 1;
}
public void draw(Graphics g) {
g.drawLine(x, y, x + w / 2, y - h);
g.drawLine(x + w / 2, y - h, x + w, y);
g.drawLine(x + w, y, x, y);
}
public void moveTo(int x, int y) {
this.x = x - w / 2;
}
}
Then let's incorporate this into the applet.
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.event.*;
public class Two extends Applet implements MouseListener, MouseMotionListener {
int NUM_ALIENS = 10;
Alien aliens[] = new Alien[NUM_ALIENS];
Turet turet;
public void init() {
for (int i = 0; i < NUM_ALIENS; i++) {
aliens[i] = new Alien(this);
}
turet = new Turet(this);
addMouseMotionListener(this);
addMouseListener(this);
}
public void paint(Graphics g) {
for (int i = 0; i < aliens.length; i++) {
aliens[i].move();
aliens[i].draw(g);
}
turet.draw(g);
repaint(300);
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) { }
}
I leave it as an exercise for you to see the differences. Now we add everything else.
This process will be explained in class, but be aware it's tricky.
First we need a missile kind of object.
The turet must be able to control it being fired.
The applet must know of it, to show it.
The missile must be able to move.
If a contact occurs between the missile and any of the aliens both the alien and the missile disappear.
So here's how the missile might be designed:
import java.applet.*;
import java.awt.*;
public class Missile {
int x, y, radius = 2;
public Missile(int x, int y) {
this.x = x - radius;
this.y = y - radius;
}
public void draw(Graphics g) {
g.fillOval(x - radius, y - radius, 2 * radius, 2 * radius);
}
public void move() {
y -= 10;
}
}
Here now is the modified turet:
import java.applet.Applet;
import java.awt.Graphics;
public class Turet {
int x, y, w, h;
Two context;
public Turet(Two context) {
this.context = context;
w = 10;
h = 10;
x = (context.getWidth() - w) / 2;
y = context.getHeight() - 1;
}
public void draw(Graphics g) {
g.drawLine(x, y, x + w / 2, y - h);
g.drawLine(x + w / 2, y - h, x + w, y);
g.drawLine(x + w, y, x, y);
}
public void moveTo(int x, int y) {
this.x = x - w / 2;
}
public void shoot() {
if ((context.missile) == null) {
context.missile = new Missile(x + w / 2, y - h);
System.out.println(((context.missile) == null));
}
}
}
Again, it is very instructive to check the differences. Here's the applet with knowledge of missile(s):
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.event.*;
public class Two extends Applet implements MouseListener, MouseMotionListener {
int NUM_ALIENS = 10;
Alien aliens[] = new Alien[NUM_ALIENS];
Turet turet;
public void init() {
for (int i = 0; i < NUM_ALIENS; i++) {
aliens[i] = new Alien(this);
}
turet = new Turet(this);
addMouseMotionListener(this);
addMouseListener(this);
}
public void paint(Graphics g) {
for (int i = 0; i < aliens.length; i++) {
if (aliens[i] != null) {
aliens[i].move();
aliens[i].draw(g);
}
}
turet.draw(g);
if (missile != null) {
missile.move();
missile.draw(g);
}
detectCollisions();
repaint(300);
}
public Missile missile = null;
public void detectCollisions() {
for (int i = 0; i < aliens.length; i++) {
if (missile != null && missile.y < 0) {
missile = null;
break;
}
if (aliens[i] != null && missile != null) {
if (aliens[i].contains(missile)) {
missile = null;
aliens[i] = null;
}
}
}
}
public void mouseClicked(MouseEvent e) {
turet.shoot();
}
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
int x = e.getX(), y = e.getY();
turet.moveTo(x, y);
}
public void mouseDragged(MouseEvent e) { }
}
And one can see the alien class itself needs to be modified.
import java.applet.Applet;
import java.awt.Graphics;
public class Alien {
Applet context;
int dX, dY;
int x, y, radius;
public Alien(Applet context) {
this.context = context;
double value = Math.random();
if (value < 0.33) { dX = -1; }
else if (value < 0.66) { dX = 0; }
else { dX = 1; }
if (value < 0.33) { dY = -1; }
else if (value < 0.66 && dX != 0) { dY = 0; }
else { dY = 1; }
radius = (int)(Math.random() * 20 + 10); // [10, 30]
x = (int)(Math.random() * (context.getWidth() - 2 * radius));
y = (int)(Math.random() * (context.getHeight() - 2 * radius));
// x and y are coordinates of top left corner
}
public void draw(Graphics g) {
g.drawOval(x, y, 2 * radius, 2 * radius);
}
public void move() {
if (dX < 0) {
x -= 3;
} else if (dX > 0) {
x += 3;
}
if (dY < 0) {
y -= 3;
} else if (dY > 0) {
y += 3;
}
if (x > context.getWidth() - 2 * radius) {
x = context.getWidth() - 2 * radius;
dX = -1;
} else if (x < 0) {
x = 0; dX = 1;
}
if (y > context.getHeight() - 2 * radius) {
y = context.getHeight() - 2 * radius;
dY = -1;
} else if (y < 0) {
y = 0; dY = 1;
}
}
public boolean contains(Missile m) {
return (Math.sqrt((m.x - x - radius) * (m.x - x - radius) +
(m.y - y - radius) * (m.y - y - radius))
<= radius + 2 * m.radius);
}
}
So now you have the basic framework of the game.