Hello guys, I’m just over a week learning Java and for some crazy reason I am learning Java2D(which is weird since I’ve been coding in OpenGL for years now and have developed an OpenGL framework http://rel.phatcode.net/junk.php?id=133 )
Anyways, here’s the source and binary for the Java2D framework:
http://rel.phatcode.net/junk.php?id=131
Somehow disabling sprite transparency by composition speeds things up quite a bit. Any thoughts on why that happens or any way to speed things up?
Does Java2D do stuff in software via GDI?
Thanks!
Java2DFramework.java
import javax.swing.JFrame;
public class Java2DFramework extends JFrame
{
private static final long serialVersionUID = 1L;
public Java2DFramework()
{
add( new Screen() );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
setSize( Globals.SCREEN_WIDTH, Globals.SCREEN_HEIGHT );
setLocationRelativeTo( null );
setTitle( "Relminator's Java 2D Framework" );
setResizable( false );
setVisible( true );
}
public static void main(String[] args)
{
new Java2DFramework();
}
}
screen.java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.Font;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.Dimension;
import java.awt.BasicStroke;
import java.awt.geom.*;
import java.awt.AlphaComposite;
import javax.swing.JPanel;
public class Screen extends JPanel implements Runnable
{
private static final long serialVersionUID = 1L;
private Thread animator;
private double accumulator = 0;
private int fps = 0;
private int framesPerSecond = 0;
private double previousTime = 0;
private double oldTime = 0;
private double secondsElapsed = 0;
private Starfield stars = new Starfield();
private Picture picture = new Picture();
public Screen()
{
addKeyListener(new TAdapter());
setFocusable(true);
setBackground(Color.BLACK);
setDoubleBuffered(true);
}
public void addNotify()
{
super.addNotify();
animator = new Thread( this );
animator.start();
}
public void paint( Graphics g )
{
super.paint(g);
Graphics2D g2D = (Graphics2D)g;
render( g2D );
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
private class TAdapter extends KeyAdapter
{
public void keyReleased( KeyEvent e )
{
picture.keyReleased( e );
}
public void keyPressed( KeyEvent e )
{
picture.keyPressed( e );
}
}
public void update()
{
stars.update();
picture.move();
repaint();
}
public void render( Graphics2D g2D )
{
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f);
g2D.setComposite(ac);
g2D.setFont(new Font("Courier New", Font.BOLD, 24));
g2D.setColor( Color.BLUE );
g2D.drawString( "FPS :" + fps, 0, 24 );
stars.render( g2D, secondsElapsed );
Dimension size = getSize();
double w = size.getWidth();
double h = size.getHeight();
Rectangle2D e = new Rectangle2D.Double(-10, -10, 20, 20);
g2D.setStroke(new BasicStroke(1));
double hw = w/2;
double hh = h/2;
double scale = 0;
float color = 0;
double posX = hw + ( Math.cos(secondsElapsed * 0.5) + Math.sin(secondsElapsed * 1.25) ) * hw/2;
double posY = hh + ( Math.sin(secondsElapsed * 2.5) + Math.sin(secondsElapsed * 0.25) ) * hh/2;
for( int deg = 0; deg < (360*4); deg += 25)
{
AffineTransform at = AffineTransform.getTranslateInstance( posX, posY );
at.rotate( Math.toRadians(deg * 5 + secondsElapsed * 150) );
at.scale( scale + Math.abs(Math.sin(secondsElapsed * 0.9) * 10),
scale + Math.abs(Math.sin(secondsElapsed * 1.5) * 10));
scale += 0.2;
color = (float)Math.abs( Math.sin(secondsElapsed * 2.5 + deg) );
g2D.setColor( new Color(color, 1.0f - color, color/2.0f) );
g2D.draw( at.createTransformedShape(e) );
}
g2D.drawImage( picture.getImage(), picture.getX(), picture.getY(), this );
}
public void run()
{
double dt = getDeltaTime( getSystemTime() );
while( true )
{
dt = getDeltaTime( getSystemTime() );
if( dt > Globals.FIXED_TIME_STEP ) dt = Globals.FIXED_TIME_STEP;
accumulator += dt;
secondsElapsed += dt;
while( accumulator >= Globals.FIXED_TIME_STEP )
{
update();
accumulator -= Globals.FIXED_TIME_STEP;
}
try
{
Thread.sleep(15);
}
catch (InterruptedException e)
{
System.out.println("interrupted");
}
}
}
public double getSystemTime()
{
return System.currentTimeMillis() / (double)1000.0;
}
public double getDeltaTime( double timerInSeconds )
{
double currentTime = timerInSeconds;
double elapsedTime = currentTime - oldTime;
oldTime = currentTime;
framesPerSecond++;
if( (currentTime - previousTime) > 1.0 )
{
previousTime = currentTime;
fps = framesPerSecond;
framesPerSecond = 0;
}
return elapsedTime;
}
}
Starfield.java
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;
public class Starfield
{
private static final int NUMSTARS = 512;
private ArrayList<Star> stars = new ArrayList<Star>();
public Starfield()
{
for( int i = 0; i < NUMSTARS; i++ )
{
Star star = new Star( -Globals.SCREEN_WIDTH/2.0f + (float)Math.random() * Globals.SCREEN_WIDTH/1.0f,
-Globals.SCREEN_HEIGHT/2.0f + (float)Math.random() * Globals.SCREEN_HEIGHT/1.0f,
-(float)Math.random() * 255,
01.f + (float)Math.random() * 2);
stars.add( star );
}
}
public void update()
{
for( int i = 0; i < stars.size(); i++ )
{
Star star = stars.get(i);
star.move();
}
}
public void render( Graphics2D g2D, double secondsElapsed )
{
float color = (float)Math.abs( Math.sin(secondsElapsed * 0.5) );
g2D.setColor( new Color(1.0f - color, color, color) );
for( int i = 0; i < stars.size(); i++ )
{
Star star = stars.get( i );
int sx = star.getScreenX();
int sy = star.getScreenY();
g2D.drawLine( sx, sy, sx, sy );
}
}
} // end class
Star.java
public class Star
{
private float x;
private float y;
private float z;
private float speed;
private float screenX;
private float screenY;
public Star()
{
x = 0;
y = 0;
z = 0;
speed = 0;
}
public Star( float x, float y, float z, float speed )
{
this.x = x;
this.y = y;
this.z = z;
this.speed = speed;
}
public int getScreenX()
{
return (int)screenX;
}
public int getScreenY()
{
return (int)screenY;
}
public float getDistance()
{
return (Globals.LENS - z);
}
public void init( float x, float y, float z, float speed )
{
this.x = x;
this.y = y;
this.z = z;
this.speed = speed;
}
public void move()
{
z += speed;
if( z > Globals.LENS )
{
z = 0;
}
float sx = x;
float sy = y;
float sz = z;
float distance = Globals.LENS - sz;
if( distance > 0 )
{
screenX = Globals.SCREEN_WIDTH/2 + (Globals.LENS * sx / distance);
screenY = Globals.SCREEN_HEIGHT/2 - (Globals.LENS * sy / distance);
}
}
}
Picture.java
import javax.swing.ImageIcon;
import java.awt.Image;
import java.awt.event.KeyEvent;
public class Picture
{
private String fileName = "gfx/fairy.png";
private Image image;
private float x;
private float y;
private float dx;
private float dy;
private float speed = 2.5f;
Picture()
{
ImageIcon ii = new ImageIcon(this.getClass().getResource(fileName));
image = ii.getImage();
x = Globals.SCREEN_WIDTH/2.0f - image.getWidth(null)/2.0f;
y = Globals.SCREEN_HEIGHT/2.0f - image.getHeight(null)/2.0f;
}
public int getX()
{
return (int)x;
}
public int getY()
{
return (int)y;
}
public Image getImage()
{
return image;
}
public void move()
{
x += dx;
y += dy;
}
public void keyPressed( KeyEvent e )
{
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT)
{
dx = -speed;
}
if (key == KeyEvent.VK_RIGHT)
{
dx = speed;
}
if (key == KeyEvent.VK_UP)
{
dy = -speed;
}
if (key == KeyEvent.VK_DOWN)
{
dy = speed;
}
}
public void keyReleased(KeyEvent e)
{
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT)
{
dx = 0;
}
if (key == KeyEvent.VK_RIGHT)
{
dx = 0;
}
if (key == KeyEvent.VK_UP)
{
dy = 0;
}
if (key == KeyEvent.VK_DOWN)
{
dy = 0;
}
}
}
Globals.java
public class Globals
{
public static final double FIXED_TIME_STEP = 1/60.0;
public final static int SCREEN_WIDTH = 640;
public final static int SCREEN_HEIGHT = 480;
public final static int LENS = 256;
}