Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (580)
games submitted by our members
Games in WIP (500)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [Solved]Having trouble with drawing the right way (Top-Down Tile Game)  (Read 1644 times)
0 Members and 1 Guest are viewing this topic.
Offline hapsburgabsinth

Senior Newbie





« Posted 2011-11-30 14: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! Smiley


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;
            //Draw tiles
           Tile tile = this.game.getTileMap().getTileAt(position);
            if(tile != null){
               image = tile.getImage();
            }else{
               tile = new Tile(position, "WATER");
               image = tile.getImage();
            }

            //Draw items
           Item item = this.game.getTileMap().getItemAt(position);
            if(item != null){
               image = item.getImage();
            }

            //Draw buildings
           Building building = this.game.getTileMap().getBuildingAt(position);
            if(building != null){
               image = building.getImage();
            }

            //Draw units
           Unit unit = this.game.getTileMap().getUnitAt(position);
            if(unit != null){
               image = unit.getImage();
               yOffset = -40; //Unit height
           }
           
            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);
   }
}
Offline steveyO
« Reply #1 - Posted 2011-11-30 14: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..

https://play.google.com/store/apps/details?id=com.bullsquared.alggame Annoying Little Gits (Android)
www.bullsquared.com   Play java (applet) games! www.chessclockpro.com Free Online Chess Clock
Offline hapsburgabsinth

Senior Newbie





« Reply #2 - Posted 2011-11-30 14:32:55 »

Can you specify, I don't quite understand what you mean Smiley

Also found out that I should use a canvas and not a JPanel to draw on, but it didn't help though.... Sad
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline theagentd
« Reply #3 - Posted 2011-11-30 15:11:00 »

Quote
1  
bbg.fillRect(0, 580, 800, 20);
Don't fill 800*20 * 24*42 = 16 128 000 pixels per update?

Myomyomyo.
Offline delt0r

JGO Coder


Medals: 22


Computers can do that?


« Reply #4 - Posted 2011-11-30 15: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
Offline hapsburgabsinth

Senior Newbie





« Reply #5 - Posted 2011-11-30 15: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();

         // Draw on the image
        g2d.setColor(Color.red);
         g2d.fill(new Ellipse2D.Float(0, 0, 20, 20));
         g2d.dispose();
      }
      return image;
   }
Offline Lordpomeroy

Junior Member


Medals: 1
Projects: 1



« Reply #6 - Posted 2011-11-30 15:55:40 »

There you find the problem: You are loading your image everytime.
Offline hapsburgabsinth

Senior Newbie





« Reply #7 - Posted 2011-11-30 15:56:27 »

Quote
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? Tongue
Offline delt0r

JGO Coder


Medals: 22


Computers can do that?


« Reply #8 - Posted 2011-11-30 16: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
Offline hapsburgabsinth

Senior Newbie





« Reply #9 - Posted 2011-11-30 16: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!
Legends of Yore - The Casual Retro Roguelike
Offline delt0r

JGO Coder


Medals: 22


Computers can do that?


« Reply #10 - Posted 2011-11-30 16:32:45 »

Are you even reading the posts?

I have no special talents. I am only passionately curious.--Albert Einstein
Offline hapsburgabsinth

Senior Newbie





« Reply #11 - Posted 2011-11-30 16:37:15 »

I can't find the method, that you are referring to Smiley

And I meant loading ONLY the images that I draw into memory Smiley
Offline theagentd
« Reply #12 - Posted 2011-11-30 17:39:39 »

Quote
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? Tongue

Your loops:
1  
2  
for(int y = 0; y < 24; y++){
     for(int x = 0; x < 42; x++){

24*42 times runs.

Quote
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.  Pointing

Myomyomyo.
Offline hapsburgabsinth

Senior Newbie





« Reply #13 - Posted 2011-11-30 17:41:27 »

Ohh I feel stupid, will look into that Tongue Thanks Smiley
Offline hapsburgabsinth

Senior Newbie





« Reply #14 - Posted 2011-11-30 17: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 Smiley
Offline ra4king

JGO Kernel


Medals: 322
Projects: 2
Exp: 4 years


I'm the King!


« Reply #15 - Posted 2011-11-30 19: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.

Offline hapsburgabsinth

Senior Newbie





« Reply #16 - Posted 2011-11-30 19: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 Smiley 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 Smiley

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 Smiley

And thanks to delt0r and Lordpomeroy too Smiley
Offline ra4king

JGO Kernel


Medals: 322
Projects: 2
Exp: 4 years


I'm the King!


« Reply #17 - Posted 2011-11-30 19: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 Wink

Offline hapsburgabsinth

Senior Newbie





« Reply #18 - Posted 2011-11-30 19: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 Smiley

It down to 1-6 time in milliseconds now! Cheesy

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 Smiley
Offline hapsburgabsinth

Senior Newbie





« Reply #19 - Posted 2011-11-30 19: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 Tongue
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (48 views)
2014-04-15 18:08:23

BurntPizza (44 views)
2014-04-15 03:46:01

UprightPath (60 views)
2014-04-14 17:39:50

UprightPath (42 views)
2014-04-14 17:35:47

Porlus (58 views)
2014-04-14 15:48:38

tom_mai78101 (82 views)
2014-04-10 04:04:31

BurntPizza (140 views)
2014-04-08 23:06:04

tom_mai78101 (240 views)
2014-04-05 13:34:39

trollwarrior1 (200 views)
2014-04-04 12:06:45

CJLetsGame (207 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!