コード例 #1
0
ファイル: Generator.py プロジェクト: szakats/bzflag_mirror
def Random(size          = Scale.WorldSize,
           wallHeight    = Scale.WallHeight,
           randomHeights = False,
           pyrBase       = 4.0 * Scale.TankHeight,
           pyrHeight     = 5.0 * Scale.TankHeight,
           boxBase       = 5.0 * Scale.TankLength,
           boxHeight     = 6.0 * Scale.MuzzleHeight,
           citySize      = 5,
           ):
    """
    Generate a traditional random world. The defaults use the
    same random world algorithm as bzfs proper, but it can
    be tweaked to a much greater extent.

    Keyword arguments:
        size          : Distance along each side of the generated square world
        wallHeight    : Height of the world's walls
        randomHeights : Boolean, enable randomly varying object heights
        pyrBase       : Base size for pyramids
        pyrHeight     : Height for pyramids
        boxBase       : Base size for boxes
        boxHeight     : Height for boxes
        citySize      : Determines the number of total pyramids and blocks
    """
    from random import random
    import math

    w = World()
    w.erase()
    w.lifetime = 'temporary'
    w.storeSkeletonHeader(size=size, wallHeight=wallHeight)

    def addRandom(cls, height, base):
        h = height
        num = int((0.5 + 0.7 * random()) * citySize * citySize)
        for i in xrange(num):
            if randomHeights:
                h = height * (2.0 * (random() + 0.5))
            w.storeBlock(cls(
                center = [size * (random() - 0.5),
                          size * (random() - 0.5),
                          0],
                angle = 2.0 * math.pi * random(),
                size = [base, base, h]))
    
    addRandom(WorldObjects.Box, boxHeight, boxBase)
    addRandom(WorldObjects.Pyramid, pyrHeight, pyrBase)
    
    w.storeSkeletonFooter()    
    w.postprocess()
    return w
コード例 #2
0
ファイル: Generator.py プロジェクト: szakats/bzflag_mirror
def Empty(size=Scale.WorldSize,
          wallHeight=Scale.WallHeight,
          ):
    """
    Generate a world with no pyramids or blocks, only walls.
    
    Keyword arguments:
        size       : Distance along each side of the generated square world
        wallHeight : Height of the world's walls
    """
    w = World()
    w.erase()
    w.storeSkeletonHeader(size=size, wallHeight=wallHeight)
    w.storeSkeletonFooter()    
    w.postprocess()
    return w
コード例 #3
0
ファイル: Generator.py プロジェクト: szakats/bzflag_mirror
def Binary(name):
    """
    Load a world from a binary file. This is the world format used in
    transit from server to client, and used in the client's world cache.

    Positional arguments:
        name : File or URI containing the binary world
    """
    from BZFlag.Protocol import Common
    
    blockDict = Common.getMessageDict(WorldObjects)
    f = Util.autoFile(name)
    w = World()
    w.erase()
    while 1:
        # Read the block header
        header = WorldObjects.BlockHeader()
        packedHeader = f.read(header.getSize())
        if len(packedHeader) < header.getSize():
            raise Errors.ProtocolError("Premature end of binary world data")
        header.unmarshall(packedHeader)

        # Look up the block type and instantiate it
        try:
            block = blockDict[header.id]()
        except KeyError:
            raise Errors.ProtocolError(
                "Unknown block type 0x%04X in binary world data" % header.id)

        # Read the block body
        packedBody = f.read(block.getSize() - len(packedHeader))
        if len(packedBody) < (block.getSize() - len(packedHeader)):
            raise Errors.ProtocolError("Incomplete block in binary world data")
        block.unmarshall(packedHeader + packedBody)
        w.storeBlock(block)

        # We're done if this was the EndOfData block
        if isinstance(block, WorldObjects.EndOfData):
            break
    w.postprocess()
    return w
コード例 #4
0
ファイル: Generator.py プロジェクト: szakats/bzflag_mirror
def Heightmap(name,
              size          = Scale.WorldSize,
              wallHeight    = Scale.WallHeight,
              boxHeight     = 20.0 * Scale.MuzzleHeight,
              ):
    """
    Uses the given image file to make a heightmapped world.
    This is very silly and nobody should use this except
    as an example and a proof-of-concept.
    Requires PIL.

    Positional arguments:
        name : File or URI containing the heightmap, in any format PIL supports

    Keyword arguments:
        size       : Distance along each side of the generated square world
        wallHeight : Height of the world's walls
        boxHeight  : Maximum box height, corresponding to a fully white pixel 
    """
    import Image
    f = Util.autoFile(name, "rb")
    img = Image.open(f).convert("L")   # Convert to grayscale
    w = World()
    w.erase()
    w.storeSkeletonHeader(size=size, wallHeight=wallHeight)

    # For now just output a box per nonzero pixel. If I expected
    # anyone to actually use this I'd make it combine rectangular
    # regions of the same pixel value into larger boxes.
    for y in xrange(img.size[1]):
        for x in xrange(img.size[0]):
            p = img.getpixel((x,y))
            if p:
                w.storeBlock(WorldObjects.Box(
                    center = ( (float(x) / img.size[0] - 0.5) * size,
                              -(float(y) / img.size[1] - 0.5) * size,
                               0),
                    size   = (size / img.size[0],
                              size / img.size[1],
                              p / 255.0 * boxHeight),
                    angle  = 0))
    
    w.storeSkeletonFooter()    
    w.postprocess()
    f.close()
    return w
コード例 #5
0
ファイル: Generator.py プロジェクト: szakats/bzflag_mirror
def Text(name,
         size       = Scale.WorldSize,
         wallHeight = Scale.WallHeight,
         ):
    """
    Load a world from a text file. This is the default world format.

    Positional arguments:
        name : File or URI containing the world

    Keyword arguments:
        size       : Default distance along each side of the generated square world
        wallHeight : Height of the world's walls
    """
    import re
    
    f = Util.autoFile(name)
    w = World()
    section = None
    sectionDict = Util.getSubclassDict(WorldObjects, WorldObjects.WorldObject,
                                       'textName', 'textSectionDict')

    # We won't actually add the objects to the world until later,
    # since we need to start the world out with walls and a game style
    # block, but we might get the information needed for those at any
    # point in the file.
    w.erase()
    blocks = []
        
    for line in f:
        # If this is a kludge used by map editors to store extra
        # attributes. Don't process any comments on the line.
        if not line.startswith("#!"):
            line = re.sub("#.*", "", line)
        line = line.strip()
        if line:
            if section:
                # We're inside a section. Accumulate lines until 'end'
                sectionLines.append(line)
                if line == 'end':
                    # Done with this section, process it.

                    if section == 'world':
                        # World information
                        for line in sectionLines:
                            tokens = re.split("\s+", line)
                            keyword = tokens[0].lower()
                            args = tokens[1:]
                            if keyword == 'size':
                                size = int(args[0])

                    else:
                        # Assume all other sections are world objects
                        try:
                            cls = sectionDict[section]
                        except KeyError:
                            raise Errors.ProtocolError(
                                "World file contains unknown section type '%s'" % section)
                        inst = cls()
                        inst.textRead(sectionLines)
                        blocks.append(inst)
                        
                    section = None
            elif not line.startswith("#!"):
                # We're beginning a section
                section = line.lower()
                if section.find(" ") >= 0:
                    raise Errors.ProtocolError("Unexpected whitespace within section name")
                sectionLines = []

    if section:
        raise Errors.ProtocolError("World file has unterminated '%s' section" % section)

    # Now store all the blocks in our world
    w.storeSkeletonHeader(size, wallHeight)
    for block in blocks:
        w.storeBlock(block)
    w.storeSkeletonFooter()
    w.postprocess()
    return w