Hysocs
Newbie
- Mar 5, 2024
- 18
- 6
Ok, so somewhere a while back, I played a game that had a map you could drag around, etc. So, I went out of my way to make one for my game. I tried to do this on a screen by setting a viewport and displaying my image for the map into it. However, I ran into an issue when I then added a frame or any clickable UI elements; it prevented scrolling in the viewport.
I tried so many things, like separating the image and UI into vbox and hbox. It restored the viewport, but the UI didn't follow it. I did end up getting something that works 100%, but I ended up switching to Python and using Pygame to create my own custom module that could detect mouse events and that could be added to the screen's viewport. It's working all fine and dandy; it's just the logic is really large, 200 lines. So, I was wondering if I could indeed pull this off in Ren'Py only and not need to do Python logic.
this is what i got so far
You might think 200 lines isn't bad, but I haven't integrated it into any other systems yet. After integrations, it's going to be quite large and probably slow down a lot, especially since I will be displaying images for the NPCs present at locations.
I would prefer to handle it as a viewport with a square size and place image buttons inside of it. I'm hoping someone here knows how to get the viewport to function with an image and clickable objects on top of it. If I remove the image, it works; for instance, if I add a frame that's blank. I mean, I do scrollable menus all the time. It's just something wonky with Ren'Py and images on top of images in a viewport.
I feel like using Pygame for mouse events will probably cause issues later especially on other platforms
If it's possible, I will just redo my code and handle it via a screen instead of this. It's mainly because I'm lazy and don't want to write any more logic. It took me hours to get hovering over the button to work properly.
I tried so many things, like separating the image and UI into vbox and hbox. It restored the viewport, but the UI didn't follow it. I did end up getting something that works 100%, but I ended up switching to Python and using Pygame to create my own custom module that could detect mouse events and that could be added to the screen's viewport. It's working all fine and dandy; it's just the logic is really large, 200 lines. So, I was wondering if I could indeed pull this off in Ren'Py only and not need to do Python logic.
this is what i got so far
You must be registered to see the links
You might think 200 lines isn't bad, but I haven't integrated it into any other systems yet. After integrations, it's going to be quite large and probably slow down a lot, especially since I will be displaying images for the NPCs present at locations.
I would prefer to handle it as a viewport with a square size and place image buttons inside of it. I'm hoping someone here knows how to get the viewport to function with an image and clickable objects on top of it. If I remove the image, it works; for instance, if I add a frame that's blank. I mean, I do scrollable menus all the time. It's just something wonky with Ren'Py and images on top of images in a viewport.
I feel like using Pygame for mouse events will probably cause issues later especially on other platforms
Python:
# how its used in a screen
side "c b r":
viewport id "map_viewport":
draggable True
mousewheel True
xinitial 400
yinitial 500
add DraggableMap("images/Map2.png", 2000, 2000, buttons)
bar value XScrollValue("map_viewport")
vbar value YScrollValue("map_viewport")
#this is how im rendering the image. i use another class for buttons, this isnt all of the logic
class DraggableMap(renpy.Displayable):
def __init__(self, image, width, height, buttons, **properties):
super(DraggableMap, self).__init__(**properties)
self.image = renpy.easy.displayable(image)
self.image_width = width
self.image_height = height
self.buttons = buttons
def render(self, width, height, st, at):
render = renpy.Render(self.image_width, self.image_height)
base = renpy.render(self.image, self.image_width, self.image_height, st, at)
render.blit(base, (0, 0))
for button in self.buttons:
button.render(render)
return render
# here im using pygame to handle clicking and i also handle alot of button logic with it also
def event(self, ev, x, y, st):
hover_changed = False
for button in self.buttons:
if button.check_hover(x, y):
if not button.hovering:
button.on_hover()
button.hovering = True
hover_changed = True
if ev.type == pygame.MOUSEBUTTONUP:
button.on_click()
return None
else:
if button.hovering:
button.on_leave()
button.hovering = False
hover_changed = True
if hover_changed:
renpy.redraw(self, 0) # Redraw the map if any button's hover state changed
return None