зеркало из https://github.com/mozilla/pluotsorbet.git
236 строки
6.7 KiB
Java
236 строки
6.7 KiB
Java
/**
|
|
* Copyright 2001 Jean-Francois Doue
|
|
*
|
|
* This file is part of Asteroid Zone. Asteroid Zone is free software;
|
|
* you can redistribute it and/or modify it under the terms of the
|
|
* GNU General Public License as published by the Free Software Foundation;
|
|
* either version 2 of the License, or (at your option) any later version.
|
|
* Asteroid Zone is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Asteroid Zone; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
* Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
package asteroids;
|
|
|
|
import javax.microedition.lcdui.*;
|
|
import java.util.*;
|
|
|
|
/**
|
|
* Class to implement the player's spaceship. The spaceship
|
|
* can rotate, move, shoot and teleport itself.
|
|
* @author Jean-Francois Doue
|
|
* @version 1.4, 2002/10/14
|
|
*/
|
|
public class Ship extends Mobile {
|
|
/**
|
|
* False if the ship has been shot.
|
|
*/
|
|
public boolean isAlive;
|
|
|
|
/**
|
|
* The orientation of the ship.
|
|
*/
|
|
public byte angle;
|
|
|
|
/**
|
|
* The X coordinates of an array of points representing the ship
|
|
* at various orientations.
|
|
*/
|
|
public static byte[] xcoords;
|
|
|
|
/**
|
|
* The Y coordinates of an array of points representing the ship
|
|
* at various orientations.
|
|
*/
|
|
public static byte[] ycoords;
|
|
|
|
/**
|
|
* The size of the ship (in pixels).
|
|
*/
|
|
public static byte radius;
|
|
|
|
/**
|
|
* The ship singleton
|
|
*/
|
|
public static Ship ship;
|
|
|
|
|
|
private byte _explosionFrame;
|
|
private byte _latency; // To limit the ship's firing power
|
|
|
|
static {
|
|
// Instantiate the ship.
|
|
ship = new Ship();
|
|
|
|
final byte[] pointx = {5,-3, 0,-3};
|
|
final byte[] pointy = {0, 4, 0,-4};
|
|
|
|
radius = (byte)(5 * ratioNum / ratioDenom);
|
|
xcoords = new byte[128];
|
|
ycoords = new byte[128];
|
|
for (int i = 0; i < 32; i++) {
|
|
int offset = i << 2;
|
|
for (int j = 0; j < 4; j++) {
|
|
xcoords[offset + j] = (byte)(((pointx[j] * cos[i] - pointy[j] * sin[i]) * ratioNum / ratioDenom) >> 6);
|
|
ycoords[offset + j] = (byte)(((pointx[j] * sin[i] + pointy[j] * cos[i]) * ratioNum / ratioDenom) >> 6);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Ship() {
|
|
}
|
|
|
|
/**
|
|
* Positions the ship at its original location, orientation
|
|
* and velocity.
|
|
*/
|
|
public final void reset() {
|
|
angle = 0;
|
|
moveTo(Mobile.width >> 1, Mobile.height >> 1);
|
|
vx = 0;
|
|
vy = 0;
|
|
isAlive = true;
|
|
rotate(0);
|
|
}
|
|
|
|
/**
|
|
* Called when the ship collides with an asteroid.
|
|
*/
|
|
public final void explode() {
|
|
isAlive = false;
|
|
_explosionFrame = 0;
|
|
}
|
|
|
|
/**
|
|
* Move the ship to its next position.
|
|
*/
|
|
public final void move() {
|
|
if (isAlive) {
|
|
xold = x;
|
|
yold = y;
|
|
_x += vx;
|
|
_y += vy;
|
|
x = _x >> 8;
|
|
y = _y >> 8;
|
|
|
|
// If a border has been hit, wrap the trajectory around
|
|
// the screen. The new origin is the projection of the
|
|
// intersection point on the opposite border.
|
|
if (x <= 0) {
|
|
moveTo(width - 2, y);
|
|
} else if (x >= width - 1) {
|
|
moveTo(1, y);
|
|
} else if (y <= 0) {
|
|
moveTo(x, height - 2);
|
|
} else if (y >= height - 1) {
|
|
moveTo(x, 1);
|
|
}
|
|
|
|
if (_latency > 0) {
|
|
_latency--;
|
|
}
|
|
} else {
|
|
_explosionFrame++;
|
|
if (_explosionFrame > 20) {
|
|
reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Changes the orientation of the ship.
|
|
*/
|
|
public final void rotate(int direction) {
|
|
if (isAlive) {
|
|
angle += direction;
|
|
if (angle > 31) {
|
|
angle -= 32;
|
|
} else if (angle < 0) {
|
|
angle += 32;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds velocity to the ship.
|
|
*/
|
|
public final void burn() {
|
|
if (isAlive) {
|
|
int newvx = vx + (cos[angle] << 1);
|
|
int newvy = vy + (sin[angle] << 1);
|
|
// clamp the ship velocity.
|
|
if (newvx * newvx + newvy * newvy < 262144) {
|
|
vx = newvx;
|
|
vy = newvy;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Shoots a rocket.
|
|
*/
|
|
public final Rocket shoot(Pool rockets) {
|
|
if (isAlive) {
|
|
if (_latency == 0) {
|
|
Rocket rocket = (Rocket)rockets.addNewObject();
|
|
if (rocket != null) {
|
|
int offset = angle << 2;
|
|
rocket.init(xcoords[offset] + x, ycoords[offset] + y, angle, vx, vy);
|
|
|
|
// Prevent the ship for shooting again for 3 frames
|
|
_latency = 3;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Teleports the ship to another lcoation.
|
|
*/
|
|
public final void teleport() {
|
|
if (isAlive) {
|
|
moveTo(Math.abs(Game.random.nextInt()) % width, Math.abs(Game.random.nextInt()) % height);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Draws the ship at the specified location and orientation.
|
|
*/
|
|
public static void draw(int orientation, int xpos, int ypos, Graphics g) {
|
|
int offset = orientation << 2;
|
|
g.drawLine(xcoords[offset] + xpos, ycoords[offset] + ypos,
|
|
xcoords[offset + 1] + xpos, ycoords[offset + 1] + ypos);
|
|
g.drawLine(xcoords[offset + 1] + xpos, ycoords[offset + 1] + ypos,
|
|
xcoords[offset + 2] + xpos, ycoords[offset + 2] + ypos);
|
|
g.drawLine(xcoords[offset + 2] + xpos, ycoords[offset + 2] + ypos,
|
|
xcoords[offset + 3] + xpos, ycoords[offset + 3] + ypos);
|
|
g.drawLine(xcoords[offset + 3] + xpos, ycoords[offset + 3] + ypos,
|
|
xcoords[offset + 0] + xpos, ycoords[offset + 0] + ypos);
|
|
}
|
|
|
|
/**
|
|
* Draws the ship in the specified graphic context.
|
|
*/
|
|
public final void draw(Graphics g) {
|
|
if (isAlive) {
|
|
draw(angle, x, y, g);
|
|
} else {
|
|
if (_explosionFrame < 6) {
|
|
g.setColor(255, 0, 0);
|
|
int radius = _explosionFrame;
|
|
g.drawArc(x - radius, y - radius, radius << 1, radius << 1, 0, 360);
|
|
radius = _explosionFrame + 2;
|
|
g.drawArc(x - radius, y - radius, radius << 1, radius << 1, 0, 360);
|
|
radius = _explosionFrame + 4;
|
|
g.drawArc(x - radius, y - radius, radius << 1, radius << 1, 0, 360);
|
|
}
|
|
}
|
|
}
|
|
}
|