Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (494)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
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  
  setting images depending on surrounding  (Read 747 times)
0 Members and 1 Guest are viewing this topic.
Offline Trosters

Junior Member


Projects: 1



« Posted 2011-08-22 11:14:25 »

I am writing a small game to learn path finding(which was quite easy by the way!:D). It is kind of a tower defense game where you get to build the walls yourself, and I've run into problems.

I first implemented walls as multiple different classes, each with different images and I then allowed the user to chose what his wall should look like by picking different classes.

Some image examples to make things clearer:




Now my problem is that I instead want to use only one class - Wall. And I want the class constructor to calculate what image is the correct image. I have tried some different solutions but they all come down to me realizing that they will probably work but they will take a week to write and a year to debug because they will be so long and so messy.

Basically what I have had in mind is, when a wall is created it will look around its 8 neighbours: (X beeing the wall itself)
1 2 3
4 X 5
6 7 8
and check which are walls, then select image using a bazillion of if-phrases and then notifying all the walls nearby that "I am new, check your surroundings again and update your images accordingly".

My problem is that to do this, my only idea is to go like:
1  
2  
3  
4  
5  
6  
if (map[tileY-1][tileX-1] instanceof Wall && map[tileY-1][tileX] instanceof Wall .... && map[tileY+1][tileX+1] instanceof Wall) {
   setImage();
} else if (!map[tileY-1][tileX-1] instanceof Wall && map[tileY-1][tileX] instanceof Wall .... && map[tileY+1][tileX+1] instanceof Wall) {
setImage();
} ... {
}


But this would just be so insanely long and complicated to read through it just don't seem like a very good idea. I mean it would be like 2^8 if statements?:/

So I decided to ask you guys! How can I solve this?
Offline theagentd
« Reply #1 - Posted 2011-08-22 14:31:16 »

There was a technique that was usable for this. I faced the same problem with tile transitions recently, and I found a really good article here on JGO about it. I can't for the love of god find it right now, but someone should remember it!
You basically need to generate a unique tile for each combination of neighbors, meaning you'll need 2^8 different images (you're aware of this, right?). Let's say you have these images loaded in an array:
1  
Image[] images = new Image[256]

Now for each combination of neighbors you need a unique index in this array. You can easily get this, but you still need eight if-statements. The idea is to use a byte's bits as neighbor flags.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
int tile = 0; //The tile index.
int i = 0; //Current bit to modify.
for(int y = -1; y < 2; y++){
    for(int x = -1; x < 2; x++){
        if(x == 0 && y == 0){
            continue; //Skip self
       }
        if(map[tileY + y][tileX + x] instanceof Wall){
            tile += 1 << i; //Set the bit on the i'th place to 1.
       }
        i++;
    }
}
setImage(tile);

Really bad code, but it should work (barring any spelling errors, programming in post FTW) right away, if you have all the 256 images ready. The tricky part is getting the images in the right order. In this case index 0 would be a lone wall with no neighbors:
1  
2  
3  
...
.#.
...


1 would be a wall with the top left neighbor also being a wall:
1  
2  
3  
#..
.#.
...


2 would be a wall with the top neighbor also being a wall:
1  
2  
3  
.#.
.#.
...


3 is 1 plus 2, so it is both top left and top:
1  
2  
3  
##.
.#.
...


4 is top right:
1  
2  
3  
..#
.#.
...


5 is 1 + 4:
1  
2  
3  
#.#
.#.
...


E.t.c...
I hope you get it. xD Some more examples:
2+4+32=38 is the 5th image of your example images.
1+2+4+8+16+32+64+128=255 is the 4th (all gray) image of your example images.

Myomyomyo.
Offline Trosters

Junior Member


Projects: 1



« Reply #2 - Posted 2011-08-22 15:34:26 »

Yeah, thanks I got some help over at slick forums and I am on my way to solving this completely, just takes ALOT of time to make all the images required since there's 255 neighbourcombinations!:p

Here's the post on slick forums if anyone has a similiar problem some time and finds this thread:
http://slick.javaunlimited.net/viewtopic.php?t=3692
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline philfrei
« Reply #3 - Posted 2011-08-22 20:45:04 »

Sounds like you are already well on your way to a solution. But I thought I'd share something I came up with using a Hex tile grid. http://www.Hexara.com/gameNS.htm in it, various searches of neighboring hexes need to be done to update the status as to whether a "scroll" chain is present or not.

To do this, I maintain a tree representation of the grid, separate from the grid itself, optimized for recursive searches.  For example, each "searchHex" has a LinkedHashSet of all neighboring searchHexes, and an array of booleans to mark whether a searchHex has already been touched or not, as well as the appropriate state values needed.

Separating the structure used for the searches from the representation used for display makes a certain sense. You will probably find performance pickups by making the structure one of aggregation that is as immutable as possible, allowing for concurrency optimizations by the JVM.

"Greetings my friends! We are all interested in the future, for that is where you and I are going to spend the rest of our lives!" -- The Amazing Criswell
Offline theagentd
« Reply #4 - Posted 2011-08-23 12:20:15 »

Quote
I use the following values:
1 2 4
8 X 16
32 64 128

My first code example generated these exact values...
Tips: By only using the direct neighbors (not the diagonal ones), you only need 2^4=16 tiles. It's also possible to divide the tile into 4 smaller tiles, and then you only have to check 3 neighbors per tile, resulting in only 5 different subtiles. The tiles images are 1/4 times as large, and you only need 5 of them to represent all 256 tiles you need. The only problem is more repetitive patterns of your tile, but this can be solved by having multiple (say 5 or so) slightly different tiles for each compination:

My/your solution: 256 images, tileSize^2 * 4 * 256 = tileSize^2 * 1024 bytes.
My proposed solution: 5 images, (tileSize/2)^2 * 4 * 5 = tileSize^2 * 5 bytes.

Even if you multiply my proposed solution with 5, it's still way lower than 256 images.

Myomyomyo.
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.

Dwinin (21 views)
2014-09-12 09:08:26

Norakomi (55 views)
2014-09-10 13:57:51

TehJavaDev (66 views)
2014-09-10 06:39:09

Tekkerue (33 views)
2014-09-09 02:24:56

mitcheeb (54 views)
2014-09-08 06:06:29

BurntPizza (38 views)
2014-09-07 01:13:42

Longarmx (24 views)
2014-09-07 01:12:14

Longarmx (30 views)
2014-09-07 01:11:22

Longarmx (28 views)
2014-09-07 01:10:19

mitcheeb (37 views)
2014-09-04 23:08:59
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!