Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (578)
games submitted by our members
Games in WIP (499)
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  
  Rendering and Scale Issue  (Read 391 times)
0 Members and 1 Guest are viewing this topic.
Offline Mizzath

Senior Newbie





« Posted 2012-11-12 05:50:52 »

Good day, me hearties!

Let's get straight to it. I've made a game that's composed of three class files: Game.java, Screen.java, and Map.java.

Game.java: game loop, etc

Screen.java: renders a map

Map: the map

Alright. Pretty basic, eh? Right. That's what I was hoping for.

Issue starts here: THE SCREEN IS SCALED AFTER RENDERING PROCESS COMPLETES IN ORDER TO SAVE CPU POWER.

Not much of a problem, it seems. Well, read on.

In order to calculate the width/height (in pixels) of my tile-map, I simply multiplied the tile size by the width/height in tiles. This would be accurate, but after the scaling (x3), this data is completely wrong. A coordinate before the scaling doesn't represent the same thing it did after the scaling. I implemented a player & camera, not realizing that my coordinate system was entirely nullified, and I began experiencing many issues, such as not being able to calculate when the player reaches the edge of the map.

Keep in mind that the player was a BufferedImage rendered on top of the Screen/Map (also a BufferedImage).

How can I retain this scale and accurately implement a coordinate system? Should I somehow merge the player image into the map image, resulting in both items being scaled? This seems sensible, yet how would I carry it out?

Game.java:

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  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
package com.mizzath.game;

import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;

import javax.swing.JFrame;

import com.mizzath.graphics.*;

public class Game extends Canvas implements Runnable {
   private static final long serialVersionUID = 1L;
   
   int width = 300;
   int height = width / 12 * 9;
   int scale = 3;
   String title = "Game";
   
   boolean running = false;
   
   BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
   int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
   
   JFrame frame;
   Thread thread;
   Screen screen;
   
   Map map;
   
   public Game() {
      frame = new JFrame(title);
     
      map = new Map(64, 64, 16);
      screen = new Screen(width, height, map);
     
      Dimension size = new Dimension(width * scale, height * scale);
     
      setSize(size);

      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setResizable(false);
      frame.add(this);
      frame.pack();
      frame.setVisible(true);
     
      start();
   }
   
   public void run() {
      long start = System.nanoTime();
      long timer = System.currentTimeMillis();
      double period = 1000000000D / 60D;
      double delta = 0;
     
      int updates = 0; // Logic
     int frames = 0;  // Rendering
     
      while(running) {
         long now = System.nanoTime();
         
         delta += (now - start) / period;
         
         start = now;
         
         if (delta > 1) {
            updates++;
            update();
            delta--;
         }
         
         frames++;
         render();
         
         if (System.currentTimeMillis() - timer > 1000) {
            frame.setTitle(title + " | Logical updates: " + updates + ", Graphical Updates: " + frames);
           
            timer += 1000;
            updates = 0;
            frames = 0;
         }
      }
   }
   
   public void render() {
      BufferStrategy strategy = getBufferStrategy();
     
      if (strategy == null) {
         createBufferStrategy(3);
         return;
      }
     
      screen.render(0, 0);
     
      for (int i = 0; i < pixels.length; i++) {
         pixels[i] = screen.pixels[i];
      }
     
      Graphics g = strategy.getDrawGraphics();
     
      g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
     
      g.dispose();
      strategy.show();
   }
   
   public void update() {
     
   }
   
   public void start() {
      running = true;
     
      thread = new Thread(this, "Display");
      thread.start();
   }
   
   public void stop() {
      running = false;
     
      try {
         thread.join();
      } catch (InterruptedException e) {
         
      }
   }

   public static void main(String[] args) {
      Game game = new Game();
   }
}


Screen.java:

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  
package com.mizzath.graphics;

public class Screen {
   private int width, height;
   
   private Map map;
   
   public int[] pixels;
   
   public Screen(int width, int height, Map map) {
      this.width = width;
      this.height = height;
      this.map = map;
     
      pixels = new int[width * height];
   }
   
   public void render(int xOffset, int yOffset) {
      for (int y = 0; y < height; y++) {
         int yy = y + yOffset;
         if (yy < 0 || yy >= map.heightInPixels()) break;
         
         for (int x = 0; x < width; x++) {
            int xx = x + xOffset;
            if (xx < 0 || xx >= map.widthInPixels()) break;
           
            int tileIndex = (xx >> (map.tileSize() / 4)) + (yy >> (map.tileSize() / 4)) * map.widthInTiles();
           
            if (tileIndex < map.tiles().length) {
               pixels[x + y * width] = map.tiles()[tileIndex];
            }
         }
      }
   }
}


Map.java:

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  
package com.mizzath.graphics;

import java.util.Random;

public class Map {
   private int widthInTiles, heightInTiles, tileSize;
   private int[] tiles;
   
   private Random random = new Random();
   
   public Map(int widthInTiles, int heightInTiles, int tileSize) {
      this.widthInTiles = widthInTiles;
      this.heightInTiles = heightInTiles;
      this.tileSize = tileSize;
     
      tiles = new int[widthInTiles * heightInTiles];
     
      for (int i = 0; i < tiles.length; i++) {
         tiles[i] = random.nextInt(0xffffff);
      }
   }
   
   public int[] tiles() {
      return tiles;
   }
   
   public int tileSize() {
      return tileSize;
   }
   
   public int widthInTiles() {
      return widthInTiles;
   }
   
   public int heightInTiles() {
      return heightInTiles;
   }
   
   public int widthInPixels() {
      return widthInTiles * tileSize;
   }
   
   public int heightInPixels() {
      return heightInTiles * tileSize;
   }
}


Thanks, mates!
Offline StumpyStrust
« Reply #1 - Posted 2012-11-12 06:56:55 »

I don't want to be rude, but what is with everyone using all this pixel[] nonsense? Unless you are trying to do some super ridiculous effects in java2D or are working on a java4k game there is really no need to touch an array of pixels.

Look into Graphics2D.scale I think. It may help.

Also, I recommended not over thinking this too much. When I wanted to do some pixel effects it java2D was slow. So I rendered everything like normal to a Volatile Image at full resolution. This keeps things fast. After the rendering was done and I wanted to access the pixels for lighting or w/e, I then drew the volatile image to a bufferedimage at the a reduced resolution. Thing are still fast. Now I access the pixels from the bufferedimage which un-managed it. This is were the slow down happens but because the resolution is low, it is manageable. After doing my black pixel magic, I draw the edited buffered image using the buffer strategies graphics object.

You could use two volatile images instead of bufferedImage and us getSnapShot() but I am not sure if that would be much of a performance boost. The key thing is keeping things managed. It is hard to beat the performance of the simple, g.drawImage() as it keeps everything managed. The moment you touch pixel[], BAM! unmanaged. If you only do this every once in a while it is no problem but if you do it every frame...

Offline Mizzath

Senior Newbie





« Reply #2 - Posted 2012-11-12 07:10:25 »

I don't want to be rude, but what is with everyone using all this pixel[] nonsense? Unless you are trying to do some super ridiculous effects in java2D or are working on a java4k game there is really no need to touch an array of pixels.

Look into Graphics2D.scale I think. It may help.

Also, I recommended not over thinking this too much. When I wanted to do some pixel effects it java2D was slow. So I rendered everything like normal to a Volatile Image at full resolution. This keeps things fast. After the rendering was done and I wanted to access the pixels for lighting or w/e, I then drew the volatile image to a bufferedimage at the a reduced resolution. Thing are still fast. Now I access the pixels from the bufferedimage which un-managed it. This is were the slow down happens but because the resolution is low, it is manageable. After doing my black pixel magic, I draw the edited buffered image using the buffer strategies graphics object.

You could use two volatile images instead of bufferedImage and us getSnapShot() but I am not sure if that would be much of a performance boost. The key thing is keeping things managed. It is hard to beat the performance of the simple, g.drawImage() as it keeps everything managed. The moment you touch pixel[], BAM! unmanaged. If you only do this every once in a while it is no problem but if you do it every frame...

Believe me, I'm absolutely new when it comes to Java game development, so input like this is truly appreciated. I'll research a VolatileImage for a while and then attempt to implement it. However, how simple would it be to recreate my tile map?
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 (28 views)
2014-04-15 18:08:23

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

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

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

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

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

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

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

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

CJLetsGame (195 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!