hapsburgabsinth
|
 |
«
Posted
2011-11-30 13:17:53 » |
|
I'm having trouble drawing the right way it seems, it takes about 500-800 milliseconds to complete a single loop in my render method. Any suggestions or links that might explain what to do. Can't find anything on the forum, please help!  This is my render code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| public class GamePanel extends Canvas{
private BufferedImage backBuffer; private int windowHeight; private int windowWidth; private ZompocalypseGame game; private GUI gui; private Position position;
public GamePanel(int windowWidth, int windowHeight, ZompocalypseGame sGame, GUI gui){ setIgnoreRepaint(true); this.windowWidth = windowWidth; this.windowHeight = windowHeight; setVisible(true); this.game = sGame; this.gui = gui; this.position = new Position(0,0); this.backBuffer = new BufferedImage(this.windowWidth, this.windowHeight, BufferedImage.TYPE_INT_RGB); }
public void draw(){ Graphics2D g = (Graphics2D) getGraphics(); g.setColor(Color.BLACK); g.fillRect(0, 0, windowWidth, windowHeight); g.drawImage(this.backBuffer, 0, 0, this); g.dispose(); }
public void render() { Graphics2D bbg = (Graphics2D) this.backBuffer.getGraphics(); BufferedImage image = null; Player player = this.game.getTileMap().getPlayer();
long foo = System.currentTimeMillis(); for(int y = 0; y < 24; y++){ for(int x = 0; x < 42; x++){ position.setX(x + player.getPosition().getX()-21); position.setY(y + player.getPosition().getY()-12); int yOffset = 0; Tile tile = this.game.getTileMap().getTileAt(position); if(tile != null){ image = tile.getImage(); }else{ tile = new Tile(position, "WATER"); image = tile.getImage(); }
Item item = this.game.getTileMap().getItemAt(position); if(item != null){ image = item.getImage(); }
Building building = this.game.getTileMap().getBuildingAt(position); if(building != null){ image = building.getImage(); }
Unit unit = this.game.getTileMap().getUnitAt(position); if(unit != null){ image = unit.getImage(); yOffset = -40; } bbg.drawImage(image, x*20, y*20+yOffset, this); bbg.setColor(Color.WHITE); bbg.fillRect(0, 580, 800, 20); bbg.setColor(Color.BLACK); bbg.drawString(String.valueOf(gui.getFps()), 10, 595); } } long bar = System.currentTimeMillis(); System.out.println(bar - foo); } } |
|
|
|
|
steveyO
|
 |
«
Reply #1 - Posted
2011-11-30 13:30:31 » |
|
Haven't really looked at the code but at a glance would suggest to create your background image outside your main loop,and in your main loop simply render your 'already created image' background..
|
|
|
|
hapsburgabsinth
|
 |
«
Reply #2 - Posted
2011-11-30 13:32:55 » |
|
Can you specify, I don't quite understand what you mean  Also found out that I should use a canvas and not a JPanel to draw on, but it didn't help though.... 
|
|
|
|
Games published by our own members! Check 'em out!
|
|
theagentd
|
 |
«
Reply #3 - Posted
2011-11-30 14:11:00 » |
|
1
| bbg.fillRect(0, 580, 800, 20); |
Don't fill 800*20 * 24*42 = 16 128 000 pixels per update?
|
Myomyomyo.
|
|
|
delt0r
|
 |
«
Reply #4 - Posted
2011-11-30 14:23:16 » |
|
well the only thing i can see that would make it slow is the image format. Create your bufferedImage with GraphicsDevice.createCompatableImage();. Any colour space/format conversions fall back to a really slow software renderer.
In fact you should copy all your images onto a compatible image. For example using ImageIO to load a jpg will return a BufferedImage in a YCrCb or whatever colour space in some cases.
|
I have no special talents. I am only passionately curious.--Albert Einstein
|
|
|
hapsburgabsinth
|
 |
«
Reply #5 - Posted
2011-11-30 14:51:18 » |
|
I already use ImageIO, but it's in the tile class, and I use .png This is the code I use in Tile.class: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public BufferedImage getImage() { BufferedImage image = null; try{ image = ImageIO.read(new File("bin/image/tile/" + this.type + ".png")); }catch (Exception e) { System.out.println("Couldn't find " + this.type + "'s image file!"); } if(this.isTargeted){ Graphics2D g2d = image.createGraphics();
g2d.setColor(Color.red); g2d.fill(new Ellipse2D.Float(0, 0, 20, 20)); g2d.dispose(); } return image; } |
|
|
|
|
Lordpomeroy
|
 |
«
Reply #6 - Posted
2011-11-30 14:55:40 » |
|
There you find the problem: You are loading your image everytime.
|
|
|
|
hapsburgabsinth
|
 |
«
Reply #7 - Posted
2011-11-30 14:56:27 » |
|
1
| bbg.fillRect(0, 580, 800, 20); |
Don't fill 800*20 * 24*42 = 16 128 000 pixels per update? Where do you get that calculation from? 
|
|
|
|
delt0r
|
 |
«
Reply #8 - Posted
2011-11-30 15:11:18 » |
|
My point wasn't to use ImageIO. But that ImageIO will often use a incompatible image format from the device. So that draw image will result in a colour translation per pixel rather than just a mem copy of the data to the video memory.
|
I have no special talents. I am only passionately curious.--Albert Einstein
|
|
|
hapsburgabsinth
|
 |
«
Reply #9 - Posted
2011-11-30 15:17:21 » |
|
There you find the problem: You are loading your image everytime.
Now I load the image in the constructor, and it got better, down at 200+ milliseconds, but not quite the time i hoped for... Was aiming for 16 milliseconds (to reach 60 fps)... would it help to only load into memory the images that I draw? If so, how would I do such a thing?
|
|
|
|
Games published by our own members! Check 'em out!
|
|
delt0r
|
 |
«
Reply #10 - Posted
2011-11-30 15:32:45 » |
|
Are you even reading the posts?
|
I have no special talents. I am only passionately curious.--Albert Einstein
|
|
|
hapsburgabsinth
|
 |
«
Reply #11 - Posted
2011-11-30 15:37:15 » |
|
I can't find the method, that you are referring to  And I meant loading ONLY the images that I draw into memory 
|
|
|
|
theagentd
|
 |
«
Reply #12 - Posted
2011-11-30 16:39:39 » |
|
1
| bbg.fillRect(0, 580, 800, 20); |
Don't fill 800*20 * 24*42 = 16 128 000 pixels per update? Where do you get that calculation from?  Your loops: 1 2
| for(int y = 0; y < 24; y++){ for(int x = 0; x < 42; x++){ |
24*42 times runs. 1
| bbg.fillRect(0, 580, 800, 20); |
Fills a rectangle 800x20 pixel rectangle at (0, 580). This is done ONCE FOR EACH LOOP = 24*42 times * 800*20 pixels. Why are you filling a that big rectangle for each tile AT THE SAME PLACE every loop? My post was supposed to make you notice that. 
|
Myomyomyo.
|
|
|
hapsburgabsinth
|
 |
«
Reply #13 - Posted
2011-11-30 16:41:27 » |
|
Ohh I feel stupid, will look into that  Thanks 
|
|
|
|
hapsburgabsinth
|
 |
«
Reply #14 - Posted
2011-11-30 16:53:23 » |
|
Just to make things anymore cryptic (for me especially), when I move around, the time it takes to do the loop is going towards 16 (as I want).... Still having 200+ in the start though o.O I really can't figure this out myself, my knowledge on this area isn't enough 
|
|
|
|
ra4king
|
 |
«
Reply #15 - Posted
2011-11-30 18:30:31 » |
|
This is how you create a compatible image (lines 101-113).As others have pointed out: - Try to do as little drawing calls as possible, Java2D is quite slow. - Don't load images in your loop - Try to create as little number of objects in your loop - Find better ways than using lots of for loops EDIT: I took a good look at your render() method: - I believe theagentd pointed out, don't fillRect 24*24 times! This should only be done once and on the whole image. - Why are you drawing the FPS 24*24 times?! This should also be done once and at the end of your render() method.
|
|
|
|
hapsburgabsinth
|
 |
«
Reply #16 - Posted
2011-11-30 18:35:54 » |
|
This is how you create a compatible image (lines 101-113).As others have pointed out: - Try to do as little drawing calls as possible, Java2D is quite slow. - Don't load images in your loop - Try to create as little number of objects in your loop - Find better ways than using lots of for loops Thanks again a lot  I just found out, that if I don't have any null tiles on my screen it only takes 1-7 milliseconds to draw, so it must be something with the null tiles I draw... Just have to figure out how to solve that problem  Would need to make my player go off center when he reaches the edge of the world..... But I will look into the link you posted  And thanks to delt0r and Lordpomeroy too 
|
|
|
|
ra4king
|
 |
«
Reply #17 - Posted
2011-11-30 18:38:36 » |
|
If the Tile is null, you create a new Tile object, which means.......what is in your Tile constructor? Looks like you are loading the "WATER" image every time 
|
|
|
|
hapsburgabsinth
|
 |
«
Reply #18 - Posted
2011-11-30 18:44:47 » |
|
You're having a point there... Even though I fixed that.... But it works after I just created a null tile, and just using that tiles image  It down to 1-6 time in milliseconds now!  I'm so happy, have been working on those two problems I've posted to day for like a month!!!! Gave an appreciate to everyone who helped 
|
|
|
|
hapsburgabsinth
|
 |
«
Reply #19 - Posted
2011-11-30 18:47:45 » |
|
Of cause, now I see the problem... The problem was that I created a new tile if the tile was null, and in the constructor I loaded the image 
|
|
|
|
|