Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (483)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (550)
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] Looping through an images pixels differently  (Read 971 times)
0 Members and 1 Guest are viewing this topic.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Posted 2011-10-30 21:00:57 »

I need to load an image into a level-object. You can see this structure at the end of the OP. It's basicly a 2D array, of nulls and bricks.
Each black pixel is one brick, each white is a null.



My world, however, starts from the buttom left. So, I need to loop through it in that manner. Or, do something else.
For now, I've been looping it so that the whole level appeared upside down.

My current loop:
1  
2  
3  
4  
5  
6  
7  
8  
for (int x = 0; x < length; x++) {
         for (int y = 0; y < 20; y++) {
            Color color = img.getColor(x, y);
            if (color.getRedByte() == 0 && color.getGreenByte() == 0 && color.getBlueByte() == 0) {
               returnValue.setBrick(x, y, new Brick());
            }
         }
      }


What's odd though, is that my level is rendered correctly, even though the data structure is messed up.



1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
// World-rendering
     int startingX = cameraX/10;
      g.setColor(Color.green);
      for (int x = startingX; x < 50+startingX; x++) {
         for(int y = 0; y < 20; y++) {
            if (level.getBrick(x, y) != null) {
               int k = x * 10;
               int startDrawX = k - cameraX;
               int startDrawY = y * 10;
               g.drawRect(startDrawX, startDrawY, 10, 10);
            }
         }
      }


Finally, the level class, if you want to see how it works.
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  
package com.javadaemon.skrollr.model;

import java.util.ArrayList;

/**
 * A static level.
 *
 * @author Mads Horndrup
 *
 */

public class StaticWorld {
   
   private ArrayList<Brick[]> worldColumns;
   
   public StaticWorld(int length) {
      worldColumns = new ArrayList<Brick[]>();
      for (int i = 0; i < length; i++) {
         worldColumns.add(new Brick[20]);
      }
   }
   
   public ArrayList<Brick[]> getWorldColumns() {
      return worldColumns;
   }
   
   public Brick getBrick(int x, int y) {
      if (x < 0 || y < 0 || y >= 20) {
         return null;
      }
      else if (x >= worldColumns.size()) {
         return null;
      } else {
         Brick brick = worldColumns.get(x)[y];
         return brick;
      }
   }
   
   public void setBrick(int x, int y, Brick brick) {
      worldColumns.get(x)[y] = brick;
   }
   
   public boolean isInsideBrick(double worldX, double worldY) {
      int x = (int)worldX /10;
      int y = (int) worldY /10;
      System.out.println("method: " + x + " " + y);
      if (getBrick(x, y) == null) {
         return false;
      } else {
         return true;
      }
   }
   
   public double checkBrickTop(double worldX, double worldY, double step) {
      if (isInsideBrick(worldX, worldY)) {
         double shouldBeY = worldY/10 +1 ;
         double diff = shouldBeY - worldY;
         return step - diff;
      } else {
         return step;
      }
   }
}


Thing is, when I use methods like isInsideBrick(0, 0), it grabs the pixel from the top-left corner of the picture, and reports that there is no pixel there. However, by specifying (0, 0) I mean the worlds bottom-left corner, where there is in fact a brick.

So.. I believe this is a simple error, of looping through the image when loading, the correct way.

I can elaborate, please ask.

Online theagentd
« Reply #1 - Posted 2011-10-30 21:41:48 »

Just flip the y-coordinate?
imageY = imageHeight - 1 - worldY
so if you want the bottom left coordinate, you send in worldY = 0. If your map is 20 tiles high, this will become 20 - 1 - 0 = 19, which is the last (bottom) line of your pixels in your image.

Myomyomyo.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #2 - Posted 2011-10-30 21:52:58 »

Just flip the y-coordinate?
imageY = imageHeight - 1 - worldY
so if you want the bottom left coordinate, you send in worldY = 0. If your map is 20 tiles high, this will become 20 - 1 - 0 = 19, which is the last (bottom) line of your pixels in your image.

That work's beautifully.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
 for (int x = 0; x < length; x++) {
         for (int y = 0; y < 20; y++) {
            Color color = img.getColor(x, y);
            if (color.getRedByte() == 0 && color.getGreenByte() == 0 && color.getBlueByte() == 0) {
               int newY = 20 - 1 -y;
               returnValue.setBrick(x, newY, new Brick());
               //System.out.println(x +" "+y+" ");
           }
         }
      }


However, now my world is rendered upside down:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
// World-rendering
     int startingX = cameraX/10;
      g.setColor(Color.green);
      for (int x = startingX; x < 50+startingX; x++) {
         for(int y = 0; y < 20; y++) {
            if (level.getBrick(x, y) != null) {
               int k = x * 10;
               int startDrawX = k - cameraX;
               int startDrawY = (y * 10);
               g.drawRect(startDrawX, startDrawY, 10, 10);
            }
         }
      }


Any ideas? My worlds 0, 0 is at the lower-left, so it's kind of the same problem.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online theagentd
« Reply #3 - Posted 2011-10-30 21:55:28 »

Flip it back again? xD

Myomyomyo.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #4 - Posted 2011-10-30 22:27:04 »

Flip it back again? xD

Doesn't work, quite the same way.. Atleast, I couldn't.   Cheesy
Look at the loop:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
// World-rendering
     int startingX = cameraX/10;
      g.setColor(Color.green);
      for (int x = startingX; x < 50+startingX; x++) {
         for(int y = 0; y < 20; y++) {
            if (level.getBrick(x, y) != null) {
               int k = x * 10;
               int startDrawX = k - cameraX;
               int startDrawY = (y * 10);
               g.drawRect(startDrawX, startDrawY, 10, 10);
            }
         }
      }

This loops through the map as it should, but the draw coordinates are off.. It draws upside down Cheesy

Online theagentd
« Reply #5 - Posted 2011-10-31 10:39:12 »

So you need to access the map in two different ways, right? You need it flipped up side down (for checking collisions) and you need it as normal when rendering it. You really shouldn't have both a flipped version and an unflipped version in memory, so you'll just have to decide to keep it either flipped or unflipped in memory, and then when you get need to find a brick correct the y-coordinate if you need it flipped compared to how you store it.

Let's say that you store the map unflipped (you use your original map loading code to create Bricks). Rendering should work fine with just level.getBrick(x, y);. However in all your collision detection code (isInsideBrick(x, y), e.t.c) you flip the y-coordinate (int newY = height - 1 - y;). You should build this into the isInsideBrick() and the other collision methods of course. The level will be rendered correctly, and the collision will be handled correctly. Success!

Now, think about the reason you got into this problem in the first place. Why are you using a coordinate system that is different from the screen's top left coordinate system? You're making it a lot harder for yourself by doing it like this.

Myomyomyo.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #6 - Posted 2011-10-31 23:38:19 »

So you need to access the map in two different ways, right? You need it flipped up side down (for checking collisions) and you need it as normal when rendering it. You really shouldn't have both a flipped version and an unflipped version in memory, so you'll just have to decide to keep it either flipped or unflipped in memory, and then when you get need to find a brick correct the y-coordinate if you need it flipped compared to how you store it.

Let's say that you store the map unflipped (you use your original map loading code to create Bricks). Rendering should work fine with just level.getBrick(x, y);. However in all your collision detection code (isInsideBrick(x, y), e.t.c) you flip the y-coordinate (int newY = height - 1 - y;). You should build this into the isInsideBrick() and the other collision methods of course. The level will be rendered correctly, and the collision will be handled correctly. Success!

Now, think about the reason you got into this problem in the first place. Why are you using a coordinate system that is different from the screen's top left coordinate system? You're making it a lot harder for yourself by doing it like this.

No, I only have it once. The problem is, in how the rendering loop works. I solved it, though, by altering the way it loops/draws Smiley

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.

CopyableCougar4 (19 views)
2014-08-22 19:31:30

atombrot (30 views)
2014-08-19 09:29:53

Tekkerue (26 views)
2014-08-16 06:45:27

Tekkerue (23 views)
2014-08-16 06:22:17

Tekkerue (15 views)
2014-08-16 06:20:21

Tekkerue (24 views)
2014-08-16 06:12:11

Rayexar (63 views)
2014-08-11 02:49:23

BurntPizza (40 views)
2014-08-09 21:09:32

BurntPizza (31 views)
2014-08-08 02:01:56

Norakomi (38 views)
2014-08-06 19:49:38
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!