Tuesday, August 6, 2013

Laying down some tile!

I finally got it to work!

Pictured is a test room that will be used to test the functionality of other aspects of the game, both basic and advance.  There were some share of challenges with this, but as I said from yesterday's post, baby steps.

Right now its just the drawing of the sprites.  Once that is done it would be implementing the PC to be able to take button input and move accordingly, and then collision detection.  After all, the walls should behave like walls.

Nevertheless, as I went to coding this test room I came across a stumbling block as I was coding it.  In earlier coding the sprite subclass I had for the walls was set such that I give it a compass direction represented as an integer (north, south, east, west).  As for the corners I would give it two compass directions: one for each of the joining walls.  As an example, if the corner was where a north and west facing wall intercepted than it was north/west.

Course, this was coded under the understanding that the fillSprite command was simply going to make a deep copy of an already created object, not pass a constructor.  So, seeing as the constructor required an orientation for walls but none for floor... well, one can see the clusterf*ck that was to come.

The solution was simply having two different fill functions: one for the floor and one for the walls.  The thinking is simply that when building the levels the only things that would be batched-put would be walls and floors.  Every other sprite: doors, chests, and NPCs would be manually placed anyways.

Here's the one for the floor:

def fillFloor(sprite_construct,leftTop,rightBottom,group):
    proto = sprite_construct()
    for x in range(leftTop[0],rightBottom[0]+1,proto.rect.width):
         for y in range(leftTop[1],rightBottom[1]+1,proto.rect.height):
            sprite = sprite_construct()
            sprite.rect.center = (x,y)
            group.add(sprite)


The '+1' on the range was to fix a problem where the sprites to be located along the right-most and bottom-most position were not unfilled, so this is done with an understanding of the Python range function, which is built into the language.

Now, here's the one for the walls, the interesting one:

def fillWall(sprite_construct,orientation,start,finish,axis,group):
    proto = sprite_construct(orientation)
    for c in range(start,finish+1,proto.rect.width):
        sprite = sprite_construct(orientation)
        if orientation == NORTH or orientation == SOUTH:
            sprite.rect.center = (c,axis)
        else:
            sprite.rect.center = (axis,c)
        group.add(sprite)


I realized when building walls that they would be one sprite long by so many sprites wide (or vice versa).  So, I simply place x/y position of the start, the x/y position of the end, the y/x position of the wall along the y/x of the screen (the axis) and the wall's orientation.  The function would position the wall according to whether it was a horizontal wall (a North or South facing wall) or a vertical one (East or West).

So, the calls that brought about that room?

        #first the floor
        fillFloor(StoneFloor,(0,0),(300,300),self.floor)
        #then walls
        fillWall(StoneWall,SOUTH,75,225,275,self.walls)
        fillWall(StoneWall,NORTH,75,225,25,self.walls)
        fillWall(StoneWall,EAST,75,225,25,self.walls)
        fillWall(StoneWall,WEST,75,225,275,self.walls)
        #corners are inserted manually
        self.walls.add(InnerStoneCorner(NORTH,WEST,(25,25)))
        self.walls.add(InnerStoneCorner(NORTH,EAST,(25,275)))
        self.walls.add(InnerStoneCorner(SOUTH,WEST,(275,25)))
        self.walls.add(InnerStoneCorner(SOUTH,EAST,(275,275)))
        #lets test the outer corners
        self.walls.add(OuterStoneCorner(SOUTH,WEST,(125,175)))
        self.walls.add(OuterStoneCorner(SOUTH,EAST,(125,125)))
        self.walls.add(OuterStoneCorner(NORTH,WEST,(175,175)))
        self.walls.add(OuterStoneCorner(NORTH,EAST,(175,125)))
        #as are doors and arches
        self.doors.add(StoneEntrance(NORTH,(150,25)))
        self.doors.add(WoodenDoor(NORTH,(150,25)))


And voila!  A room.

No comments:

Post a Comment