I'm working on a Java Game using LWJGL. I made a particle system and would like to obtain same result as found on this website: http://play.cubedpixels.de
This is what I got so far:
I tried my best and the problem is it's stopping and they are only moving in one direction. Also the lines are not like on this website. On the website it's smoother and better. They are using OpenGL too.
How to solve these problems and make my implementation better, more like it is one the website?
The code below shows two classes: ParticleGalaxy and Particle. Latter one is inner class of the former, but for clarity I've split them into separate snippets.
ParticleGalaxy:
public class ParticleGalaxy
{
private int count;
private int width;
private int height;
private int mousex;
private int mousey;
public ArrayList<Particle> particles = new ArrayList();
private Random random = new Random();
private TimerUtil timer = new TimerUtil();
int state = 0;
int a = 255;
int r = 255;
int g = 0;
int b = 0;
public ParticleGalaxy(int count, int width, int height)
{
this.count = count;
this.width = width;
this.height = height;
for(int i = 0; i < count; i++)
{
this.particles.add(
new Particle(this.random.nextInt(width),
this.random.nextInt(height)));
}
}
public void drawParticles(int mousex, int mousey)
{
this.mousex = mousex;
this.mousey = mousey;
for(Particle p : this.particles)
{
if(p.reset)
{
p.resetPosSize();
p.reset = false;
}
int x = Math.abs(p.getX() - mousex);
int y = Math.abs(p.getY() - mousey);
if((x < 40 && x > -40) && (y<35 && y>-40))
{
p.setConnect(true);
}
else
{
p.setConnect(false);
}
p.draw();
}
}
}
Particle:
public class Particle
{
private int x;
private int y;
private int k;
private int movey;
private int movex;
private int starty;
private int startx;
private int locationy;
private int locationx;
private float size;
private boolean reset;
private boolean connect;
private Random random = new Random();
private TimerUtil timer = new TimerUtil();
private boolean moving = false;
private boolean start = false;
public Particle(int x, int y)
{
this.x = x;
this.y = y;
this.startx = x;
this.starty = y;
this.size = genRandom(0.57F, 0.71F);
}
public void setConnect(boolean bool)
{
connect = bool;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
private void drawLine(int xto, int yto, int xfrom, int yfrom)
{
GL11.glLineWidth(1.2f);
GL11.glColor3f(1.0f, 1.0f, 1.0f);
GL11.glBegin(GL11.GL_LINE_STRIP);
GL11.glVertex2d(xto, yto);
GL11.glVertex2d(xfrom, yfrom);
GL11.glEnd();
}
public void draw()
{
if(!start)
{
start = true;
movex = height - random.nextInt(height);
movey = width - random.nextInt(width);
move(startx, starty, movex, movey);
}
float speed = 1;
float elapsed = 0.01f;
// On starting movement
float distance = (float)Math.sqrt(Math.pow(movex - startx, 2) +
Math.pow(movey - starty, 2));
float directionX = (movex - startx) / distance;
float directionY = (movey - starty) / distance;
if(moving == true)
{
x += directionX * speed * elapsed;
y += directionY * speed * elapsed;
if(Math.sqrt(Math.pow(x - startx, 2) + Math.pow(y - starty, 2)) >= distance)
{
x = (int)movex;
y = (int)movey;
resetPosSize();
this.reset = true;
moving = false;
}
}
this.k += 1;
int xx = 0;
int yy = 0;
this.locationx = this.x + xx;
this.locationy = this.y + yy;
if(locationx < 0 || locationy < 0)
this.reset = true;
if(locationx > width || locationy > height)
this.reset = true;
GuiUtils.drawCircle(this.x + xx, this.y + yy, this.size, -1);
if(connect)
{
for(Particle p : particles)
{
if(p.connect)
drawLine(locationx, locationy, p.locationx, p.locationy);
}
}
}
public void move(int startX, int startY, int endX, int endY)
{
x = (int)startX;
y = (int)startY;
moving = true;
}
public void resetPosSize()
{
this.x = this.random.nextInt(ParticleGalaxy.this.width);
this.y = this.random.nextInt(ParticleGalaxy.this.height);
startx = x;
starty = y;
movex = height - random.nextInt(height);
movey = width - random.nextInt(width);
move(startx, starty, movex, movey);
}
public float genRandom(float min, float max)
{
return (float)(min + Math.random() * (max - min + 1.0F));
}
}
Related
So I'm working on a paint program in school and now I have to double buffer it. After a week of searching and using tutorials online I am still unable to double buffer my program properly... I have written a double buffer function but then you can't paint anything... When i disable the double buffer you can paint fine but the screen flickers. Please help
(Yes I am aware that some of my code is deprecated and I should fix that)
Code:
import java.applet.*;
import java.awt.*;
public class PaintRun extends Applet
{
static int posx = 0;
static int posy = 0;
static int posxOld = 0;
static int posyOld = 0;
static int size = 20;
static int toolNum = 0;
static boolean ready = false;
static Color col = new Color(120,120,120);
static Button clear = new Button(0,0,20,'C');
static Button sizeInc = new Button(20,0,20,'+');
static Button sizeDec = new Button(40,0,20,'-');
static Tools tool = new Tools(posx,posy);
public void paint(Graphics g)
{
drawButtons(g);
detectButtons(g);
}
private static void detectButtons(Graphics g)
{
if (clear.detect(posx,posy) == true)
{
g.setColor(Color.WHITE);
g.fillRect(0, 0, 800000, 800000);
drawButtons(g);
}
else if (sizeInc.detect(posx, posy))
{
size+=2;
drawButtons(g);
}
else if (sizeDec.detect(posx, posy))
{
size-=2;
if (size <= 2)
size = 2;
drawButtons(g);
}
else
{
if (ready == true)
{
g.setColor(Color.BLACK);
g.drawLine(posxOld, posyOld, posx, posy);
drawButtons(g);
}
}
}
private static void drawButtons(Graphics g)
{
clear.setColor(col, Color.BLACK);
sizeInc.setColor(col, Color.BLACK);
sizeDec.setColor(col, Color.BLACK);
clear.drawButton(g);
sizeInc.drawButton(g);
sizeDec.drawButton(g);
}
public boolean mouseDown(Event e, int x, int y)
{
posx = x;
posy = y;
posxOld = x;
posyOld = y;
ready = true;
repaint();
return true;
}
public boolean mouseDrag(Event e, int x, int y)
{
posxOld = posx;
posyOld = posy;
posx = x;
posy = y;
repaint();
return true;
}
// Normal Update function
public void update(Graphics g)
{
paint(g);
}
// Double buffered Update function
/*public void update(Graphics g)
{
Graphics offgc;
Image offscreen = null;
Dimension d = size();
offscreen = createImage(d.width, d.height);
offgc = offscreen.getGraphics();
offgc.setColor(getBackground());
offgc.fillRect(0, 0, d.width, d.height);
offgc.setColor(getForeground());
paint(offgc);
g.drawImage(offscreen, 0, 0, this);
}
*/
}
class Button extends Applet
{
int minX; // X coord where the button is drawn
int minY; // Y coord where the button is drawn
int maxX; // X size
int maxY; // Y size
char letter;
Color back;
Color line;
// Constructor block
public Button(char desc)
{
minX = 0;
minY = 0;
maxX = 40;
maxY = 40;
back = new Color(255,255,255);
line = new Color(0,0,0);
letter = desc;
}
public Button(int x, int y, char desc)
{
minX = x;
minY = y;
maxX = 40;
maxY = 40;
back = new Color(255,255,255);
line = new Color(0,0,0);
letter = desc;
}
public Button(int x, int y, int size, char desc)
{
minX = x;
minY = y;
maxX = size;
maxY = size;
back = new Color(255,255,255);
line = new Color(0,0,0);
letter = desc;
}
public Button(int x, int y, int sizeX, int sizeY, char desc)
{
minX = x;
minY = y;
maxX = sizeX;
maxY = sizeY;
back = new Color(255,255,255);
line = new Color(0,0,0);
letter = desc;
}
// Draws the button
public void drawButton(Graphics g)
{
g.setColor(back);
g.fillRect(minX, minY, maxX, maxY);
g.setColor(line);
g.drawRect(minX, minY, maxX, maxY);
g.drawString(Character.toString(letter), (minX+maxX/2)-4, (minY+maxY/2)+4);
}
// Sets the button colors
public void setColor(Color b, Color l)
{
back = b;
line = l;
}
// Detects if those coordinates are in the button location or not
public boolean detect(int x, int y)
{
boolean flag = false;
if (x > minX && x < (minX + maxX) && y > minY && y < (minY + maxY))
flag = true;
else
flag = false;
return flag;
}
}
Hey if i have a simple rectangle class, how can i make it so that it creates that rectangle next to each other in a grid like pattern? maybe like 10 rows 10 columns?
public class Vak {
private int posX = 0;
private int posY = 0;
private int width = 50;
private int height = 50;
private Color colour;
public Vak(Color c, int x, int y){
this.colour = c;
this.posX = x;
this.posY = y;
}
public int vakPosY(){
return this.posY;
}
public int vakPosX(){
return this.posX;
}
public void draw (Graphics g){
g.setColor(this.colour);
g.drawRect(posX, posY, width, height);
}
public void move(int numberPixelsX, int numberPixelsY){
this.posX = this.posX + numberPixelsX;
this.posY = this.posY + numberPixelsY;
}
}
this is my code for rectangle "vak"
Is this what you are looking for?
int mapWidth = 10;
int mapHeight = 10;
// tileWidth and tileHeight should probably be public static const fields or static readonly properties of some class, but I put them here for now.
int tileWidth = 50; // Pixels
int tileHeight = 50; // Pixels
// tiles should probably be a field of a Map class (if you have one)
Vak[][] tiles = new Vak[mapWidth][mapHeight];
for(int x = 0; x < mapWidth; x++)
{
for(int y = 0; y < mapHeight; y++)
{
tiles[x][y] = new Vak(Color.white, x*tileWidth, y*tileHeight);
}
}
And then in the drawing part of the main loop:
for(Vak[] row : tiles)
{
for(Vak tile : row)
{
tile.draw(g);
}
}
I want to add to my activList elements that have 3 parameters (an iD and their x y position) using: activList.add(new Fiducial(iD, x, y ));
import TUIO.*;
TuioProcessing tuioClient;
// Grid variables
int cols = 10, rows = 10;
int rectangleWidth = 100;
int rectangleHeight = 60;
// these are some helper variables which are used
// to create scalable graphical feedback
int k, l, iD;
float cursor_size = 15;
float object_size = 60;
float table_size = 760;
float scale_factor = 1;
float x, y;
ArrayList<Fiducial> activList;
public class Fiducial {
public int iD;
public float x;
public float y;
}
void draw() {
// Begin loop for columns
for ( k = 0; k < cols; k++) {
// Begin loop for rows
for ( l = 0; l < rows; l++) {
fill(255);
stroke(0);
rect(k*rectangleWidth, l*rectangleHeight, rectangleWidth, rectangleHeight);
}
}
// This part detects the fiducial markers
float obj_size = object_size*scale_factor;
float cur_size = cursor_size*scale_factor;
ArrayList<TuioObject> tuioObjectList = tuioClient.getTuioObjectList();
for (int i=0; i<tuioObjectList.size (); i++) {
TuioObject tobj= tuioObjectList.get(i);
stroke(0);
fill(0, 0, 0);
pushMatrix();
translate(tobj.getScreenX(width), tobj.getScreenY(height));
rotate(tobj.getAngle());
rect(-80, -40, 80, 40);
popMatrix();
fill(255);
x = round(10*tobj.getX ());
y = round(10*tobj.getY ());
iD = tobj.getSymbolID();
activList.add(new Fiducial(iD, x, y ));
}
}
When running this, I get the error "The constructor FiducialDetection.Fiducial(int,float,float) is undefined" at this line:
activList.add(new Fiducial(iD, x, y ));
I don't get it, I defined it using:
public class Fiducial {
public int iD;
public float x;
public float y;
}
Why do I still get this error ?
You have to add constructor with argument.
public class Fiducial {
public int iD;
public float x;
public float y;
public Fiducial(int iD, float x, float y) {
this.iD = iD;
this.x = x;
this.y = y;
}
}
I have a chicken image that only moves whenever I press my arrow keys, the image always appear at the lower left corner when I start to run the program. My problem is that how can I make the image appear at the top or anywhere on the screen(except on the lower left) and the image still moves when I press the arrow keys . I'm not really sure but I think this problem is coming from my translate(). Is there something wrong with my calculation? Thanks for sharing your ideas...
Here's the code...
public class Chicken extends Sprite implements ImageObserver
{
private java.awt.Image fishImage;
private final Board board;
private double x;
private double y;
private final double chickenHeight = 1.6;
private final double chickenWidth = 1.8;
private double speed;
private boolean visible;
private double angle;
private double dx_m;
private double dy_m;
private boolean collision = false;
public Chicken(Board board, String name, double x, double y, double speed)
{
super(name);
this.board = board;
this.x = x;
this.y = y;
this.speed = convertToMeterPerSecond(speed);
visible = true;
URL iU = this.getClass().getResource("chicken.jpg");
ImageIcon icon = new ImageIcon(iU);
chickenImage = icon.getImage();
}
public Image getImage()
{
return chickenImage;
}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT)
{
dx_m = -0.5;
}
if (key == KeyEvent.VK_RIGHT)
{
dx_m = 0.5;
}
if (key == KeyEvent.VK_UP)
{
dy_m = 0.5;
}
if (key == KeyEvent.VK_DOWN)
{
dy_m = -0.5;
}
}
public void keyReleased(KeyEvent e)
{
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT)
{
dx_m = 0;
}
if (key == KeyEvent.VK_RIGHT)
{
dx_m = 0;
}
if (key == KeyEvent.VK_UP)
{
dy_m = 0;
}
if (key == KeyEvent.VK_DOWN)
{
dy_m = 0;
}
}
#Override
public void move(long dt)
{
double right_wall = board.x1_world;
double up_wall = board.y1_world;
double down_wall = 0.0;
double left_wall = 0.0;
x += dx_m;
y += dy_m;
if (x >= right_wall)
{
x = right_wall;
}
if (y > up_wall)
{
y = up_wall;
}
if (x <= left_wall)
{
x = left_wall;
}
if (y < down_wall)
{
y = down_wall;
}
}
#Override
public void render(Graphics2D g2d)
{
AffineTransform t = g2d.getTransform();
final double foot_position_y = chickenHeight;
final double foot_position_x = chickenWidth / 2;
double xx = board.convertToPixelX(x - foot_position_x);
double yy = board.convertToPixelY(y + foot_position_y);
g2d.translate(xx, yy);
// ratio for the actual size of the Image
double x_expected_pixels = chickenHeight * board.meter;
double y_expected_pixels = chickenWidth * board.meter;
double w = ((ToolkitImage) chickenImage).getWidth();
double h = ((ToolkitImage) chickenImage).getHeight();
double x_s = x_expected_pixels / w;
double y_s = y_expected_pixels / h;
g2d.scale(x_s, y_s);
g2d.drawImage(getImage(), (int) x, (int) y, this);
g2d.setTransform(t);
}
#Override
public void moveAt(double distance_x, double distance_y)
{
this.x = (int) distance_x;
this.y = (int) distance_y;
}
public void setAngle(double angle)
{
this.angle = angle;
}
#Override
public RectangleX getBounds()
{
return new RectangleX(x, y, chickenWidth, chickenHeight);
}
#Override
public double getWidth()
{
return WIDTH;
}
#Override
public double getHeight()
{
return HEIGHT;
}
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
{
return true;
}
}
this is my chicken class
public double meter;
int y1_pixel;
y1_pixel = getHeight();
public int convertToPixelX(double distance)
{
return (int) (distance * meter);
}
public int convertToPixelY(double y_world)
{
return (int) (y1_pixel - (y_world * meter));
}
this is coming from my board class.
Your render method is using the x and y coordinates of the class to determine where to draw the Chicken each time. A simple solution to your problem is to use random values for x and y when you create a Chicken instance.
An alternate solution would be to create another constructor that do not take values for x or y and instead sets them to be default values anywhere between 0 and board.x1_world or board.y1_world, depending on the variable.
public Chicken(Board board, String name, double speed)
{
this( board, name,
(int)( Math.random() * ( board.x1_world - chickenWidth ) ),
(int)( Math.random() * ( board.y1_world - chickenHeight ) ),
speed );
}
I have a two image that moves in a random direction. Now, if that images would bump each other I want it to disappear and that is my problem about making a collision detection. Could someone help me about this problem?
Here is the code:
public class HumanBeing extends Sprite implements ImageObserver
{
private java.awt.Image humanImage;
private final World world;
private double x;
private double y;
private double speed;
private double direction = 1;
private java.util.List<Sprite> objects = new ArrayList<Sprite>();
private double angle;
public HumanBeing(World world, double x, double y, double speed)
{
this.world =world;
this.x = x;
this.y = y;
this.speed = convertToMeterPerSecond(speed);
URL iU = this.getClass().getResource("human.jpg");
ImageIcon icon = new ImageIcon(iU);
humanImage = icon.getImage();
objects.add(this);
}
public Image getImage()
{
return humanImage;
}
#Override
public void move(long dt)
{
double dt_s = dt / 1e9;
double dx_m = speed * dt_s * Math.sin(angle);
double dy_m = speed * dt_s * Math.cos(angle);
final double right_wall = world.x1_world;
final double up_wall = world.y1_world;
final double down_wall = 0.0;
final double left_wall = 0.0;
x += dx_m;
y += dy_m;
if (x >= right_wall)
{
setRandomDirection();
}
if (y > up_wall)
{
setRandomDirection();
}
if (x <= left_wall)
{
setRandomDirection();
}
if (y < down_wall)
{
setRandomDirection();
}
}
public void setRandomDirection()
{
HumanBeing humanbeing = this;
humanbeing.setAngle(Math.PI * 2 * Math.random());
}
#Override
public void render(Graphics2D g2d)
{
AffineTransform t = g2d.getTransform();
final double humanHeight = 1.6;// meter
final double humanWidth = 1.8; //meter
final double foot_position_y = humanHeight;
final double foot_position_x = humanWidth / 2;
int xx = world.convertToPixelX(x - foot_position_x); // to find the upper-left corner
int yy = world.convertToPixelY(y + foot_position_y); // to find the upper-left corner
g2d.translate(xx, yy);
// ratio for actual Image size
double x_expected_pixels = humanHeight * board.meter;
double y_expected_pixels = humanWidth * board.meter;
double w = ((ToolkitImage) humanImage).getWidth();
double h = ((ToolkitImage) humanImage).getHeight();
double x_s = x_expected_pixels / w;
double y_s = y_expected_pixels / h;
g2d.scale(x_s, y_s);
g2d.drawImage(getImage(), 0, 0, this); // upper left corner
g2d.setColor(Color.BLACK);
g2d.setTransform(t);
}
#Override
public void moveAt(double distance_x, double distance_y)
{
this.x = distance_x;
this.y = distance_y;
}
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
{
return false;
}
public void setAngle(double angle)
{
this.angle = angle;
}
}
this is my HumanBeing class
public class Chicken extends Sprite implements ImageObserver
{
private java.awt.Image chickenImage;
private final World world;
private double x;
private double y;
private double speed;
private double angle;
public Chicken(World world, double x, double y, double speed)
{
this.world = world;
this.x = x;
this.y = y;
this.speed = convertToMeterPerSecond(speed);
URL iU = this.getClass().getResource("chicken.gif");
ImageIcon icon = new ImageIcon(iU);
chickenImage = icon.getImage();
}
public Image getImage()
{
return chickenImage;
}
public void move(long dt)
{
double dt_s = dt / 1e9;
double dx_m = speed * dt_s * Math.sin(angle);
double dy_m = speed * dt_s * Math.cos(angle);
final double right_wall = world.x1_world;
final double up_wall = world.y1_world;
final double down_wall = 0.0;
final double left_wall = 0.0;
x += dx_m;
y += dy_m;
if (x >= right_wall)
{
x = right_wall;
setRandomDirection();
}
if (y > up_wall)
{
y = up_wall;
setRandomDirection();
}
if (x <= left_wall)
{
x = left_wall;
setRandomDirection();
}
if (y < down_wall)
{
y = down_wall;
setRandomDirection();
}
}
public void setRandomDirection()
{
Chicken chicken = this;
chicken.setAngle(Math.PI * 2 * Math.random());
}
#Override
public void render(Graphics2D g2d)
{
AffineTransform t = g2d.getTransform();
double height = 0.3; //meter
double width = 0.3; //meter
double chicken_footy = height;
double chicken_footx = width/2;
int xx = world.convertToPixelX(x - chicken_footx);
int yy = world.convertToPixelY(y + chicken_footy);
g2d.translate(xx, yy);
double x_expected_pixels = width * board.meter;
double y_expected_pixels = height * board.meter;
double x_s = x_expected_pixels / ((ToolkitImage) chickenImage).getWidth();
double y_s = y_expected_pixels / ((ToolkitImage) chickenImage).getHeight();
g2d.scale(x_s, y_s);
g2d.drawImage(getImage(), 0, 0, this);
g2d.setColor(Color.BLACK);
g2d.setTransform(t);
}
public void moveAt(double distance_x, double distance_y)
{
this.x = (int) distance_x;
this.y = (int) distance_y;
}
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
{
return true;
}
public void setAngle(double angle)
{
this.angle = angle;
}
}
this is my chicken class
Draw invisible Rectangle around your sprites as like Box's and than use below method to check whether they are intersecting or not :)
http://download.oracle.com/javase/1.4.2/docs/api/java/awt/Rectangle.html#intersects(java.awt.Rectangle)
if(rect.intersect(anotherRect))
{
disappear();
}
Good luck