class Weapon
{
private ArrayList<Shot> magazine;
private int maxShots;
private double rotationAngle = 90;
private double rotationSpeed = 1.5;
public Weapon(int maxShots)
{
this.maxShots = maxShots;
magazine = new ArrayList<Shot>(maxShots);
}
public void rotate(int direction)
{
// no need to create hashamp etc to hold "left" or "right"
// when passing keyPressed, KeyeEvent.getKeyCode is enough.
// i see alot of people having separate if statements,
// why, i dont know when you can only go in one
// direction at a time!
// also of note, most people wrongly assume that
// either left or right will be passed, hence, if/else
// statements. use "if/else if" to guarantee only
// left or right
if (direction == KeyEvent.VK_LEFT)
{
angle-=speed;
}
else if (direction == KeyEvent.VK_RIGHT)
{
angle+=speed;
}
}
public void draw(Graphics2D g2, Dimension boundary)
{
// do NOT check if shot is out of bounds here,
// the only thing that should be done in draw,
// is draw!
}
public Iterator<Shot> getMagazine()
{
// by returning the iterator, you guarantee
// concurrency i.e preventing concurrent modifications
// to data, for example, drawing shots, moving shots
// and removing them
return magazine.iterator();
}
public void shoot()
{
double radian = Math.toRadians(-angle); // invert angle
double x = [center x] + ([length of weapon] * Math.cos(radian))-[your shot diameter];
double y = [center y] + ([length of weapon] * Math.sin(radian))-[your shot diameter];
if (magazine.size() < capacity)
{
magazine.add(new Shot(x,y,radian));
}
}
}
class Shot extends Ellipse2D.Double
{
Point2D.Double point;
Point2D.Double velocity;
double shotSpeed = 10;
public Shot(Point2D.Double origin, double radian)
{
velocity = new Point2D.Double(Math.cos(radian)*shotSpeed,Math.sin(radian)*shotSpeed);
point = new Point2D.Double(origin.x+velocity.x,origin.y+velocity.y);
setFrame(point.x,point.y,[shot diameter],[shot diameter]);
}
public void draw(Graphics2D g2)
{
g2.setColor(Color.pink);
g2.fill(this);
}
public void move()
{
point.x+=velocity.x;
point.y+=velocity.y;
setFrame(point.x,point.y,[shot diameter],[shot diameter]);
}
}
// use javax.swing.Timer to update/paint instead is
// while(true) with a Thread.sleep. it allows for stopping and
// restarting without creating additional objects
public void actionPerformed(ActionEvent event)
{
// check for rotation......
// check for shots fired....
// iterator is faster than conditional loops
Iterator<Shot> iterator = weapon.getMagazine();
while(iterator.hasNext())
{
Shot shot = iterator.next();
// getBounds() is the bounds of your panel
// shot.getBounds() is an inherited method of
// Ellipse2D.Double
// use java.awt.geom.RectangleShape.contains(Rectangle) method
if (getBounds().contains(shot.getBounds()))
{
// if the shot is within the rectangle, move it
shot.move();
}
else
{
iterator.remove();
}
}
// collision detection etc...
repaint();
}