N-Game v2.0
Would you like to react to this message? Create an account in a few clicks or log in to continue.
Latest topics
» A Dying Breed
Making a level with programming EmptyThu Feb 01, 2024 12:24 pm by Ephemeral

» N v2.0 is a good game, yes or no
Making a level with programming EmptySun Nov 19, 2023 5:34 am by V3L0C1T4

» N v2.0 is fun. Do you agree?
Making a level with programming EmptyFri Feb 11, 2022 1:45 am by V3L0C1T4

» Corona Virus - Share your tips & discuss
Making a level with programming EmptyMon Jun 29, 2020 1:12 am by james_s

» Good Wishes From The AiR
Making a level with programming EmptySun May 24, 2020 6:33 pm by james_s

» Custom Color!!!!
Making a level with programming EmptyThu Jan 16, 2020 12:37 am by JaeyDoesYT

» The 14th flavour?
Making a level with programming EmptyMon Jan 13, 2020 11:17 pm by JaeyDoesYT

» Suggestions for Nv2.0
Making a level with programming EmptyMon Jan 13, 2020 1:43 pm by JaeyDoesYT

» Level data, fully explained.
Making a level with programming EmptyFri Jan 25, 2019 6:17 pm by vrugtehagel


Making a level with programming

Go down

Making a level with programming Empty Making a level with programming

Post by garamond Sat Dec 27, 2014 9:51 pm

I'm making a level which requires programming, so I've written some helper code, which I'm sharing here. For one level I already used it, for making a "fake" red rating -- the idea is the same as in "How to make "Blind Plays" Levels" tutorial -- i.e. how to position objects outside normal level limits. Except this post is about doing that with python programming.

One example is "it's time" by Snowtiger (the blue ratings just outside in the mini level preview). (I can't find my own level now :/ )

I'm posting the code here.
By modifying move_exampe() you can move objects. More specific directions are written there.

The code can do much more. You can also add objects programatically -- add_mines_example() adds a diagonal with 70 mines.

Maybe somebody can use this for whatever reason :)

Code:
import operator


empty_objects = {  # "name": (position number in data, num of bytes, data)
    "player" : (0, 2, ""),
    "mine" : (1, 2, ""),
    "gold" : (2, 2, ""),
    "exit" : (3, 4, ""),
    "regular_door" : (4, 3, ""),
    "locked_door" : (5, 5, ""),
    "trap_door" : (6, 5, ""),
    "launchpad" : (7, 3, ""),
    "oneway" : (8, 3, ""),
    "chaingun" : (9, 4, ""),
    "laser" : (10, 4, ""),
    "zap" : (11, 4, ""),
    "chaser" : (12, 4, ""),
    "floorguard" : (13, 2, ""),
    "bounceblock" : (14, 2, ""),
    "rocket" : (15, 2, ""),
    "gauss" : (16, 2, ""),
    "thwump" : (17, 3, "")
}


def move(objects, type, diff_x, diff_y, pos_start):

    orig = objects[type]
    num, b, original_objects = orig
    new_objects = ""
    length = b * 2

    for i in range((len(original_objects) - 4) // length):
        rev_hex_x = original_objects[4 + i * length + pos_start : 4 + i * length + pos_start + 2]
        rev_hex_y = original_objects[4 + i * length + pos_start + 2 : 4 + i * length + pos_start + 4]

        final_x = dec_to_reverse_hex(hex_to_dec(rev_hex_x) + diff_x)
        final_y = dec_to_reverse_hex(hex_to_dec(rev_hex_y) + diff_y)

        temp = original_objects[4 + i * length : 4 + i * length + length]
        temp = list(temp)

        temp[pos_start + 0] = final_x[0]
        temp[pos_start + 1] = final_x[1]
        temp[pos_start + 2] = final_y[0]
        temp[pos_start + 3] = final_y[1]

        new_objects += "".join(temp)
    #print(new_objects)
    objects[type] = num, bytes, original_objects[0:4] + new_objects


def add_object(objects, type, object_data):
    orig = objects[type]
    num, bytes, original_objects = orig
    num_original = hex_to_dec(original_objects[0:4])
    num_added = hex_to_dec(object_data[0:4])
    objects[type] = num, bytes, dec_to_reverse_hex_byte(num_original + num_added) + original_objects[4:] + object_data[4:]


def hex_to_dec(reverse_hex_string):
    if reverse_hex_string == "00" or reverse_hex_string == "0000":
        return 0
    if len(reverse_hex_string) == 2:
        return int(reverse_hex_string[::-1], 16)
    else:  # len is 4
        first = int(reverse_hex_string[0:2][::-1], 16)
        second = int(reverse_hex_string[2:4][::-1], 16)
        return first * 16 * 16 + second


def dec_to_reverse_hex(dec):
    num = (hex(dec)[2:])[::-1]  # we've got no negative numbers
    if len(str(num)) == 1:
        return str(num) + "0"
    return num


def dec_to_reverse_hex_byte(dec):
    num = (hex(dec)[2:])  # we've got no negative numbers
    if len(str(num)) == 1:
        return "00" + str(num) + "0"
    if len(str(num)) == 2:
        return "00" + str(num)[1] + str(num)[0]
    if len(str(num)) == 3:
        return str(num)[0] + "0" + str(num)[2] + str(num)[1]
    if len(str(num)) == 4:
        return str(num)[1] + str(num)[0] + str(num)[3] + str(num)[2]


def serialise(objects, data):
    pos = 0
    sorted_objects = sorted(objects.items(), key=operator.itemgetter(1))
    for item in sorted_objects:
        num_objects = hex_to_dec(data[pos : pos + 4])
        till_next = num_objects * item[1][1] * 2
        objects[item[0]] = item[1][0], item[1][1], data[pos : pos + 4 + till_next]
        #print("#: " + str(item[1][0]), "position: " + str(pos), "num_objects: " + str(num_objects))
        pos += till_next + 4


def pack(objects):
    packed = ""
    sorted_objects = sorted(objects.items(), key=operator.itemgetter(1))
    for item in sorted_objects:
        packed += (item[1][2])
    return packed


def move_example():
    # paste here level data from N Editor. Remove level name in the beginning, if it's present
    data = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087017511751165900590f4a0f4e0f41125c0759045907511f4c065e045a045c025e00501250165a00581755145510551f461f4a1f4d125c175d175d165d1f451758165614561058125a105a145c125c16542751245120512f422f462f4922582759275926592f41275426522452205422562056245822582650375d245d205d2f4e2f423f4532543755375536553f4d2750365e245e20503252305234543254365c3759345930593f4a3f4e3f4142504751475146514f49375c365a345a305c325e305e3450425046584755445540554f464f4a4f4d425c475d475d465d4f454758465644564058425a405a445c425c465000000000000000000000000000000000003c0450020c00500200105002001450020a0650020e0650020e0250020a02500208145002081050020c1050020c1450020a125002061650020a16500206125002042450020420500208205002082450020622500202265002062650020222500200345002003050020430500204345002023250020e265002023650020e2250020c3450020c30500200405002004450020e3250020a3650020e3650020a32500208445002084050020c4050020c4450020a425002064650020a4650020642500200000000000000000000000000000"
    new = data[1426 + 8:]  #only objects
    objects = empty_objects.copy()
    serialise(objects, new)
    # Specify objects that you want to move. List of names is in the beginning of this file
    # "135" means move object for roughly a level width to the right
    move(objects, "laser", 135, 0, 0)
    move(objects, "mine", 135, 0, 0)
    print(data[0:1426 + 8] + pack(objects))


def draw_many_doors_example():
    data = "0000" * 18
    objects = empty_objects.copy()
    serialise(objects, data)

    # add many many doors
    for i in range(128 + 1 - 4):  #128
        for j in range(94 // 2):  #94
            add_object(objects, "locked_door", "0010" + dec_to_reverse_hex(i + 4) + dec_to_reverse_hex(j * 2 + 4) + "00" + "8080")

    for i in range(128 // 4 - 4):  #128
        for j in range(94):  #94
            add_object(objects, "locked_door", "0010" + dec_to_reverse_hex(i * 4 + 4) + dec_to_reverse_hex(j + 4) + "20" + "8080")

    #print(sorted(objects.items(), key=operator.itemgetter(1)))
    print(dummy_blocks + pack(objects))


def add_mines_example():
    data = "0000" * 18
    objects = empty_objects.copy()
    serialise(objects, data)

    # add single mine
    add_object(objects, "mine", "0010ffff") # 0010 is 1 mine, ff is position x, ff is position y

    # add 70 mines in a diagonal line
    for i in range(70):
        add_object(objects, "mine", "0010" + dec_to_reverse_hex(i) + dec_to_reverse_hex(i))

    print(dummy_blocks + pack(objects))


# dummy_blocks + empty objects data = empty level
dummy_blocks = "00000000" + "00" * 31 * 23 # "00" is empty block
data = "0000" * 18

#move_example()
#draw_many_doors_example()
add_mines_example()
If you don't have python installed, you can play with it on http://repl.it/7EL

garamond
Admin

Messages : 21
Joined : 2014-11-16

Back to top Go down

Back to top

- Similar topics

 
Permissions in this forum:
You cannot reply to topics in this forum