Please Read - Im stumped

Been working on this game for about 2 months now, i work on it when i get free time between high school and sport etc etc.

Its a 2D Tiles based multiplayer shooter, everything works as it should at this stage, but my FPS is well below what i would like and probably require.

Previous to adding some lighting effects (ill explain later) my FPS was around 50 - 100, for some reason it switched every frame. That was aceptable, but not really great.

my rendering for the above looked like this:

for(int y = 0; y < screenHeight / tileHeight; y++){

for(int x = 0; x < screenWidth / tileWidth; x++){

if(map[y][x] == 0){

g.drawImage(tile, x * tileWidth, y * tileHeight,null);

}

if(map[y][x] == 2){

g.drawImage(tile, x * tileWidth, y * tileHeight,null);

}

if(map[y][x] == 3){

g.drawImage(tile, x * tileWidth, y * tileHeight,null);

}

}

}

Ok g was a graphics object pointing to BufferStrategy.getDrawGraphics();

So yea, im using bufferStrategy.

Now ive added a little effect of the player holding a flashLight which will come in use on dark maps. However to do pixel lighting i need to access the pixels, so i use bufferedImage and infortunately the only way ive found which willl work is this:

BufferedImage tileBuffer;

for(int y = 0; y < screenHeight / tileHeight; y++){

for(int x = 0; x < screenWidth / tileWidth; x++){

if(map[y][x] == 0){

gTile.drawImage(tile, 0, 0,null);

}

if(map[y][x] == 2){

gTile.drawImage(tile,0, 0,null);

}

if(map[y][x] == 3){

gTile.drawImage(tile, 0, 0,null);

}

//Do lighting by creating polygon (triangle) with the mouse co-ords and light neccery pixels if the tile intercepts the polygon.

g.drawImage(tileBuffer, x * 50, y * 50,null);

}

}

gTile is a graphics object pointing to tileBuffer.createGraphics();

I believe this was the reason for my FPS drop, before i only had to draw straight to he bufferStrat but now i hve to draw the tile to a buffferedImage and then the bufferStrat. I've tested and profiled my code and i believe im correct.

Before Lighting FPS: 50 - 100

After Lighting Implemented FPS: 20

Now im gona ask a huge favour, below im going to paste majority of my rendering code, i would be greatly appreciated if you could help me improve my FPS greatly.

I know its a big ask, but please just hve a quick look, it might be something so simple that im just not aware of atm.

Thanks in advance, Nick.

import javax.swing.*;

import java.awt.image.*;

import java.awt.*;

import java.util.*;

publicclass Map{

Rectangle rect;

Color[][] grassColors =new Color[50][50];

Color[][] rockColors =new Color[50][50];

Color[][] skyColors =new Color[50][50];

Color[][] waterColors =new Color[50][50];

int screenWidth = 800;

int screenHeight = 800;

int tileHeight = 50;

int tileWidth = 50;

Graphics2D g;

BufferedImage tile;

BufferedImage tileLight;

int lightPosX;

int lightPosY;

int pointerX;

int pointerY;

int height;

int width;

Color change;

long startTime;

long finnishTime;

double d1;//Distance from mouse to origin

double d2;//Distance from origin to measure point

double d3;//Distance from mouse to measure point

double measurePointX;

double measurePointY;

double angleDeg;

int[] xPoints =newint[3];

int[] yPoints =newint[3];

Polygon flashLight;

double angle = 0;

double angleDiff = .5;

int radius = 175;//Distance light travels

double p1X;

double p1Y;

double p2X;

double p2Y;

int mapX, mapY;

int playerx;

int playery;

WarPanel reference;

Iterator it;

ClientIO io;

//Map

int[][] map ={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,4,2,2,2,4,2,2,2,2,2,4,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},};

//End Map

BufferedImage buffImage;

Image grass;

Image rock;

Image sky;

Image water;

BufferedImage renew;

BufferedImage grassBuffer;

BufferedImage rockBuffer;

BufferedImage skyBuffer;

BufferedImage waterBuffer;

public Map(WarPanel ref, ClientIO c){

io = c;

reference = ref;

renew =new BufferedImage(16 * 50, 16 * 50, BufferedImage.TYPE_INT_ARGB);

buffImage =new BufferedImage(16 * 50, 16 * 50, BufferedImage.TYPE_INT_ARGB);

grass =new ImageIcon("Grass.jpg").getImage();

rock =new ImageIcon("Rock.jpg").getImage();

sky =new ImageIcon("stars.jpg").getImage();

water =new ImageIcon("Water.jpg").getImage();

grassBuffer =new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB );

g = grassBuffer.createGraphics();

g.drawImage(grass, 0, 0,null);

rockBuffer =new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB );

g = rockBuffer.createGraphics();

g.drawImage(rock, 0, 0,null);

skyBuffer =new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB );

g = skyBuffer.createGraphics();

g.drawImage(sky, 0, 0,null);

waterBuffer =new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB );

g = waterBuffer.createGraphics();

g.drawImage(water, 0, 0,null);

//Set Up Lighting

tile =new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB );

g = tile.createGraphics();

getColors();

//Below Darken Tiles

/*

for(int y = 0; y < tile.getHeight(); y++){

for(int x = 0; x < tile.getWidth(); x++){

change = new Color(tile.getRGB(x, y)).darker();

tile.setRGB(x, y, change.getRGB());

}

}

*/

lightPosX = 400;

lightPosY = 400;

measurePointX = lightPosX + 5;

measurePointY = lightPosY;

rect =new Rectangle();

flashLight =new Polygon();

}

publicvoid drawMap(Graphics g2D,int p,int p1,int x,int y){

try{

int offsetX = x;

int offsetY = y;

//Begin Lighting Math

int pointerX = reference.crossHairX;

int pointerY = reference.crossHairY;

d1 = Math.sqrt((pointerX - lightPosX)*(pointerX - lightPosX) + (pointerY - lightPosY)*(pointerY - lightPosY));

d2 = Math.sqrt((measurePointX - lightPosX)*(measurePointX - lightPosX) + (measurePointY - lightPosY)*(measurePointY - lightPosY));

d3 = (pointerX - measurePointX)*(pointerX - measurePointX) + (pointerY - measurePointY)*(pointerY - measurePointY);

angle = -(Math.acos((d1*d1 + d2*d2 - d3)/(2*d1*d2)));

if(pointerY > lightPosY){

angle = 6.283185307 - angle;

}

//Rotating Triangle - This below code snipet was passed to me by kajbj.

angle = angle - .994837674;

p1X = Math.cos(angle) * radius - Math.sin(angle) * radius;

p1Y = Math.sin(angle) * radius + Math.cos(angle) * radius;

p2X = Math.cos(angle+angleDiff) * radius - Math.sin(angle+angleDiff) * radius;

p2Y = Math.sin(angle+angleDiff) * radius + Math.cos(angle+angleDiff) * radius;

//End snipet, thank you kajbj :)

xPoints[0] = lightPosX;

xPoints[1] = (int)p1X + lightPosX;

xPoints[2] = (int)p2X + lightPosX;

yPoints[0] = lightPosY;

yPoints[1] = (int)p1Y + lightPosY;

yPoints[2] = (int)p2Y + lightPosY;

flashLight.reset();

flashLight.addPoint(xPoints[0], yPoints[0]);

flashLight.addPoint(xPoints[1], yPoints[1]);

flashLight.addPoint(xPoints[2], yPoints[2]);

//End Lighting Math

for(int c = y / tileHeight; c <= 16 + ( y / tileHeight) + 1; c++){

for(int r = x / tileWidth; r <= 16 + ( x / tileWidth) + 1; r++){

int xDraw = r * tileWidth - offsetX;

int yDraw = c * tileHeight - offsetY;

if((c > 32)||(c < 0)||(r > 32)||(r < 0)){

//Do nothing

}

else{

if(map[c][r] == 0){

//g2D.drawImage(grass, 0, 0, (int)(50 - xDraw), 0, (int)(-1*xDraw), 0, L, 0, null);

g.drawImage(grassBuffer, 0, 0,null);

//tile = grassBuffer;

}

if(map[c][r] == 1){

g.drawImage(rockBuffer, 0, 0,null);

//tile = rockBuffer;

}

if(map[c][r] == 2){

g.drawImage(rockBuffer,0, 0,null);

//tile = rockBuffer;

}

if(map[c][r] == 4){

g.drawImage(waterBuffer, 0, 0,null);

//tile = waterBuffer;

}

rect.setRect(xDraw, yDraw, 50, 50);

if(flashLight.intersects(rect)){

int pChange = 0;

for(int y1 = 0; y1 < 50; y1 += 2){

int yDist = (y1 + yDraw - lightPosY)*(y1 + yDraw - lightPosY);

for(int x1 = 0; x1 < 50; x1 += 2){

if(flashLight.contains(x1 + xDraw,y1 + yDraw)){

double dSource = (x1 + xDraw - lightPosX)*(x1 + xDraw - lightPosX) + yDist;

change =new Color(tile.getRGB(x1, y1));

int even = pChange % 2;

if(dSource < 30625){

if(dSource > 25600){

if(even == 0){

change = change.brighter();

}

}

else{

change = change.brighter();

}

}

else{

change = change.brighter();

}

if(dSource < 2500){

if(dSource > 625){

if(even == 0){

change = change.brighter();

}

}

else{

change = change.brighter();

}

}

if(dSource < 10000){

if(dSource > 5625){

if(even == 0){

change = change.brighter();

}

}

else{

change = change.brighter();

}

}

if(dSource < 22500){

if(dSource > 15625){

if(even == 0){

change = change.brighter();

}

}

else{

change = change.brighter();

}

}

tile.setRGB(x1, y1, change.getRGB());

pChange += 1;

}//End If polygon contains

}//End For - X

pChange = 0;

}//End For - Y

}//End if intercepts

g2D.drawImage(tile, xDraw, yDraw, 50, 50,null);

//restoreColors(); Killed FPS: 1

}//End Else From First Loop

}//End r

}//End c

if((io.opX >= x) && (io.opY >= y)){

g2D.drawRect(io.opX - reference.imgCropx1, io.opY - reference.imgCropy1, 20, 20);

}

Bullet temp;

int v;

v = 0;

it = reference.bullets.iterator();

while(it.hasNext()){

temp = (Bullet)it.next();

if(((int)temp.bx >= x) && ((int)temp.by >= y)){

g2D.drawOval((int)temp.bx - reference.imgCropx1, (int)temp.by - reference.imgCropy1, 10, 10);

}

v++;

}

it = reference.opBullets.iterator();

while(it.hasNext()){

temp = (Bullet)it.next();

if(((int)temp.bx >= x) && ((int)temp.by >= y)){

g2D.drawOval((int)temp.bx - reference.imgCropx1, (int)temp.by - reference.imgCropy1, 10, 10);

}

v++;

}

}catch(Exception e){System.out.println(e +" Caught"); drawMap(g2D,p,p1, x, y);}

//return buffImage;

}

publicvoid getColors(){

g.drawImage(grass, 0, 0,null);

for(int y = 0; y < tile.getHeight(); y++){

for(int x = 0; x < tile.getWidth(); x++){

grassColors[y][x] =new Color(tile.getRGB(x, y));

}

}

g.drawImage(rock, 0, 0,null);

for(int y = 0; y < tile.getHeight(); y++){

for(int x = 0; x < tile.getWidth(); x++){

rockColors[y][x] =new Color(tile.getRGB(x, y));

}

}

g.drawImage(water, 0, 0,null);

for(int y = 0; y < tile.getHeight(); y++){

for(int x = 0; x < tile.getWidth(); x++){

waterColors[y][x] =new Color(tile.getRGB(x, y));

}

}

g.drawImage(sky, 0, 0,null);

for(int y = 0; y < tile.getHeight(); y++){

for(int x = 0; x < tile.getWidth(); x++){

skyColors[y][x] =new Color(tile.getRGB(x, y));

}

}

}

publicvoid restoreColors(){

for(int y = 0; y < 50; y++){

for(int x = 0; x < 50; x++){

grassBuffer.setRGB(x, y, grassColors[y][x].getRGB());

}

}

/*for(int y = 0; y < 50; y++){

for(int x = 0; x < 50; x++){

rockBuffer.setRGB(x, y, rockColors[y][x].getRGB());

}

}

for(int y = 0; y < 50; y++){

for(int x = 0; x < 50; x++){

waterBuffer.setRGB(x, y, waterColors[y][x].getRGB());

}

}

*/

}

}

[27833 byte] By [NickyP101a] at [2007-10-1 11:55:24]
# 1
You might not want to use a buffered image. If you can extend JPanel, then just put the draw code inside the paint method. JPanel is already double buffered, and it's faster than using a buffered image.There might be other ways.
rkippena at 2007-7-10 13:42:45 > top of Java-index,Other Topics,Java Game Development...