Im trying to make a Java screensaver of a 3D rotating Lorenz Attractor
Im using java and jogl (OPENGL) to render the graphics...
i have 2 classes one is the main program setup OPENGL etc...
and another that just stores a LinkedList of Point3d's That are the vertex of the line..
Only one new point is added to the List every frame render.....
The problem i am having is render speed is very slow, my question is this...
1. Is there a Better / Easy way of buffering either the screen or the line strip so i only need to draw the last line....
2. Can VBO's be used for LINE_STRIP's and if i have to add one vertex to the buffer every step is this really going to speed things up...?
Its really quite annoying... glBegin()/ glEnd() works fine up to about 100 lines then crashes badly.
Help much needed to speed up render and would be greatly apreaciated.....
Ive added the working code below to get it to work you have to link to JOGL opengl lib's
CODE
LorenzSim.java
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import javax.media.opengl.glu.GLU;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.vecmath.Point3d;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.*;
import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.util.gl2.GLUT;
import java.util.*;
import java.awt.event.*;
import sun.misc.*;
public class LorenzSim implements GLEventListener, KeyListener {
private static final int MIN_X = -20;
private static final int MAX_X = 20;
private static final int MIN_Y = -20;
private static final int MAX_Y = 20;
private static final double MIN_Z = 0;
private static final double MAX_Z = 40;
/**
* #param args
*/
// GLOBAL PARTS
boolean started = false;
int index = 0; // ANIMATOR COUNTER
String consoleLine = "";
// GENERAL OPEN GL
GLProfile glp = null;
GLCapabilities caps = null;
GLCanvas canvas = null;
GraphicsEnvironment ge = null;
GraphicsDevice gd = null;
Frame frame = null;
// GL _ CAM
double camX = 30;
double camY = 30;
double camZ = 50;
Lorenz myLorenz = null;
public LorenzSim ()
{
// GENERAL OPEN GL AND AWT SETUP
glp = GLProfile.getDefault();
caps = new GLCapabilities(glp);
canvas = new GLCanvas(caps);
ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gd = ge.getDefaultScreenDevice();
frame = new Frame("QuadSim");
frame.setSize(600,600);
//frame.setUndecorated(true);
//gd.setFullScreenWindow(frame);
frame.setVisible(true);
canvas.setSize(frame.getWidth(),frame.getHeight());
frame.add(canvas);
// SETUP EVENT LISTENERS
canvas.addGLEventListener(this);
canvas.addKeyListener(this);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
frame.dispose();
System.exit(0);
}
});
started = true;
FPSAnimator animator = new FPSAnimator(canvas, 60);
animator.add(canvas);
animator.start();
caps.setDoubleBuffered(true);
myLorenz = new Lorenz();
myLorenz.doSteps(0);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Welcome to Quad Simulator v0.1 - by Phil Poore");
LorenzSim mySim = new LorenzSim();
}
//############################################
// GL EVENT INTERFACE
//############################################
#Override
public void display(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
if (started)
{
update();
render(drawable);
//System.out.println("Drisplay_index:"+index);
}
}
private void update() {
// TODO Auto-generated method stub
index++;
myLorenz.step();
}
private void render(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
drawable.swapBuffers();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// START OF RENDER CYCLE
setCamera(gl,glu);
drawAxis(gl);
drawBox(gl);
drawLorenz(gl);
drawHUD(gl);
}
private void drawLorenz(GL2 gl) {
// TODO Auto-generated method stub
gl.glBegin(GL.GL_LINE_STRIP);
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glLineWidth(0.1f);
for (int i = 0; i < myLorenz.myPoints.size() - 1; i++)
{
//float dx = (float) (myLorenz.myPoints.get(i).x - myLorenz.myPoints.get(i+1).x);
//float dy = (float) (myLorenz.myPoints.get(i).y - myLorenz.myPoints.get(i+1).y);
//float dz = (float) (myLorenz.myPoints.get(i).z - myLorenz.myPoints.get(i+1).z);
//float dc = (Math.abs(dx) + Math.abs(dy) + Math.abs(dz))/3.0f;
//gl.glColor3d(dc,dc,dc);
gl.glVertex3d(
myLorenz.myPoints.get(i).x,
myLorenz.myPoints.get(i).y,
myLorenz.myPoints.get(i).z);
}
gl.glEnd();
}
private void drawBox(GL2 gl) {
// TODO Auto-generated method stub
Point3d a = new Point3d(MIN_X,MIN_Y,MIN_Z);
Point3d b = new Point3d(MAX_X,MIN_Y,MIN_Z);
Point3d c = new Point3d(MAX_X,MAX_Y,MIN_Z);
Point3d d = new Point3d(MIN_X,MAX_Y,MIN_Z);
Point3d aa = new Point3d(MIN_X,MIN_Y,MAX_Z);
Point3d ab = new Point3d(MAX_X,MIN_Y,MAX_Z);
Point3d ac = new Point3d(MAX_X,MAX_Y,MAX_Z);
Point3d ad = new Point3d(MIN_X,MAX_Y,MAX_Z);
gl.glBegin(GL.GL_LINE_STRIP);
gl.glVertex3d(a.x, a.y, a.z);
gl.glVertex3d(b.x, b.y, b.z);
gl.glVertex3d(c.x, c.y, c.z);
gl.glVertex3d(d.x, d.y, d.z);
gl.glVertex3d(a.x, a.y, a.z);
gl.glEnd();
gl.glBegin(GL.GL_LINE_STRIP);
gl.glVertex3d(aa.x, aa.y, aa.z);
gl.glVertex3d(ab.x, ab.y, ab.z);
gl.glVertex3d(ac.x, ac.y, ac.z);
gl.glVertex3d(ad.x, ad.y, ad.z);
gl.glVertex3d(aa.x, aa.y, aa.z);
gl.glEnd();
gl.glBegin(GL.GL_LINES);
gl.glVertex3d(a.x, a.y, a.z);
gl.glVertex3d(aa.x, aa.y, aa.z);
gl.glVertex3d(b.x, b.y, b.z);
gl.glVertex3d(ab.x, ab.y, ab.z);
gl.glVertex3d(c.x, c.y, c.z);
gl.glVertex3d(ac.x, ac.y, ac.z);
gl.glVertex3d(d.x, d.y, d.z);
gl.glVertex3d(ad.x, ad.y, ad.z);
gl.glEnd();
}
private void drawHUD(GL2 gl) {
// TODO Auto-generated method stub
gl.glRasterPos2d(10,10);
gl.glWindowPos2d(10, 10);
gl.glColor3d(0.8, 0.8, 0.8);
GLUT glut = new GLUT();
//DecimalFormat df = new DecimalFormat("#.##");
glut.glutBitmapString(GLUT.BITMAP_8_BY_13,
":");
}
#Override
public void dispose(GLAutoDrawable arg0) {
// TODO Auto-generated method stub
}
#Override
public void init(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
//gl.glOrtho(0,100,-5,25,0,100);
gl.glEnable( GL.GL_LINE_SMOOTH );
gl.glHint( GL.GL_LINE_SMOOTH_HINT, GL.GL_NICEST );
}
#Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
int arg4) {
// TODO Auto-generated method stub
}
private void drawAxis(GL2 gl) {
gl.glLineWidth((float) 1.0);
gl.glBegin(GL.GL_LINES);
// X
gl.glColor3f(1, 0, 0);
gl.glVertex3d(0,0,0);
gl.glVertex3d(1,0,0);
// Y
gl.glColor3f(0, 1, 0);
gl.glVertex3d(0,0,0);
gl.glVertex3d(0,1,0);
// Z
gl.glColor3f(0, 0, 1);
gl.glVertex3d(0,0,0);
gl.glVertex3d(0,0,1);
gl.glEnd();
}
private void setCamera(GL2 gl,GLU glu)
{
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(120, 1.0, 5, 100);
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
gl.glLoadIdentity();
glu.gluLookAt(camX, camY, camZ,
0.0,0.0 ,0.0 ,
0.0,0.0, 1.0);
gl.glRotated(0.0+index, 0, 0, 1);
// gl.glTranslated(MAX_X-MIN_X, MAX_Y-MIN_Y, MAX_Z-MIN_Z);
}
//############################################
// KEY LISTENER INTERFACE
//############################################
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == 27)
System.exit(0);
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Lorenz.java
import javax.vecmath.*;
import java.awt.geom.;
import java.util.;
public class Lorenz {
public static final double rho = 28.0;
public static final double sigma = 10.0;
public static final double beta = 8.0/3.0;
private static final double step = 200.0;
public LinkedList<Point3d> myPoints = null;
public Lorenz ()
{
myPoints = new LinkedList<Point3d>();
Point3d first = new Point3d(0.1,0.1,0.1);
myPoints.add(first);
}
public void step()
{
System.out.println("stepping..."+myPoints.size());
Point3d last = myPoints.get(myPoints.size()-1);
double dx = (sigma * (last.y - last.x))/step;
double dy = ((last.x*(rho-last.z))-last.y)/step;
double dz = ((last.x*last.y - beta*last.z))/step;
Point3d next = new Point3d(last.x+dx,last.y+dy,last.z+dz);
myPoints.add(next);
}
public void doSteps(int count)
{
for (int i = 0; i < count; i++)
{
step();
}
}
public void dump()
{
System.out.println(myPoints.toString());
}
}
Phil
Try creating multiple VBOs for your set of lines. That way you only have to update a smaller number of vertices for each new line and the bulk of your geometry is already (probably) in video memory.
this may sound funny but try to remove the System.out.println() in the step() method. Printing to console is fairly slow/unpredictable in java so don't do this every frame.
to answer your question:
2) VBOs are fast for large(er) datasets and best used with rarely or partly updating data. They can represent any primitive you like, triangles, line strips etc. Adding one vertex every frame is not a good idea since they are allocated statically. You can still use them by predicting the maximum amount of vertices you would like to render and simply allocate this buffer a-priory.
if you decide to use VBOs you will have to make this changes:
- allocate a VBO which will determine the max amount of vertices of the graph
- upload only the new vertices per frame
- stop at max or think about a ringbuffer, but you will probably need an additional buffer used as indexbuffer to implement this
tipp: use JOGL's debug pipeline, it will try to throw an exception as soon as OpenGL sets an error code. This will may help to fix the crash issue you mentioned.
http://michael-bien.com/mbien/entry/jogl_2_composeable_pipline
Related
I want to take user input to get the radius value and use that to create a circle in java opengl (jogl). The radius variable name is rx. However, when i try to take the input in main(), the variable is not recognized anywhere else. I cannot take the input outside this function either. But when i manually assign a value to rx(radius), the code works fine. What should i do?
package rrassi2;
import java.awt.Frame;
import java.util.Scanner;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.glu.GLU;
public class ellipse implements GLEventListener{
/**
* #param args
*/
int pntX1 = 70, pntY1=50, ry=50;
private GLU glu;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner bucky = new Scanner(System.in);
int rx = bucky.nextInt();
bucky.close();
GLProfile glp = GLProfile.get(GLProfile.GL2);
GLCapabilities cap = new GLCapabilities(glp);
GLCanvas canvas = new GLCanvas(cap);
Frame frame = new Frame("Assignment1");
frame.setSize(1200, 800);
frame.add(canvas);
frame.setVisible(true);
ellipse l = new ellipse();
canvas.addGLEventListener(l);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent arg0) {
// TODO Auto-generated method stub
System.exit(0);
}});
}
public void display(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
gl.glClear (GL2.GL_COLOR_BUFFER_BIT);
//gl.glColor3f (0.0f, 0.0f, 0.0f);
gl.glPointSize(1.0f);
midPointCircleAlgo(gl);
gl.glFlush ();
}
public void dispose(GLAutoDrawable arg0) {
// TODO Auto-generated method stub
}
public void init(GLAutoDrawable gld) {
// TODO Auto-generated method stub
GL2 gl = gld.getGL().getGL2();
glu = new GLU();
gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
gl.glColor3f(0.0f, 0.0f, 0.0f);
gl.glPointSize(4.0f);
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
void plot(GL2 gl,int x, int y)
{
gl.glBegin(GL2.GL_POINTS);
gl.glVertex2i(x+pntX1, y+pntY1);
gl.glEnd();
}
void midPointCircleAlgo(GL2 gl)
{
int x = 0;
int y = ry;
float decision = ry^2-rx^2*ry+((rx^2)/4);
plot(gl, x, y);
while(! ((2*(ry^2)*x )> (2*(rx^2)*y)))
{
if (decision < 0)
{
x++;
decision += (2*(ry^2)*x)+ry^2 ;
}
else
{
y--;
x++;
decision +=(2*(ry^2)*x)-(2*(ry^2)*y)+ry^2;
}
plot(gl,x, y);
plot(gl, -x, y);
plot (gl, x,-y);
plot (gl, -x, -y);
}
double decision2 = (((ry^2)*((x+0.5)*(x+0.5)))-((rx^2)*(ry^2))+((rx^2)*((y-1)^2)));
plot(gl, x, y);
while(y> 0)
{
if (decision2 > 0)
{
y--;
decision2 += -(2*(rx^2)*y)+rx^2 ;
}
else
{
y--;
x++;
decision2 +=(2*(ry^2)*x)-(2*(rx^2)*y)+rx^2;
}
plot(gl,x, y);
plot(gl, -x, y);
plot (gl, x,-y);
plot (gl, -x, -y);
}
}
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
int arg4) {
// TODO Auto-generated method stub
}
}
Either create a static int rx above the main function
static int rx;
int pntX1 = 70, pntY1=50, ry=50;
private GLU glu;
public static void main(String[] args) {
// your code here
rx = bucky.nextInt();
// your code here
}
Or add a method to your class ellipse:
int pntX1 = 70, pntY1=50, ry=50;
int rx; // <-------------- Note this new line here
private GLU glu;
public static void main(String[] args) {
// your code here
ellipse l = new ellipse();
l.readRadius();
// your code here
}
public void readRadius() {
Scanner bucky = new Scanner(System.in);
this.rx = bucky.nextInt();
bucky.close();
}
Note the static keyword in
public static void main(String[] args)
In a static method you can only assign values to variables that also have the static keyword:
static int myAwesomeNumber;
int myOtherNumber;
static void myMethod() {
myAwesomeNumber = 123; // this works
myOtherNumber = 789 // this does not work
}
void myOtherMethod() {
myAwesomeNumber = 123; // this works
myOtherNumber = 789 // this works aswell because the method is not static
}
I want in my game to draw houses (huis = house) that fall continuesly at the sides of the screen. (On the grass as the 'world' moves downwards.'
But,having this code, and no trouble in the logcat i dont know why it doesnt draw the houses.
The 'main flow' of this code goes as follows: I created an arraylist that holds the house.png. Then through a for loop it adds a house when there is some space between it.
package com.mygdx.Papermadness;
import java.util.ArrayList;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureWrap;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
public class Papermadness extends InputAdapter implements ApplicationListener {
private SpriteBatch huisBatch;
private Texture huisTexture;
private SpriteBatch batch;
private Sprite sprite;
private SpriteBatch spriteBatch;
private Sprite huisSprite;
private Texture spriteTexture;
private float scrollTimer = 0.0f;
private float huisVelocity = 200f;
private float huisLinksY = 2100;
private float huisLinksX = 0;
private float huisRechtsY = 2100;
private float huisRechtsX = 903;
private Sprite huis;
private ArrayList<Sprite> huisArray = new ArrayList<Sprite>();
Rectangle bounds;
Player player;
Paper paper;
ShapeRenderer sr;
#Override
public void create() {
player = new Player(new Vector2(50, 100), new Vector2(100, 100));
paper = new Paper(new Vector2(Gdx.input.getX(),Gdx.graphics.getHeight()-Gdx.input.getY()), new Vector2(50, 50));
sr = new ShapeRenderer();
spriteBatch = new SpriteBatch();
huisBatch = new SpriteBatch();
huisTexture = new Texture("huis.png");
huisSprite = new Sprite(huisTexture);
spriteTexture = new Texture("b2.png");
spriteTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
sprite = new Sprite(spriteTexture);
sprite.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch = new SpriteBatch();
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
float delta = Gdx.graphics.getDeltaTime();
scrollTimer += Gdx.graphics.getDeltaTime();
if (scrollTimer > 2f)
scrollTimer = 0.0f;
sprite.setV(scrollTimer + 2);
sprite.setV2(scrollTimer);
player.update();
paper.update();
spriteBatch.begin();
sprite.draw(spriteBatch);
for (int i = 0; i < huisArray.size(); i++) {
huisArray.get(i).setY(huisArray.get(i).getY() - huisVelocity * delta);
if (huisArray.get(i).getY() <= 200) {
huisArray.remove(i);
i--;
}
}
if (huisArray.size() > 0 && huisArray.get(0).getY() < 1200) {
addNewHuis();
}
huisBatch.begin();
for (int i = 0; i < huisArray.size(); i++) {
huisBatch.draw(huisArray.get(i), huisArray.get(i).getX(), huisArray.get(i).getY());
}
huisLinksY -= huisVelocity * delta;
huisRechtsY -= huisVelocity * delta;
batch.begin();
player.draw(batch);
paper.draw(batch);
batch.end();
sr.begin(ShapeType.Filled);
sr.setColor(Color.BLUE);
sr.setColor(Color.RED);
sr.setColor(Color.YELLOW);
sr.rect(Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY(), paper.getSize().x,
paper.getSize().y);
sr.end();
}
private void addNewHuis() {
huis = new Sprite();
huis.setY(1800);
huisArray.add(0, huis);
}
#Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
#Override
public void resume() {
// TODO Auto-generated method stub
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
}
Any help would be appreciated.
From my point of view, your house array is empty - so it does not have anything to draw. You create huisArray, but you do not add anything to it. So when you render() is called first, huisArray.size() == 0 is true.
for (int i = 0; i < huisArray.size(); i++) { //you do not step into this piece of code.
huisArray.get(i).setY(huisArray.get(i).getY() - huisVelocity * delta);
if (huisArray.get(i).getY() <= 200) {
huisArray.remove(i);
i--;
}
}
Then, you want to add a house if there are some houses there. But it's still empty so you do not add anything.
if (huisArray.size() > 0 && huisArray.get(0).getY() < 1200) {
addNewHuis();
}
And you attempt to draw still empty array:
huisBatch.begin();
for (int i = 0; i < huisArray.size(); i++) { //you do not step into this piece of code either
huisBatch.draw(huisArray.get(i), huisArray.get(i).getX(), huisArray.get(i).getY());
}
Solution: Add one-two huisSprite to huisArray in create().
Hope it helps :)
I am trying to move a circle in a straight line. But my Code is not giving expected results. I m using mouseMotionListener to constantly get the target points and x_pos and y_pos are co-ordinated for my circle. I am using trigonometric function sin cos and atan, to move the object in straight line --its a logic i have seen here from a question posted on stack overflow--
but it is not giving me the expected results, am i doing something wrong plz help:
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import java.awt.*;
import javax.swing.*;
public class Snake extends JPanel {
static Snake snake = new Snake();
static Co_Ordinates co = new Co_Ordinates();
static int x_pos = 10, y_pos = 500;
static int slope;
int delta_x,delta_y;
double direction;
double x_inc,y_inc;
public Snake() {
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d=(Graphics2D)g;
g2d.setColor(Color.green);
g2d.fillArc(x_pos, y_pos, 20, 20, 0, 360);
try {
Thread.sleep(10);
} catch (Exception e) {
}
/*if(x_pos==co.x_Cur){
if(co.y_Cur>=y_pos)
y_pos++;
else if(co.y_Cur<=y_pos)
y_pos--;
}
else if(y_pos==co.y_Cur){
if(co.x_Cur>=x_pos)
x_pos++;
else if(co.x_Cur<=x_pos)
x_pos--;
}
*/
//slope=((co.y_Cur - y_pos) / (co.x_Cur - x_pos));
//y_pos = slope*x_pos+y_pos;
//x_pos++;
//System.out.println("...");
if(x_pos!=co.x_Cur&&y_pos!=co.y_Cur){
int delta_x = co.x_Cur - x_pos;
int delta_y = co.y_Cur - y_pos;
direction = Math.atan(delta_y / delta_x); // Math.atan2(deltaY, deltaX) does the same thing but checks for deltaX being zero to prevent divide-by-zero exceptions
double speed = 5.0;
x_inc = (speed * Math.cos(direction));
y_inc = (speed * Math.sin(direction));
x_pos+=x_inc;
y_pos+=y_inc;
}
//x_pos = co.x_Cur;
repaint(10);// parameters
}
public void move() {
}
public static void main(String args[]) {
JFrame jf = new JFrame();
jf.add(co);
jf.addMouseMotionListener(co);
jf.addMouseListener(co);
jf.add(snake);
jf.setSize(600, 600);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}
}
class Co_Ordinates extends JPanel implements MouseMotionListener, MouseListener {
static int slope;
static Snake sn = new Snake();
static int x_Cur=sn.x_pos-20;
static int y_Cur=sn.y_pos-40;
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
x_Cur = e.getX() - 20;
y_Cur = e.getY() - 40;
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}// Class Listener ends here
In the code where you used Math.atan should be changed to Math.atan2.
atan only gives angle values between -90deg and 90deg.
atan2 gives angle values between -180deg and 180deg.
I have modified that part of the code as below.
First, change atan to atan2
Second, make the speed become zero if the circle meets the mouse pointer (the target?)
Third is a minor one but, you don't need the if-condition unless performance is critical.
Please try with this one.
// if(x_pos!=co.x_Cur&&y_pos!=co.y_Cur){
delta_x = co.x_Cur - x_pos;
delta_y = co.y_Cur - y_pos;
direction = Math.atan2(delta_y, delta_x);
double speed = Math.sqrt(delta_x*delta_x + delta_y*delta_y);
speed = Math.min(speed, 5.0);
x_inc = (speed * Math.cos(direction));
y_inc = (speed * Math.sin(direction));
x_pos+=x_inc;
y_pos+=y_inc;
//}
How do you add movement event to the sprite?
I really do not know how to use input events i have checked out tons of different links on this website and the others and none have really helped. I need someone to explain and help me out with this please.
package com.KDevs.test;
import java.util.Random;
import java.util.Vector;
import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.modifier.IEntityModifier;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.sprite.Sprite;
import org.andengine.extension.physics.box2d.PhysicsConnector;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.ui.activity.BaseGameActivity;
import android.hardware.SensorManager;
import android.util.Log;
import android.view.MotionEvent;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.FixtureDef;
public class Main extends BaseGameActivity {
Random rand;
Scene scene;
int x , y;
protected static final int CAMERA_WIDTH = 800;
protected static final int CAMERA_HEIGHT = 480;
BitmapTextureAtlas playerTexture;
ITextureRegion playerTexureRegion;
BitmapTextureAtlas blockTexture;
ITextureRegion blockTexureRegion;
BitmapTextureAtlas ZeusTexture;
ITextureRegion ZeusTexureRegion;
PhysicsWorld physicsWorld;
Sprite sPlayer;
Sprite block;
#Override
public EngineOptions onCreateEngineOptions() {
// TODO Auto-generated method stub
Camera mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
EngineOptions options = new EngineOptions(true,
ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(
CAMERA_WIDTH, CAMERA_HEIGHT), mCamera);
return options;
}
#Override
public void onCreateResources(
OnCreateResourcesCallback pOnCreateResourcesCallback)
throws Exception {
// TODO Auto-generated method stub
loadGfx();
// resource
pOnCreateResourcesCallback.onCreateResourcesFinished();
}
private void loadGfx() {
// TODO Auto-generated method stub
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
ZeusTexture = new BitmapTextureAtlas(getTextureManager(), 64, 64);
ZeusTexureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(ZeusTexture, this, "zeus.png", 0, 0);
ZeusTexture.load();
// width and height power of 2^x
playerTexture = new BitmapTextureAtlas(getTextureManager(), 64, 64);
playerTexureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(playerTexture, this, "player.png", 0, 0);
playerTexture.load();
blockTexture = new BitmapTextureAtlas(getTextureManager(), 64, 256);
blockTexureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(blockTexture, this, "block.png", 0, 0);
blockTexture.load();
}
#Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)
throws Exception {
// TODO Auto-generated method stub
this.scene = new Scene();
this.scene.setBackground(new Background(0, 0, 0));
physicsWorld = new PhysicsWorld(new Vector2(0,SensorManager.GRAVITY_MARS), false);
this.scene.registerUpdateHandler(physicsWorld);
pOnCreateSceneCallback.onCreateSceneFinished(this.scene);
}
#Override
public void onPopulateScene(Scene pScene,
OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
int counter = 0 , timer = 0;
int x2 , y2;
counter++;
x =CAMERA_WIDTH /2;
y = 416;
x2 = 300;
y2= -40;
//if(counter % 100 == 0){
//x++;
//timer++;
//}
rand = new Random();
int area = rand.nextInt(800);
//Player
sPlayer = new Sprite(x, y,
playerTexureRegion, this.mEngine.getVertexBufferObjectManager());
scene.registerTouchArea(sPlayer);
scene.setTouchAreaBindingOnActionDownEnabled(true);
scene.setTouchAreaBindingOnActionMoveEnabled(true);
//Block
block = new Sprite(x2 , y2,
blockTexureRegion, this.mEngine.getVertexBufferObjectManager());
//Zeus Sprite
Sprite zeus = new Sprite(CAMERA_WIDTH/2 , 11,
ZeusTexureRegion, this.mEngine.getVertexBufferObjectManager());
//sPlayer.setRotation(45.0f);
//I knew this shit would be helpful
block.setRotation(90.0f);
FixtureDef PLAYERBlock = PhysicsFactory.createFixtureDef(5.0f, 0.0f, 0.0f);
Body body = PhysicsFactory.createCircleBody(physicsWorld, block, BodyType.DynamicBody, PLAYERBlock);
this.scene.attachChild(sPlayer);
this.scene.attachChild(block);
this.scene.attachChild(zeus);
physicsWorld.registerPhysicsConnector(new PhysicsConnector(block, body,true,false));
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction==MotionEvent.ACTION_DOWN){
Log.e("Touching", "Touching the Screen");
}
else if(event.getAction==MotionEvent.ACTION_UP){
Log.e("Touching up", "Touching the Screen up");}
return true;
}
}
First of all I would extend from SimpleBaseGameActivity.
You need to override onAreaTouch method of a sprite object. This way:
Sprite sprite = new Sprite(x, y, texture, this.getVertexBufferObjectManager()) {
public boolean onAreaTouched(org.andengine.input.touch.TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY)
{
//<DO ANYTHING this.setPosition(x,y) method to move the sprite>
this.setPosition(this.getX() + 10 , this.getY() + 10);
return true;
};
};
scene.setTouchAreaBindingOnActionDownEnabled(true);
scene.registerTouchArea(sprite);
I've created a basic Java program that creates a rectangle on startup and every time it is clicked, the rectangle grows and changes to a different (random) color. here's my code:
package rectPAK;
import javax.swing.JFrame;
public class DisplayRect {
public static void main(String[] args) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(0,0,1000,1000);
window.getContentPane().add(new MyCanvas());
window.setVisible(true);
}
}
and then myCanvas is this:
package rectPAK;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Random;
import javax.swing.JComponent;
public class MyCanvas extends JComponent{
int W = 100;
int H = 100;
int r;
int g;
int b;
int trans;
int maxRandNum = 255;
int xPoint;
int yPoint;
public MyCanvas() {
this.addMouseListener(m);
this.addMouseMotionListener(ml);
}
Random rand = new Random();
MouseListener m = new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
W = W + 20;
H = H + 20;
r = rand.nextInt(maxRandNum);
g = rand.nextInt(maxRandNum);
b = rand.nextInt(maxRandNum);
trans = rand.nextInt(maxRandNum);
repaint();
}
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
};
MouseMotionListener ml = new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent e) {
Point p = e.getLocationOnScreen();
xPoint = p.x;
yPoint = p.y;
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
};
public void paint(Graphics gr) {
gr.setColor(Color.BLACK);
gr.drawRect(xPoint, yPoint, W, H);
gr.setColor(new Color(r,g,b,trans));
gr.fillRect(xPoint, yPoint, W, H);
}
}
now my question is this: how do i make it so that when i right-click on the rectangle, it reverts to the previous size and color? i Know it's a lot to ask, but i cant find anything about it...
Thanks a lot.
Use a set of "previous" variables (eg previousX, previousY, previousR, etc) to store the old info before every update, and create a right click event to call a method like your paint method to set the object's variables to previousX, previousY, etc.
Every time you generate a random number, store it as the previous instance. This way you will be able to go back one step. If you want to go back all the way to the first one, then you should store each created rectangle's parameters in an stack of sorts, where you could pop out each previous stage.
Once that is done you should create a method for handling right clicks, and in that method, you should set the rectangles parameters to the previous value.