Tilemap (Creator-Defined Displayable)

A place for Ren'Py tutorials and reusable Ren'Py code.
Forum rules
Do not post questions here!

This forum is for example code you want to show other people. Ren'Py questions should be asked in the Ren'Py Questions and Announcements forum.
Message
Author
User avatar
nyaatrap
Crawling Chaos
Posts: 1824
Joined: Mon Feb 13, 2012 5:37 am
Location: Kimashi Tower, Japan
Contact:

Tilemap (Creator-Defined Displayable)

#1 Post by nyaatrap » Thu Nov 05, 2015 5:03 am

There are a few tilemap engine in ren'py but I couldn't find simple ones for general use, so I wrote it.
This is a simple creator-defined displayable that creates a tilemap by tiling other displayables.
An example of how to use this displayable will be written on the next post.

Code: Select all

## Tilemap displayable

init -2 python:
    
    class Tilemap(renpy.Displayable):
        
        """
        
        This creates a displayable by tiling other displayables. It has the following field values.
        
        map -  A 2-dimensional list of integers that represent index of a tileset.
        tileset -  A list of displayables that is used as a tile of tilemap.
        tile_width - width of each tile.
        tile_height - height of each tile.
        area - Rectangle area of the displayable that will be rendered. If it's None, default, it renders all tiles. 
                
        """
        
        def __init__(self, map, tileset, tile_width, tile_height, **properties):
            
            super(Tilemap, self).__init__(**properties)            
            self.map = map
            self.tileset = tileset
            self.tile_width = tile_width
            self.tile_height = tile_height                    
            self.area = None                    
            
            
        def render(self, width, height, st, at):
                
            render = renpy.Render(width, height)
            
            # Blit all tiles into the render.
            for y in xrange(len(self.map)):
                for x in xrange(len(self.map[y])):
                    render.blit(renpy.render(self.tileset[self.map[y][x]], self.tile_width, self.tile_height, st, at), (x*self.tile_width, y*self.tile_height))
                    
            # Crop the render.
            if self.area == None:
                render = render.subsurface((0, 0, len(self.map[y])*self.tile_width, len(self.map)*self.tile_height))
            else:
                render = render.subsurface(self.area)
                
            return render
            
            
        def per_interact(self):
            
            # Redraw per interact.
            renpy.redraw(self, 0)
            
            
        def visit(self):
           
           # If the displayable has child displayables, this method should be overridden to return a list of those displayables.
           return self.tileset
Last edited by nyaatrap on Thu Nov 12, 2015 9:11 am, edited 4 times in total.

User avatar
nyaatrap
Crawling Chaos
Posts: 1824
Joined: Mon Feb 13, 2012 5:37 am
Location: Kimashi Tower, Japan
Contact:

Re: Tilemap (Creator-Defined Displayable)

#2 Post by nyaatrap » Thu Nov 05, 2015 5:05 am

An example

Code: Select all

init python:
    
    # Define a list of displayables.
    tileset =[Image("water.png"),Image("sand.png"),Image("forest.png"), Image("rock.png")]
        
    # Define a 2-demensional list of integers. Integers should be an index number of a tileset.
    # e.g. 0 stands tileset[0]
    map = [
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
        [0,0,1,1,1,3,3,1,1,1,1,1,1,0,0,0,0],
        [0,1,1,1,1,3,3,3,1,1,1,1,1,1,1,0,0],
        [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
        [1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1],
        [1,1,1,1,1,2,2,2,2,2,2,2,1,1,1,1,1],
        [1,1,1,1,1,2,2,2,2,2,2,2,1,1,1,1,1],
        [1,1,1,1,1,2,2,2,2,2,2,2,1,1,1,1,1],
        [1,1,1,1,1,2,2,2,2,2,2,2,1,1,1,1,1],
        [1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1],
        [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
        [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
        ]
    
    # Create an instance of Tilemap class with following arguments.
    # (map, tileset, tile_width, tile_height).
    tilemap = Tilemap(map, tileset, 64,64)

# Optionally, you can associate it to an image tag
image overworld = tilemap


# The game starts here.
label start:
    
    $ tilemap.area = None
    show overworld at truecenter
    "Showing an entire map"

    $ tilemap.area = (64,64,256,256)
    "Showing only rectangle area of the map"

    return
Last edited by nyaatrap on Sun Nov 08, 2015 8:06 pm, edited 3 times in total.

User avatar
firecat
Miko-Class Veteran
Posts: 540
Joined: Sat Oct 25, 2014 6:20 pm
Completed: The Unknowns Saga series
Projects: The Unknown Saga series
Tumblr: bigattck
Deviantart: bigattck
Skype: bigattck firecat
Soundcloud: bigattck-firecat
Contact:

Re: Tilemap (Creator-Defined Displayable)

#3 Post by firecat » Thu Nov 05, 2015 10:10 am

theres a error on your example:

Code: Select all

[code]
I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 1, in script
    init python:
  File "game/script.rpy", line 27, in <module>
    Tilemap = Tilemap(map, tileset, 64,64)
NameError: name 'Tilemap' is not defined

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/script.rpy", line 1, in script
    init python:
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\ast.py", line 797, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\python.py", line 1448, in py_exec_bytecode
    exec bytecode in globals, locals
  File "game/script.rpy", line 27, in <module>
    Tilemap = Tilemap(map, tileset, 64,64)
NameError: name 'Tilemap' is not defined

Windows-8-6.2.9200
Ren'Py 6.99.6.739
testing1000 0.0
[/code]
Image


Image


special thanks to nantoka.main.jp and iichan_lolbot

User avatar
mobychan
Veteran
Posts: 275
Joined: Fri Apr 24, 2015 6:31 am
Projects: The Chosen - Sakura Pink & Gentian Blue
Organization: Foresoft
Location: Germany
Contact:

Re: Tilemap (Creator-Defined Displayable)

#4 Post by mobychan » Thu Nov 05, 2015 10:30 am

@firecat:
just a guess, but did you implement both code parts?

User avatar
firecat
Miko-Class Veteran
Posts: 540
Joined: Sat Oct 25, 2014 6:20 pm
Completed: The Unknowns Saga series
Projects: The Unknown Saga series
Tumblr: bigattck
Deviantart: bigattck
Skype: bigattck firecat
Soundcloud: bigattck-firecat
Contact:

Re: Tilemap (Creator-Defined Displayable)

#5 Post by firecat » Thu Nov 05, 2015 10:54 pm

mobychan wrote:@firecat:
just a guess, but did you implement both code parts?
oh i thought they were the same, (one test later) still has bugs. nyaatrap forgot to put character in it but thats not the real problem, its this one.

Code: Select all

[code]
I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 96, in script
    e "Showing an entire map"
AttributeError: 'str' object has no attribute 'visit_all'

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/script.rpy", line 96, in script
    e "Showing an entire map"
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\ast.py", line 594, in execute
    renpy.exports.say(who, what, interact=self.interact)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\exports.py", line 1032, in say
    who(what, interact=interact)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\character.py", line 826, in __call__
    self.do_display(who, what, cb_args=self.cb_args, **display_args)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\character.py", line 688, in do_display
    **display_args)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\character.py", line 491, in display_say
    rv = renpy.ui.interact(mouse='say', type=type, roll_forward=roll_forward)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\ui.py", line 277, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\display\core.py", line 2346, in interact
    repeat, rv = self.interact_core(preloads=preloads, **kwargs)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\display\core.py", line 2602, in interact_core
    root_widget.visit_all(lambda i : i.per_interact())
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\display\core.py", line 394, in visit_all
    d.visit_all(callback)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\display\core.py", line 394, in visit_all
    d.visit_all(callback)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\display\core.py", line 394, in visit_all
    d.visit_all(callback)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\display\core.py", line 394, in visit_all
    d.visit_all(callback)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\display\core.py", line 394, in visit_all
    d.visit_all(callback)
  File "C:\Users\angel\Desktop\renpy-6.18.3-sdk\renpy\display\core.py", line 394, in visit_all
    d.visit_all(callback)
AttributeError: 'str' object has no attribute 'visit_all'

Windows-8-6.2.9200
Ren'Py 6.99.6.739
testing1000 0.0
[/code]
Image


Image


special thanks to nantoka.main.jp and iichan_lolbot

User avatar
nyaatrap
Crawling Chaos
Posts: 1824
Joined: Mon Feb 13, 2012 5:37 am
Location: Kimashi Tower, Japan
Contact:

Re: Tilemap (Creator-Defined Displayable)

#6 Post by nyaatrap » Fri Nov 06, 2015 12:41 am

Fixed the example code. The problem was tileset should be list of displayables for the visit method, but "image_path" isn't a displayable. They should have been written Image("image_path"). If tileset is a list of image path strings not general displayables, you can omit the visit method and no need to use Image() on each tiles.
Last edited by nyaatrap on Sun Nov 08, 2015 7:59 pm, edited 1 time in total.

User avatar
trooper6
Lemma-Class Veteran
Posts: 3612
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: Tilemap (Creator-Defined Displayable)

#7 Post by trooper6 » Fri Nov 06, 2015 1:07 am

I made a hex tilemap tester at one point...slightly different than this, but I'll check this out for inspiration as well.
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
nyaatrap
Crawling Chaos
Posts: 1824
Joined: Mon Feb 13, 2012 5:37 am
Location: Kimashi Tower, Japan
Contact:

Re: Tilemap (Creator-Defined Displayable)

#8 Post by nyaatrap » Sun Nov 08, 2015 10:44 pm

An advanced example that uses a spritesheet and a spreadsheet. With this code, you can import a spreadsheet created by a tool like Tiled Map Editor.

Code: Select all

init -2 python:

    class Spritesheet():
        
        @staticmethod
        def create(file, sprite_width, sprite_height, columns, rows, spacing=0, margin=0):
            
            # This creates a list of displayables from one spritesheet.
            
            list = []
            for j in xrange(rows):
                for i in xrange(columns):
                    list.append(LiveCrop(((sprite_width+spacing)*i+margin, (sprite_height+spacing)*j+margin, sprite_width, sprite_height), file))
                    
            return list
           
            
    class Spreadsheet():
        
        @staticmethod
        def create(file, integer=True):
            
            # This creates a 2-dimentional list from one csv or tsv file.
            # If integer is True, default, strings are converted into integers
        
            map=[]
            f = renpy.file(file)
            for l in f:
                if file.endswith(".csv"):
                    a = l.rstrip().split(",")
                else:
                    a = l.rstrip().split("\t")
                mapline=[]
                for c in a:
                    if integer:
                        c = int(c)
                    mapline.append(c)
                map.append(mapline)
            f.close()
                
            return map

Code: Select all

init python:

    # Define a list of displayables from spritesheet with the following arguments.
    # (file, sprite_width, sprite_height, columns, rows, spacing=0, margin=0)
    tileset = Spritesheet.create("tiles.png", 32, 32, 8, 6, 1, 1)
        
    # Define a 2-demensional list from spreadsheet
    map = Spreadsheet.create("map.csv")
    
    # Create an instance of Tilemap class with following arguments.
    # (map, tileset, tile_width, tile_height).
    
    tilemap = Tilemap(map, tileset, 32, 32)

User avatar
nyaatrap
Crawling Chaos
Posts: 1824
Joined: Mon Feb 13, 2012 5:37 am
Location: Kimashi Tower, Japan
Contact:

Re: Tilemap (Creator-Defined Displayable)

#9 Post by nyaatrap » Thu Nov 12, 2015 12:11 pm

More advanced demo that allows scrolling a huge map.
Clipboard 1.jpg
tilemap-1.0-all.zip
(26.31 MiB) Downloaded 165 times
This demo uses 500x500 tiles for performance test. It should work even on 5000x5000 tiles, because it only blits surfaces around shown area.
I confirmed it shows displayables fast, and memory usage is low. However, there's one problem - the quality is scrolling is not beautiful. I think it's because of that it uses a simple crop method with no sub-sampling. If someone knows how to make it smoother, let me know.
PS: The demo contains a tileset image from Tiled map editor. I couldn't find a license on this image. If there's a problem on it, please tell me.

User avatar
Yukari
Regular
Posts: 119
Joined: Sun Feb 06, 2011 6:28 am
Completed: Aozora Meikyuu, Yozora Rhapsody, Imolicious, Yume Puzzle
Projects: Games&Girls, Fuyuzora Rumble
Organization: Yume Creations
Tumblr: yumecreationsvn
Location: Germany
Contact:

Re: Tilemap (Creator-Defined Displayable)

#10 Post by Yukari » Sun Apr 10, 2016 12:37 pm

How can I add a sprite of a character whoo can walking around? And how can I click on tiles and show text etc?
Image

User avatar
nyaatrap
Crawling Chaos
Posts: 1824
Joined: Mon Feb 13, 2012 5:37 am
Location: Kimashi Tower, Japan
Contact:

Re: Tilemap (Creator-Defined Displayable)

#11 Post by nyaatrap » Sun Apr 10, 2016 12:45 pm

It's possible but I don't suggest... actually, I dropped this project for performance issue. I'd like to know if there's way to add something without performance lose.
It's not hard to add something, but it apparently shows lags on my core i3 laptop. core i5 plus more graphic board is minimum - is not something for ren'py game.

User avatar
zankizuna
Veteran
Posts: 402
Joined: Fri May 04, 2012 2:20 am
Projects: Softwar
Deviantart: raseru09
itch: ZanKizuna
Location: Manilaaaaaaaa
Contact:

Re: Tilemap (Creator-Defined Displayable)

#12 Post by zankizuna » Wed Jun 12, 2019 1:41 pm

Oh my gosh, i thought i was the only one working on a tilemap, this is amazing!
Here's my sample uguu
Our map code does look pretty similar!
Posts like these are so underappreciated hahaha

https://youtu.be/IK-aNQswghA

M-77
Regular
Posts: 51
Joined: Tue Sep 04, 2018 7:58 am
Contact:

Re: Tilemap (Creator-Defined Displayable)

#13 Post by M-77 » Sat Jun 15, 2019 2:50 pm

Hello "zankizuna"! (And hello "nyaatrap" too) I watched your video. Can you provide us your code of the tilemap, or just the one for the movement, here please? I would like to combine it to my purpose when I have free time. I like to do a tilmap+movement+maybe a companion following (in some events)+action points (if clicked or hit ENTER) go to next screen or back to VN/txt story again. No battle system need for my project. This is interessting, one could add this in a VN to have some cutscene/as mini game. For distraction, like find the right chest in this maze.

User avatar
zankizuna
Veteran
Posts: 402
Joined: Fri May 04, 2012 2:20 am
Projects: Softwar
Deviantart: raseru09
itch: ZanKizuna
Location: Manilaaaaaaaa
Contact:

Re: Tilemap (Creator-Defined Displayable)

#14 Post by zankizuna » Sun Jun 16, 2019 12:49 pm

M-77 wrote:
Sat Jun 15, 2019 2:50 pm
Hello "zankizuna"! (And hello "nyaatrap" too) I watched your video. Can you provide us your code of the tilemap, or just the one for the movement, here please?
Thanks for watching ♡
My code is a bit unorganized, but i should make it available soon! I was planning to upload it on itch.io for sale or free but i need to make it easier to customize first. (It's a mess but it works)

If you had keys to my dev-team-only demo you will find its code is open source, but that's for our team only...

Please wait i guess.
I'd love to share it!

User avatar
zankizuna
Veteran
Posts: 402
Joined: Fri May 04, 2012 2:20 am
Projects: Softwar
Deviantart: raseru09
itch: ZanKizuna
Location: Manilaaaaaaaa
Contact:

Re: Tilemap (Creator-Defined Displayable)

#15 Post by zankizuna » Mon Jun 17, 2019 10:32 am

Maybe try this?
Attachments
Movement.rpy
(41.64 KiB) Downloaded 25 times

Post Reply

Who is online

Users browsing this forum: No registered users