Author Topic: Python + Libtcod Filling Rooms  (Read 8482 times)

crowtongue

  • Newcomer
  • Posts: 3
  • Karma: +0/-0
    • View Profile
Python + Libtcod Filling Rooms
« on: January 17, 2013, 04:21:37 AM »
So I finished working my way through the Python Libtcod tutorial on RogueBasin. Since I have no Python background instead of copying the code I typed it all out, resolved the errors from my mistakes, and have been following a couple of Python tutorials to help me get more familiar with the language.

I've added a new room type to my game, changed it to tiles, and created a system for randomly changing some tiles in a room to give it a more dynamic look.

Although I've created a new room type, it currently just draws the outline of the room (a circle.) I have no idea how to go about filling it. I've found some diagrams talking about scanline filling, and they seem to make sense, but I have no idea how to implement them.

http://www.cs.ucdavis.edu/~ma/ECS175_S00/Notes/0411_b.pdf

 I'd like to create a function so later when I make more roomtypes I can use the same function.

This thread seems useful, but I'm still not sure how to go about doing this.

http://roguetemple.com/forums/index.php?topic=2637.0

I am willing to put the work in, and am not looking for someone to do all the work for me, just want some help getting through this.

Thanks!


Alex E

  • Rogueliker
  • ***
  • Posts: 118
  • Karma: +0/-0
    • View Profile
    • Email
Re: Python + Libtcod Filling Rooms
« Reply #1 on: January 17, 2013, 05:06:56 AM »
If you want to fill in some space, you could try this.. Find a tile somewhere in the space you want to fill and then make every adjacent tile that is not a wall become filled in as well, and so on and so on.

Here's an example

(I assume you want to fill in the room with floor tiles)
(pick a random tile to be a floor tile, which i'll show with *)
####### <- Wall Tiles
#           #
#      *   #
#           #      
#######

(fill in the adjacent tiles of the floor tile and then loop through the level again to fill in the adjacent tiles of the now filled in floor tiles)
#######
#      *   #
#    *** #
#      *   #      
#######

 (and keep filling in the adjacent tiles of the floor tiles)
#######
#    *** #
#  **** #
#    *** #      
#######

#######
#  **** #
#***** #
#  **** #      
#######

 (eventually you'll fill in the entire room)
#######
#***** #
#***** #
#***** #      
#######
« Last Edit: January 17, 2013, 05:11:51 AM by Mosenzov »

crowtongue

  • Newcomer
  • Posts: 3
  • Karma: +0/-0
    • View Profile
Re: Python + Libtcod Filling Rooms
« Reply #2 on: January 17, 2013, 07:36:09 AM »
Originally I had just tried to do the entire room this way...

But loops are working a bit different in Python than what I would expect.

I've done a couple of things based on your post

 I created a separate 'wall' property for Tiles and set it to true for all the tiles that outline the room. I've also created a function to check
Code: [Select]
if map[x][y].wall is True
The bulk of the problem I'm having with this I think isn't a conceptual thing so much as an execution thing.

so I can get the middle tile of the room as follows:

Code: [Select]
map[room.x1 + room.r][room.y1 + room.r]      (r is the radius of the room)

So to start I could use my function maybe with an if statement

Code: [Select]
if not is_wall(x,y):

Then I could have it change the .blocked of the tile. But how do I coherently make it loop in 4 directions, then in 4 directions for each of the 4 tiles around it?

The way I could think of doing this is maybe a couple of nested While statements and a bunch of variables used as counters, but this gets messy and bloated pretty fast. Is there another way?

tuturto

  • Rogueliker
  • ***
  • Posts: 259
  • Karma: +0/-0
    • View Profile
    • pyherc
Re: Python + Libtcod Filling Rooms
« Reply #3 on: January 17, 2013, 08:25:02 AM »
If you know bounds of your room, you can write two loops (one inside other):

Code: [Select]
for location_y in xrange(top_row + 1, bottom_row - 1):
    for location_x in xrange(left_side + 1, right_side - 1):
        map[location_x][location_y].floor = True

provided that your Tile has floor - attribute to tell that it is a floor tile. In square rooms left_side and right_side are constant, but in circular rooms they depend on the current row you are filling.

Hopefully this helps.
Everyone you will ever meet knows something you don't.
 - Bill Nye

crowtongue

  • Newcomer
  • Posts: 3
  • Karma: +0/-0
    • View Profile
Re: Python + Libtcod Filling Rooms
« Reply #4 on: January 22, 2013, 08:59:53 PM »
Thanks a lot for the suggestions. Gives me stuff to play around with while I'm coming up with weird room shapes.

As for the circular room, Jotaf kindly posted an easier way of doing this over at the Roguecentral board:

Code: [Select]
def create_circular_room(room):
    global map
    #center of circle
    cx = (room.x1 + room.x2) / 2
    cy = (room.y1 + room.y2) / 2

    #radius of circle: make it fit nicely inside the room, by making the
    #radius be half the width or height (whichever is smaller)
    width = room.x2 - room.x1
    height = room.y2 - room.y1
    r = min(width, height) / 2

    #go through the tiles in the circle and make them passable
    for x in range(room.x1, room.x2 + 1):
        for y in range(room.y1, room.y2 + 1):
            if math.sqrt((x - cx) ** 2 + (y - cy) ** 2) <= r:
                map[x][y].blocked = False
                map[x][y].block_sight = False

Hopefully that will help anyone else out trying to do the same thing!