ok, so i've been working on this project for a long time now, a falling sand game, on and off. it works almost the way i want it too... 2 problems, one i don't think this community will be able to help me with, the other, the optimization, i have higher hopes for.
the first one, less likely to have a solution is that heat doesn't spread right, at the moment i am averaging two heat values, the current and a neighboring pixel's, to get the new current heat, i believe this is done in the doHeat() method, but my code is sloppy and it has been a while since i did anything too it.
the second, is that it runs slowly, especially with a lot of stuff on the screen. there are a lot of loops, and i cannot think of a way to reduce the loop count, or could accessing arrayLists also be limiting the speed?
i apologize for the large size of this code, and the lack of useful comments. the entirety of the source is attached in a zip (including a main class, an class that adds to the array lists in this class, and a class that contains an editor for the physics of the sand), to find out more about the project my site has a page on it...
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.image.*;
import javax.swing.*;
/**
* Workings of Project.
* @author SciWizEH
* @version 3
/
public class SandEngine extends JPanel implements Runnable,
MouseListener, MouseMotionListener {
//check neighbor interactions?
boolean doNeighbor = true;
//calculate heat?
boolean doHeat = true;
//in bounds?
boolean inBounds = false;
//paused?
static boolean pause = false;
//width
static int pWIDTH;
//height
static int pHEIGHT;
//calculation thread
Thread runner;
//mouse position keepers
int mousex;
int mousey;
int mousex2;
int mousey2;
//image used to draw sand on
BufferedImage buffer = new BufferedImage(pWIDTH, pHEIGHT + 50,
BufferedImage.TYPE_INT_RGB);
//carrier variable
Graphics g;
//brush sice
int bsize = 4;
//random generators *some of which may be unused
Random generator = new Random();
Random generator2 = new Random();
Random generator3 = new Random();
Random generator4 = new Random();
Random generator5 = new Random();
//elemental data in 2D plane
int[][] pixelData = new int[pWIDTH + 1][pHEIGHT + 1];
//heat data in 2D plane
int[][] heatData = new int[pWIDTH + 1][pHEIGHT + 1];
//draw this 2D pixel?
boolean[][] drawData = new boolean[pWIDTH + 1][pHEIGHT + 1];
//check this 2D pixels neighbor
boolean[][] checkN = new boolean[pWIDTH + 1][pHEIGHT + 1];
//do this 2D pixels heat
boolean[][] checkH = new boolean[pWIDTH + 1][pHEIGHT + 1];
//is there a heat source on screen
boolean hSource = false;
//left 1
int leftD = 1;
//right 1
int rightD = -1;
//current element to draw
int eLEMENT = 1;
/names of elements.
*
*/
public static ArrayList < String > nameS = new ArrayList < String > ();
/colors of elements.
*
*/
public static ArrayList < Color > elements = new ArrayList < Color > ();
/slip of elements non zero slip
* denotates an element that will move only sideways./
public static ArrayList < Integer > slip = new ArrayList < Integer > ();
/gravity of elements.*/
public static ArrayList < Integer > gravity =
new ArrayList < Integer > ();
/density of elements.*/
public static ArrayList < Double > density = new ArrayList < Double > ();
/heat of elements > 100 heats things
* < 100 cools things otherwhise nothing.*/
public static ArrayList < Integer > heat = new ArrayList < Integer > ();
/first element of interaction.
*
*/
public static ArrayList < Integer > eLM1 = new ArrayList < Integer > ();
/second element of interaction.
*
*/
public static ArrayList < Integer > eLM2 = new ArrayList < Integer > ();
/possibility of happening.*/
public static ArrayList < Integer > cHANCE = new ArrayList < Integer > ();
/first new element of interaction.
*
*/
public static ArrayList < Integer > nELM1 = new ArrayList < Integer > ();
/**
* does this interaction explode.
*/
public static ArrayList < Boolean > boom = new ArrayList < Boolean > ();
/second new elelemtn of interaction.
*
*/
public static ArrayList < Integer > nELM2 = new ArrayList < Integer > ();
/
* heat needed to interact.
*/
public static ArrayList < Integer > reqHeat =
new ArrayList < Integer > ();
/**
* size of explostion.
*/
public static ArrayList < Integer > eSIZE = new ArrayList < Integer > ();
/possibility that a neighbor will happen to
*one of 8 directions or not fall through to next choice.
*/
public static double avper;
/max heat.*/
public static final int MAX_HEAT = 100;
/min heat.*/
public static final int MIN_HEAT = -100;
//draw border?
boolean bottom = false;
//has the border been drawn?
boolean borderDrawn = false;
/makes a color based on Red Green Blue first makes
* sure they are in the 0-255 range.*/
public static Color makeCol(int r, int g, int b) {
if (r > 255) {
r = 255;
}
else if (r < 0) {
r = 0;
}
if (g > 255) {
g = 255;
}
else if (g < 0) {
g = 0;
}
if (b > 255) {
b = 255;
}
else if (b < 0) {
b = 0;
}
Color c = new Color(r, g, b);
return c;
}
/checks if a value is zero.*/
public static boolean isZero(int n) {
if (n == 0) {
return true;
}
else {
return false;
}
}
/checks if a value is positive.*/
public static boolean isPositive(int n) {
if (n > 0) {
return true;
}
else {
return false;
}
}
/averages an indiscriminate number of double arguments into an int.*/
public static int average(double... nS ) {
int numberOfNumbers = nS.length;
int total = 0;
for (int i = 0; i < numberOfNumbers; i++ ) {
total += nS[i];
}
return (int)total / numberOfNumbers;
}
/returns a true with a percent chance of the input \n
* ex \n*input of 10 has about a 10% chance of returning true./
public boolean pc(double chance) {
Random rand = new Random();
double r1;
if (chance <= 0) {
return false;
}
else if (chance >= 100) {
return true;
}
else {
r1 = rand.nextInt(101);
if (r1 <= chance) {
return true;
}
else {
return false;
}
}
}
/absolute valueof input.*/
public static int absV(int n) {
return Math.abs(n);
}
/start a sand engine.*/
public SandEngine() {
setSize(pWIDTH, pHEIGHT + 50);
setBackground(new Color(236, 236, 236));
addMouseListener(this);
addMouseMotionListener(this);
startThread();
}
/start runner.*/
private void startThread() {
if (runner == null) {
runner = new Thread(this);
runner.start();
}
}
/overwrite run method.*/
public void run() {
while (runner != null) {
computeAndDrawSand();
repaint();
try {
Thread.sleep(10);
}
catch (Exception e) {
//do nothing
}
}
}
/calls methods for computing and drawing sand.*/
private void computeAndDrawSand() {
g = buffer.getGraphics();
if (!pause) {
if (!bottom) {
for (int i = 0; i < pWIDTH; i++) {
pixelData[i][pHEIGHT - 2] = 0;
drawData[i][pHEIGHT - 2] = true;
}
for (int i = 0; i < pWIDTH; i++) {
pixelData[i][1] = 0;
drawData[i][1] = true;
}
}
else {
}
moveSand();
if (doHeat) {
limitHeat();
}
g.setColor(Color.black);
g.fillRect(0, 0, pWIDTH, pHEIGHT + 50);
}
else {
g.setColor(Color.black);
g.fillRect(0, pHEIGHT, pWIDTH, pHEIGHT + 50);
}
drawSand(g);
}
/**eAM stands for Element At Mouse simply prints the name and heat
* of the element at the current mouse coordinate
*\n works closely with the mousemoved method, which
*grabs the coordinates of every movement of the mouse.
**/
private void eAM(Graphics g3) {
String cN;
int cH;
int cE;
g3.setColor(new Color(2, 255, 255));
try {
cE = pixelData[mousex2][mousey2];
cN = nameS.get(cE);
cH = heatData[mousex2][mousey2];
}
catch (ArrayIndexOutOfBoundsException e) {
cN = "Not In Bounds";
cH = 0;
}
g3.drawString("Element: " + cN + " Heat: " + cH, 5, pHEIGHT + 15);
g3.drawString("X: " + mousex2 + " Y: " + mousey2, 5, pHEIGHT + 30);
}
/**computes the movements of the sand
and checks for heat and neighbor interactions.
**/
private void moveSand() {
//variable declaration
int thisE;
int thisH;
int up;
int upH;
int upleft;
int upleftH;
int upright;
int uprightH;
int down;
int downH;
int left;
int leftH;
int right;
int rightH;
int downleft;
int downleftH;
int downright;
int downrightH;
int r1;
int r2;
int slip2;
int gravity2;
int cH;
int h;
double density2;
boolean r3;
//end variable declaration
for (int y = 1; y < pHEIGHT - 1; y++ ) {
for (int x = 1; x < pWIDTH - 1; x++ ) {
if (!drawData[x][y]) {
//variable assighnment
thisE = pixelData[x][y];
thisH = heatData[x][y];
up = pixelData[x - 1][y];
upH = heatData[x - 1][y];
upright = pixelData[x - 1][y + rightD];
uprightH = heatData[x - 1][y + rightD];
upleft = pixelData[x - 1][y + leftD];
upleftH = heatData[x - 1][y + leftD];
gravity2 = gravity.get(thisE);
down = pixelData[x][y + gravity2];
left = pixelData[x + 1][y];
right = pixelData[x - 1][y];
downleft = pixelData[x + 1][y + gravity2];
downright = pixelData[x - 1][y + gravity2];
downH = heatData[x][y + gravity2];
leftH = heatData[x + 1][y];
rightH = heatData[x - 1][y];
downleftH = heatData[x + 1][y + gravity2];
downrightH = heatData[x - 1][y + gravity2];
slip2 = slip.get(thisE);
density2 = density.get(thisE);
r1 = generator.nextInt(11);
//end variable assighnment
if (thisE != 0) {
if (gravity2 != 0) {
if (r1 < 3) {
if (downleft == 0 /&& slip2 != 0/) {
pixelData[x][y] = 0;
heatData[x][y] = 0;
pixelData[x + 1][y + gravity2] = thisE;
heatData[x + 1][y + gravity2] = thisH;
drawData[x][y] = true;
drawData[x + 1][y + gravity2] = true;
}
else if (density.get(downleft) < density2 //&&
/slip2 != 0/) {
pixelData[x + 1][y + gravity2] = thisE;
heatData[x + 1][y + gravity2] = thisH;
pixelData[x][y] = downleft;
heatData[x][y] = downleftH;
drawData[x + 1][y + gravity2] = true;
drawData[x][y] = true;
}
else if (slip2 != 0) {
if (left == 0) {
pixelData[x][y] = 0;
heatData[x][y] = 0;
pixelData[x + 1][y] = thisE;
heatData[x + 1][y] = thisH;
drawData[x + 1][y] = true;
drawData[x][y] = true;
}
else {
pixelData[x][y] = thisE;
heatData[x][y] = thisH;
drawData[x][y] = true;
}
}
else {
pixelData[x][y] = thisE;
heatData[x][y] = thisH;
drawData[x][y] = true;
}
}
else if (r1 > 7) {
if (downright == 0 /&& slip2 != 0/) {
pixelData[x][y] = 0;
heatData[x][y] = 0;
pixelData[x - 1][y + gravity2] = thisE;
heatData[x - 1][y + gravity2] = thisH;
drawData[x][y] = true;
drawData[x - 1][y + gravity2] = true;
}
else if (density.get(downright) < density2 //&&
/slip2 != 0*/) {
pixelData[x - 1][y + gravity2] = thisE;
heatData[x - 1][y + gravity2] = thisH;
pixelData[x][y] = downright;
heatData[x][y] = downrightH;
drawData[x - 1][y + gravity2] = true;
drawData[x][y] = true;
}
else if (right == 0) {
if (slip2 != 0) {
pixelData[x - 1][y] = thisE;
heatData[x - 1][y] = thisH;
pixelData[x][y] = 0;
heatData[x][y] = 0;
drawData[x - 1][y] = true;
drawData[x][y] = true;
}
else {
pixelData[x][y] = pixelData[x][y];
heatData[x][y] = heatData[x][y];
drawData[x][y] = true;
}
}
else {
pixelData[x][y] = pixelData[x][y];
heatData[x][y] = heatData[x][y];
drawData[x][y] = true;
}
}
else {
if (down == 0) {
pixelData[x][y] = 0;
heatData[x][y] = 0;
pixelData[x][y + gravity2] = thisE;
heatData[x][y + gravity2] = thisH;
drawData[x][y] = true;
drawData[x][y + gravity2] = true;
}
else if (density.get(down) < density2) {
pixelData[x][y + gravity2] = thisE;
heatData[x][y + gravity2] = thisH;
pixelData[x][y] = down;
heatData[x][y] = downH;
drawData[x][y + gravity2] = true;
drawData[x][y] = true;
}
else {
pixelData[x][y] = pixelData[x][y];
heatData[x][y] = heatData[x][y];
drawData[x][y] = true;
}
}
}
else {
pixelData[x][y] = pixelData[x][y];
heatData[x][y] = heatData[x][y];
drawData[x][y] = true;
}
}
else {
pixelData[x][y] = pixelData[x][y];
drawData[x][y] = true;
checkN[x][y] = false;
heatData[x][y] = 0;
}
if (doHeat && checkH[x][y]) {
heatEx(x, y);
}
if (doNeighbor) {
if (checkN[x][y] /*true*/) {
if (thisE != 0) {
int iT = 0;
int iT2 = 0;
double curChance;
double curChance2;
for (Integer e : eLM1) {
if (e == pixelData[x][y]) {
curChance = cHANCE.get(iT);
if (pc(curChance)) {
if (!boom.get(iT)) {
if (doNieghbor(x, y,
eLM2.get(iT), iT)) {
break;
}
}
else {
if (doExplosion(x, y,
eLM2.get(iT), iT)) {
break;
}
}
}
}
iT += 1;
}
}
}
}
}
}
}
}
/**
exchange heat computation for inputted location /n
// doing much better now, though still not perfect.
*/
private void heatEx(int x, int y) {
int thisE = pixelData[x][y];
if (thisE != 0) {
int thisH = heatData[x][y];
int h = heat.get(thisE);
if ( h > 100) {
hSource = true;
heatData[x][y] = 100;
if (heat.get(pixelData[x + 1][y]) != 0) {
heatData[x + 1][y] = heatData[x + 1][y] +
heat.get(pixelData[x][y]) - 100;
checkH[x + 1][y] = false;
}
if (heat.get(pixelData[x - 1][y]) != 0) {
heatData[x - 1][y] = heatData[x - 1][y] +
heat.get(pixelData[x][y]) - 100;
checkH[x - 1][y] = false;
}
if (heat.get(pixelData[x + 1][y + rightD]) != 0) {
heatData[x + 1][y + rightD] = heatData[x + 1][y + rightD] +
heat.get(pixelData[x][y]) - 100;
checkH[x + 1][y + rightD] = false;
}
if (heat.get(pixelData[x + 1][y + leftD]) != 0) {
heatData[x + 1][y + leftD] = heatData[x + 1][y + leftD] +
heat.get(pixelData[x][y]) - 100;
checkH[x + 1][y + leftD] = false;
}
if (heat.get(pixelData[x - 1][y + rightD]) != 0) {
heatData[x - 1][y + rightD] = heatData[x - 1][y + rightD] +
heat.get(pixelData[x][y]) - 100;
checkH[x - 1][y + rightD] = false;
}
if (heat.get(pixelData[x - 1][y]) != 0) {
heatData[x - 1][y + leftD] = heatData[x - 1][y + leftD] +
heat.get(pixelData[x][y]) - 100;
checkH[x - 1][y + leftD] = false;
}
if (heat.get(pixelData[x][y + leftD]) != 0) {
heatData[x][y + leftD] = heatData[x][y + leftD] +
heat.get(pixelData[x][y]) - 100;
checkH[x][y + leftD] = false;
}
if (heat.get(pixelData[x][y + rightD]) != 0) {
heatData[x][y + rightD] = heatData[x][y + rightD] +
heat.get(pixelData[x][y]) - 100;
checkH[x][y + rightD] = false;
}
}
else if ( h < -100) {
hSource = true;
heatData[x][y] = -100;
if (heat.get(pixelData[x + 1][y]) != 0) {
heatData[x + 1][y] = heatData[x + 1][y] +
heat.get(pixelData[x][y]) + 100;
checkH[x + 1][y] = false;
}
if (heat.get(pixelData[x - 1][y]) != 0) {
heatData[x - 1][y] = heatData[x - 1][y] +
heat.get(pixelData[x][y]) + 100;
checkH[x - 1][y] = false;
}
if (heat.get(pixelData[x + 1][y + rightD]) != 0) {
heatData[x + 1][y + rightD] = heatData[x + 1][y + rightD] +
heat.get(pixelData[x][y]) + 100;
checkH[x + 1][y + rightD] = false;
}
if (heat.get(pixelData[x + 1][y + leftD]) != 0) {
heatData[x + 1][y + leftD] = heatData[x + 1][y + leftD] +
heat.get(pixelData[x][y]) + 100;
checkH[x + 1][y + leftD] = false;
}
if (heat.get(pixelData[x - 1][y + rightD]) != 0) {
heatData[x - 1][y + rightD] = heatData[x - 1][y + rightD] +
heat.get(pixelData[x][y]) + 100;
checkH[x - 1][y + rightD] = false;
}
if (heat.get(pixelData[x - 1][y]) != 0) {
heatData[x - 1][y + leftD] = heatData[x - 1][y + leftD] +
heat.get(pixelData[x][y]) + 100;
checkH[x - 1][y + leftD] = false;
}
if (heat.get(pixelData[x][y + leftD]) != 0) {
heatData[x][y + leftD] = heatData[x][y + leftD] +
heat.get(pixelData[x][y]) + 100;
checkH[x][y + leftD] = false;
}
if (heat.get(pixelData[x][y + rightD]) != 0) {
heatData[x][y + rightD] = heatData[x][y + rightD] +
heat.get(pixelData[x][y]) + 100;
checkH[x][y + rightD] = false;
}
}
else if (isZero(h)) {
//do nothing because if heat is
//zero there is nothing to exchange
}
else if ((heatData[x][y] > 0) && thisE != 0) {
if (heat.get(pixelData[x + 1][y]) != 0) {
heatData[x + 1][y] = 1 * absV(average(heatData[x + 1][y],
heatData[x][y]));
checkH[x + 1][y] = false;
}
if (heat.get(pixelData[x - 1][y]) != 0) {
checkH[x - 1][y] = false;
heatData[x - 1][y] = 1 * absV(average(heatData[x - 1][y],
heatData[x][y]));
}
if (heat.get(pixelData[x + 1][y + rightD]) != 0) {
checkH[x + 1][y + rightD] = false;
heatData[x + 1][y + rightD] = 1 * absV(average(
heatData[x + 1][y + rightD], heatData[x][y]));
}
if (heat.get(pixelData[x + 1][y + leftD]) != 0) {
checkH[x + 1][y + leftD] = false;
heatData[x + 1][y + leftD] = 1 * absV(average(
heatData[x + 1][y + leftD], heatData[x][y]));
}
if (heat.get(pixelData[x - 1][y + rightD]) != 0) {
checkH[x - 1][y + rightD] = false;
heatData[x - 1][y + rightD] = 1 * absV(average(
heatData[x - 1][y + rightD], heatData[x][y]));
}
if (heat.get(pixelData[x - 1][y]) != 0) {
checkH[x - 1][y + leftD] = false;
heatData[x - 1][y + leftD] = 1 * absV(average(
heatData[x - 1][y + leftD], heatData[x][y]));
}
if (heat.get(pixelData[x][y + leftD]) != 0) {
checkH[x][y + leftD] = false;
heatData[x][y + leftD] = 1 * absV(average(
heatData[x][y + leftD], heatData[x][y]));
}
if (heat.get(pixelData[x][y + rightD]) != 0) {
checkH[x][y + rightD] = false;
heatData[x][y + rightD] = 1 * absV(average(
heatData[x][y + rightD], heatData[x][y]));
}
}
else if ((heatData[x][y] < 0) && thisE != 0) {
if (heat.get(pixelData[x + 1][y]) != 0) {
heatData[x + 1][y] = -1 * absV(average(
heatData[x + 1][y], heatData[x][y]));
checkH[x + 1][y] = false;
}
if (heat.get(pixelData[x - 1][y]) != 0) {
checkH[x - 1][y] = false;
heatData[x - 1][y] = -1 * absV(average(
heatData[x - 1][y], heatData[x][y]));
}
if (heat.get(pixelData[x + 1][y + rightD]) != 0) {
checkH[x + 1][y + rightD] = false;
heatData[x + 1][y + rightD] = -1 * absV(average(
heatData[x + 1][y + rightD], heatData[x][y]));
}
if (heat.get(pixelData[x + 1][y + leftD]) != 0) {
checkH[x + 1][y + leftD] = false;
heatData[x + 1][y + leftD] = -1 * absV(average(
heatData[x + 1][y + leftD], heatData[x][y]));
}
if (heat.get(pixelData[x - 1][y + rightD]) != 0) {
checkH[x - 1][y + rightD] = false;
heatData[x - 1][y + rightD] = -1 * absV(average(
heatData[x - 1][y + rightD], heatData[x][y]));
}
if (heat.get(pixelData[x - 1][y]) != 0) {
checkH[x - 1][y + leftD] = false;
heatData[x - 1][y + leftD] = -1 * absV(average(
heatData[x - 1][y + leftD], heatData[x][y]));
}
if (heat.get(pixelData[x][y + leftD]) != 0) {
checkH[x][y + leftD] = false;
heatData[x][y + leftD] = -1 * absV(average(
heatData[x][y + leftD], heatData[x][y]));
}
if (heat.get(pixelData[x][y + rightD]) != 0) {
checkH[x][y + rightD] = false;
heatData[x][y + rightD] = -1 * absV(
average(heatData[x][y + rightD], heatData[x][y]));
}
}
}
}
/limits the heat of the entire sandbox and
* lowers/raises heat when hSource is false. */
private void limitHeat() {
for (int x = 0; x < pWIDTH - 1; x++ ) {
for (int y = 0; y < pHEIGHT - 1; y++ ) {
try {
if (pixelData[x][y] == 0) {
heatData[x][y] = 0;
}
if (heatData[x][y] > 100) {
heatData[x][y] = 100;
}
if (heatData[x][y] < -100) {
heatData[x][y] = -100;
}
if (heat.get(pixelData[x][y]) == 0) {
heatData[x][y] = 0;
}
if (!hSource && pixelData[x][y] != 0 &&
heatData[x][y] != 0) {
if (heatData[x][y] > 0) {
heatData[x][y] -= heat.get(pixelData[x][y]);
if (heatData[x][y] < 0) {
heatData[x][y] = 0;
}
}
if (heatData[x][y] < 0) {
heatData[x][y] += heat.get(pixelData[x][y]);
if (heatData[x][y] > 0) {
heatData[x][y] = 0;
}
}
}
}
catch (IndexOutOfBoundsException ex) {
//do nothing
}
}
}
}
/draws sand darkening cold / brightening hot spots./
private void drawSand(Graphics g3) {
Color tC;
int c;
int c2;
int c3;
hSource = false;
for (int x = 1; x < pWIDTH - 1; x++ ) {
for (int y = 1; y < pHEIGHT - 1; y++ ) {
if ((pixelData[x][y] != 0 || pause) && drawData[x][y] == true) {
if (heatData[x][y] == 0) {
tC = elements.get(pixelData[x][y]);
}
else if (isPositive(heatData[x][y])) {
if (heat.get(pixelData[x][y]) > 100) {
tC = elements.get(pixelData[x][y]);
}
else {
c = elements.get(pixelData[x][y]).getRed() +
heatData[x][y];
c2 = elements.get(pixelData[x][y]).getGreen() +
heatData[x][y];
c3 = elements.get(pixelData[x][y]).getBlue() +
heatData[x][y];
tC = makeCol(c, c2, c3);
}
}
else {
if (heat.get(pixelData[x][y]) < -100) {
tC = elements.get(pixelData[x][y]);
}
else {
c = elements.get(pixelData[x][y]).getRed() +
heatData[x][y];
c2 = elements.get(pixelData[x][y]).getGreen() +
heatData[x][y];
c3 = elements.get(pixelData[x][y]).getBlue() +
heatData[x][y];
tC = makeCol(c, c2, c3);
}
}
g3.setColor(tC);
g3.fillRect(x, y, 1, 1);
drawData[x][y] = false;
checkN[x][y] = true;
checkH[x][y] = true;
}
}
}
eAM(g3);
}
/**overwrite paintcomponent method.*/
public void paintComponent(Graphics g4) {
super.paintComponent(g4);
if (buffer != null) {
g4.drawImage(buffer, 0, 0, null);
}
}
//the following methods overwrite mouse event methods
//some add sand one - mouse moved -finds mouse position for eAM
//most do nothing
/**
* mousePressed.
*/
public void mousePressed(MouseEvent e) {
if (inBounds) {
mousex = e.getX();
mousey = e.getY();
doCircle(mousex,mousey,bsize,eLEMENT);
}
}
/**
* nothing.
*/
public void mouseClicked(MouseEvent e) {
}
/**
* mouse dragged.
*/
public void mouseDragged(MouseEvent e) {
if (inBounds) {
mousex = e.getX();
mousey = e.getY();
doCircle(mousex,mousey,bsize,eLEMENT);
}
}
/**
* nothing.
*/
public void mouseEntered(MouseEvent e) {
inBounds = true;
}
/**
* nothing.
*/
public void mouseExited(MouseEvent e) {
inBounds = false;
}
/**
* nothing.
*/
public void mouseReleased(MouseEvent e) {
}
/**
* mouse moved.
*/
public void mouseMoved(MouseEvent e) {
mousex2 = e.getX();
mousey2 = e.getY();
}
/switch element to draw.*/
public void changeElement(int nE) {
eLEMENT = nE;
}
/change brush size.*/
public void changebsize(int nS) {
bsize = nS;
}
/change whether there is a border.*/
public void changeBottom(boolean nB) {
bottom = nB;
borderDrawn = false;
}
/chane wheter heat is calculated.*/
public void changeHeat(boolean nD) {
doHeat = nD;
}
/change whether neihgbors are done.*/
public void changeNeighbor(boolean nN) {
doNeighbor = nN;
}
/toggle whether the game is paused.*/
public static void togglePause() {
if (pause) {
pause = false;
}
else {
pause = true;
}
}
/clear sandbox.*/
public void clearS() {
for (int y = 0; y < pHEIGHT; y++ ) {
for (int x = 0; x < pWIDTH; x++ ) {
pixelData[x][y] = 0;
heatData[x][y] = 0;
drawData[x][y] = true;
}
}
}
/do neighbor interactions.*/
private boolean doNieghbor(int x, int y, int eLM, int iT) {
int thisE = pixelData[x][y];
int grav = gravity.get(thisE);
int down = pixelData[x][y + 1];
int up = pixelData[x][y - 1];
int left = pixelData[x + leftD][y];
int right = pixelData[x + rightD][y];
int downleft = pixelData[x + leftD][y + 1];
int upleft = pixelData[x + leftD][y - 1];
int downright = pixelData[x + rightD][y + 1];
int upright = pixelData[x + rightD][y - 1];
Random gen = new Random();
int tELM1 = nELM1.get(iT);
int tELM2 = nELM2.get(iT);
boolean returnd;
if (reqHeat.get(iT) == 0) {
if (pc(avper) && upleft == eLM) {
pixelData[x][y] = tELM1;
pixelData[x + leftD][y - 1] = tELM2;
checkN[x][y] = false;
checkN[x + leftD][y - 1] = false;
return true;
}
else if (pc(avper) && up == eLM) {
pixelData[x][y] = tELM1;
pixelData[x][y - 1] = tELM2;
checkN[x][y] = false;
checkN[x][y - 1] = false;
return true;
}
else if (pc(avper) && left == eLM) {
pixelData[x][y] = tELM1;
pixelData[x + leftD][y] = tELM2;
checkN[x][y] = false;
checkN[x + leftD][y] = false;
return true;
}
else if (pc(avper) && right == eLM) {
pixelData[x][y] = tELM1;
pixelData[x + rightD][y] = tELM2;
checkN[x][y] = false;
checkN[x + rightD][y] = false;
return true;
}
else if (pc(avper) && downleft == eLM) {
pixelData[x + leftD][y + 1] = tELM2;
pixelData[x][y] = tELM1;
checkN[x][y] = false;
checkN[x + leftD][y + 1] = false;
return true;
}
else if (pc(avper) && downright == eLM) {
pixelData[x + rightD][y + 1] = tELM2;
pixelData[x][y] = tELM1;
checkN[x][y] = false;
checkN[x + rightD][y + 1] = false;
return true;
}
else if (pc(avper) && upright == eLM) {
pixelData[x][y] = tELM1;
pixelData[x + rightD][y - 1] = tELM2;
checkN[x][y] = false;
checkN[x + rightD][y - 1] = false;
return true;
}
else if (down == eLM) {
pixelData[x][y] = tELM1;
pixelData[x][y + 1] = tELM2;
checkN[x][y] = false;
checkN[x][y + 1] = false;
return true;
}
else {
return false;
}
}
else if (isPositive(reqHeat.get(iT))) {
if (heatData[x][y] >= reqHeat.get(iT)) {
if (pc(avper) && upleft == eLM) {
pixelData[x][y] = tELM1;
pixelData[x + leftD][y - 1] = tELM2;
checkN[x][y] = false;
checkN[x + leftD][y - 1] = false;
return true;
}
else if (pc(avper) && up == eLM) {
pixelData[x][y] = tELM1;
pixelData[x][y - 1] = tELM2;
checkN[x][y] = false;
checkN[x][y - 1] = false;
return true;
}
else if (pc(avper) && left == eLM) {
pixelData[x][y] = tELM1;
pixelData[x + leftD][y] = tELM2;
checkN[x][y] = false;
checkN[x + leftD][y] = false;
return true;
}
else if (pc(avper) && right == eLM) {
pixelData[x][y] = tELM1;
pixelData[x + rightD][y] = tELM2;
checkN[x][y] = false;
checkN[x + rightD][y] = false;
return true;
}
else if (pc(avper) && downleft == eLM) {
pixelData[x + leftD][y + 1] = tELM2;
pixelData[x][y] = tELM1;
checkN[x][y] = false;
checkN[x + leftD][y + 1] = false;
return true;
}
else if (pc(avper) && downright == eLM) {
pixelData[x + rightD][y + 1] = tELM2;
pixelData[x][y] = tELM1;
checkN[x][y] = false;
checkN[x + rightD][y + 1] = false;
return true;
}
else if (pc(avper) && upright == eLM) {
pixelData[x][y] = tELM1;
pixelData[x + rightD][y - 1] = tELM2;
checkN[x][y] = false;
checkN[x + rightD][y - 1] = false;
return true;
}
else if (down == eLM) {
pixelData[x][y] = tELM1;
pixelData[x][y + 1] = tELM2;
checkN[x][y] = false;
checkN[x][y + 1] = false;
return true;
}
else {
return false;
}
}
else {
return false;
}
}
else {
if (heatData[x][y] <= reqHeat.get(iT)) {
if (pc(avper) && upleft == eLM) {
pixelData[x][y] = tELM1;
pixelData[x + leftD][y - 1] = tELM2;
checkN[x][y] = false;
checkN[x + leftD][y - 1] = false;
return true;
}
else if (pc(avper) && up == eLM) {
pixelData[x][y] = tELM1;
pixelData[x][y - 1] = tELM2;
checkN[x][y] = false;
checkN[x][y - 1] = false;
return true;
}
else if (pc(avper) && left == eLM) {
pixelData[x][y] = tELM1;
pixelData[x + leftD][y] = tELM2;
checkN[x][y] = false;
checkN[x + leftD][y] = false;
return true;
}
else if (pc(avper) && right == eLM) {
pixelData[x][y] = tELM1;
pixelData[x + rightD][y] = tELM2;
checkN[x][y] = false;
checkN[x + rightD][y] = false;
return true;
}
else if (pc(avper) && downleft == eLM) {
pixelData[x + leftD][y + 1] = tELM2;
pixelData[x][y] = tELM1;
checkN[x][y] = false;
checkN[x + leftD][y + 1] = false;
return true;
}
else if (pc(avper) && downright == eLM) {
pixelData[x + rightD][y + 1] = tELM2;
pixelData[x][y] = tELM1;
checkN[x][y] = false;
checkN[x + rightD][y + 1] = false;
return true;
}
else if (pc(avper) && upright == eLM) {
pixelData[x][y] = tELM1;
pixelData[x + rightD][y - 1] = tELM2;
checkN[x][y] = false;
checkN[x + rightD][y - 1] = false;
return true;
}
else if (down == eLM) {
pixelData[x][y] = tELM1;
pixelData[x][y + 1] = tELM2;
checkN[x][y] = false;
checkN[x][y + 1] = false;
return true;
}
else {
return false;
}
}
else {
return false;
}
}
}
/**
* do explosion.
*/
private boolean doExplosion(int x, int y, int eLM, int iT) {
int thisE = pixelData[x][y];
int grav = gravity.get(thisE);
int down = pixelData[x][y + 1];
int up = pixelData[x][y - 1];
int left = pixelData[x + leftD][y];
int right = pixelData[x + rightD][y];
int downleft = pixelData[x + leftD][y + 1];
int upleft = pixelData[x + leftD][y - 1];
int downright = pixelData[x + rightD][y + 1];
int upright = pixelData[x + rightD][y - 1];
int tELM1 = nELM1.get(iT);
Random gen = new Random();
boolean returnS = false;
if (reqHeat.get(iT) == 0) {
if (pc(avper) && upleft == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && up == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && left == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && right == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && downleft == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && downright == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && upright == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (down == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
}
else if (isPositive(reqHeat.get(iT))) {
if (heatData[x][y] >= reqHeat.get(iT)) {
if (pc(avper) && upleft == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && up == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && left == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && right == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && downleft == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && downright == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && upright == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (down == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
}
}
else {
if (heatData[x][y] <= reqHeat.get(iT)) {
if (pc(avper) && upleft == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && up == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && left == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && right == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && downleft == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && downright == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (pc(avper) && upright == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
else if (down == eLM) {
doEx(x, y, eSIZE.get(iT), tELM1);
return true;
}
}
}
return returnS;
}
/**
* make explosion occur.
*/
private void doEx (int x, int y, int size, int eLM) {
// int itter = 0;
// for (int i = 0; i < size; i++ ) {
// for (int j = 0; j < size; j++ ) {
// try {
// pixelData[(x - (size / 2)) + i][(y -
// (size / 2)) + j] = eLM;
// heatData[(x - (size / 2)) + i][(y -
// (size / 2)) + j] = 0;
// drawData[(x - (size / 2)) + i][(y -
// (size / 2)) + j] = true;
// }
// catch (ArrayIndexOutOfBoundsException ex) {
// //do nothing
// }
// }
// }
doCircle(x,y,size,eLM);
}
private void doCircle(int x, int y, int size, int elm){
for(int i = x-(size);i<=x+(size);i++){
for(int j = y-(size);j<=y+(size);j++){
if(Math.sqrt(((x-i)*(x-i))+((y-j)*(y-j)))<=(size)){
try {
pixelData[i][j] = elm;
heatData[i][j] = 0;
drawData[i][j] = true;
}
catch (ArrayIndexOutOfBoundsException ex) {
//do nothing
}
}
}
}
}
}
any advise is welcome
SourceZip.zip