[SOLVED] Creator Defined Displayable re-initializes when calling/invoking new context(I think?)
Posted: Sun Apr 18, 2021 4:58 pm
So I've cobbled together a relatively simple isometric exploration CDD, based on a few different approaches I've found here on the forum. However I've noticed that whenever I either try to use the normal dialogue system or perform an action that creates a new context (Like opening the menu or the confirmation UI when you try to close the window I believe?), the CDD gets re-initialized and resets the character back to their start position. I'm not sure if the dialogue system also uses contexts or if that's actually a whole different issue, but based off what I've understood about creating new contexts at least, that doesn't seem like the intended effect. So I'm wondering if there may be something I've set up strangely or if I've fundamentally misunderstood how some part of this is supposed to work.
I've provided a stripped down version of the class working in a project since that's probably the quickest way to see what I mean. For the record, you use the arrow keys to move around and space to interact when the exclamation point is visible, with the interaction points being the red, green, and blue colored squares. You still have to click to progress through the interaction dialogue.
I also included an alternate script file in the root "test" folder, where I tried working around the issue by using a variable outside the class with position values that it would theoretically write to before the reset is triggered, and then use when it was re-initialized so nothing would appear to change. I couldn't seem to get that to work either though.
Here's the class specifically for ease of viewing. (Also excuse the code itself possibly still being a bit rough. I haven't quite gotten to the point of shoring things up yet. lol)
Any guidance on how to potentially correct or work around this behavior would be greatly appreciated!
I've provided a stripped down version of the class working in a project since that's probably the quickest way to see what I mean. For the record, you use the arrow keys to move around and space to interact when the exclamation point is visible, with the interaction points being the red, green, and blue colored squares. You still have to click to progress through the interaction dialogue.
I also included an alternate script file in the root "test" folder, where I tried working around the issue by using a variable outside the class with position values that it would theoretically write to before the reset is triggered, and then use when it was re-initialized so nothing would appear to change. I couldn't seem to get that to work either though.
Here's the class specifically for ease of viewing. (Also excuse the code itself possibly still being a bit rough. I haven't quite gotten to the point of shoring things up yet. lol)
Code: Select all
class ExplorationScreen(renpy.Displayable):
def __init__(self):
renpy.log('Initializing ExplorationScreen!')
super(renpy.Displayable, self).__init__()
# sprite setup
self.sprite = front
self.bang = 'images/bang.png'
# bg
self.iso = 'images/iso.png'
self.iso_map = renpy.load_surface('images/iso.png')
self.pause_input = False
self.orientation = 1
self.direction = ''
self.pos_x = 640
self.pos_y = 360
self.dpos_x = 0.5
self.dpos_y = 0.5
self.speed_x = 0.0
self.speed_y = 0.0
self.last_st = None
self.last_x = 0
self.last_y = 0
def get_map_color(self, x, y):
try:
pos_color = self.iso_map.get_at((x,y)) [:3]
except IndexError:
pos_color = -1
finally:
return pos_color
def check_map(self, x, y):
pos_color = self.get_map_color(x, y)
new_x = x
new_y = y
if pos_color != -1:
if pos_color == (0, 0, 0):
if self.direction == 'l':
if self.get_map_color(self.last_x - 1, self.last_y + 1) != (0, 0, 0):
new_x = self.last_x - 1
new_y = self.last_y + 1
else:
new_x = self.last_x
new_y = self.last_y
elif self.direction == 'u':
if self.get_map_color(self.last_x - 1, self.last_y - 1) != (0, 0, 0):
new_x = self.last_x - 1
new_y = self.last_y - 1
else:
new_x = self.last_x
new_y = self.last_y
elif self.direction == 'd':
if self.get_map_color(self.last_x + 1, self.last_y + 1) != (0, 0, 0):
new_x = self.last_x + 1
new_y = self.last_y + 1
else:
new_x = self.last_x
new_y = self.last_y
elif self.direction == 'r':
if self.get_map_color(self.last_x + 1, self.last_y - 1) != (0, 0, 0):
new_x = self.last_x + 1
new_y = self.last_y - 1
else:
new_x = self.last_x
new_y = self.last_y
else:
new_x = self.last_x
new_y = self.last_y
return new_x, new_y
def check_interact(self, x, y):
pos_color = self.get_map_color(x, y)
if pos_color == (255, 0, 0):
renpy.log('Starting Interaction 1!')
renpy.jump('interaction_1')
elif pos_color == (0, 255, 0):
renpy.log('Starting Interaction 2!')
renpy.jump('interaction_2')
elif pos_color == (0, 0, 255):
renpy.log('Starting Ending Interaction!')
renpy.jump('interaction_end')
def render(self, width, height, st, at):
base = renpy.displayable(self.iso)
r = renpy.render(base, width, height, st, at)
if self.last_st is None:
self.last_st = st
dtime = st - self.last_st
self.last_st = st
self.last_x = self.pos_x
self.last_y = self.pos_y
move_x = dtime * self.speed_x
move_y = dtime * self.speed_y
self.pos_x += self.dpos_x * move_x
self.pos_y += self.dpos_y * move_y
map_check_results = self.check_map(self.pos_x, self.pos_y)
self.pos_x = map_check_results[0]
self.pos_y = map_check_results[1]
char = Transform(self.sprite, xanchor=0.5, yanchor=0.75, xzoom=self.orientation)
r.place(char, self.pos_x, self.pos_y)
pos_color = self.get_map_color(self.pos_x, self.pos_y)
if pos_color == (255, 0, 0):
bang = Transform(self.bang, xanchor=0.5, yanchor=1.0)
r.place(bang, self.pos_x, self.pos_y)
elif pos_color == (0, 255, 0):
bang = Transform(self.bang, xanchor=0.5, yanchor=1.0)
r.place(bang, self.pos_x, self.pos_y)
elif pos_color == (0, 0, 255):
bang = Transform(self.bang, xanchor=0.5, yanchor=1.0)
r.place(bang, self.pos_x, self.pos_y)
renpy.redraw(self, 0)
return r
def event(self, ev, x, y, st):
rate_x = 400.0
rate_y = 200.0
if not self.pause_input:
if ev.type == pygame.KEYDOWN:
if ev.key == pygame.K_LEFT:
self.sprite = back
self.orientation = 1
self.direction = 'l'
self.speed_x = -rate_x
self.speed_y = -rate_y
renpy.redraw(self, 0)
raise renpy.IgnoreEvent()
elif ev.key == pygame.K_RIGHT:
self.sprite = front
self.orientation = -1
self.direction = 'r'
self.speed_x = rate_x
self.speed_y = rate_y
renpy.redraw(self, 0)
raise renpy.IgnoreEvent()
elif ev.key == pygame.K_UP:
self.sprite = back
self.orientation = -1
self.direction = 'u'
self.speed_x = rate_x
self.speed_y = -rate_y
renpy.redraw(self, 0)
raise renpy.IgnoreEvent()
elif ev.key == pygame.K_DOWN:
self.sprite = front
self.orientation = 1
self.direction = 'd'
self.speed_x = -rate_x
self.speed_y = rate_y
renpy.redraw(self, 0)
raise renpy.IgnoreEvent()
elif ev.key == pygame.K_SPACE:
self.check_interact(self.pos_x, self.pos_y)
raise renpy.IgnoreEvent()
elif ev.type == pygame.KEYUP:
if ev.key == pygame.K_LEFT:
self.sprite = back
self.orientation = 1
self.speed_x = 0
self.speed_y = 0
raise renpy.IgnoreEvent()
elif ev.key == pygame.K_RIGHT:
self.sprite = front
self.orientation = -1
self.speed_x = 0
self.speed_y = 0
raise renpy.IgnoreEvent()
elif ev.key == pygame.K_UP:
self.sprite = back
self.orientation = -1
self.speed_x = 0
self.speed_y = 0
raise renpy.IgnoreEvent()
elif ev.key == pygame.K_DOWN:
self.sprite = front
self.orientation = 1
self.speed_x = 0
self.speed_y = 0
raise renpy.IgnoreEvent()
return None