[SOLVED] Arithmetic needed to animate a numeric counter

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
CharlieFuu69
Regular
Posts: 30
Joined: Mon Nov 11, 2019 10:32 pm
Projects: Current projects using Ren'Py : "Tears: The First Love!" (Visual Novel at 90%) , "ElectroBasics Electronic Quiz!" (Educative game at 45%).
Location: Chile
Contact:

[SOLVED] Arithmetic needed to animate a numeric counter

#1 Post by CharlieFuu69 » Sun Feb 20, 2022 5:47 pm

Hello boys. I have tried to implement an animated count similar to AnimatedValue(), but to animate numbers.

This is the code I have created:

Code: Select all

class AnimatedCounter:

    def __init__(self, hit, delay):
        self.hit = hit ## The value to be reached
        self.delay = delay ## The time it takes to get from 0 to self.hit
            
        self.update_rate = None ## Used to calculate the update interval
        self.update_count = 0 ## The current count

    def count(self, st, at):
        if self.update_rate is None:
            self.update_rate = self.delay / self.hit

        if self.update_count < self.hit:
            self.update_count += 1

        return Text("%s" % self.update_count), self.update_rate
I make it work like this:

Code: Select all

screen anim_num(delay, hit):
    default counter = AnimatedCounter(hit = hit, delay = delay)
    add DynamicDisplayable(counter.count) align(0.5, 0.5)
The code runs the count in an animated way and it works fine, except for one thing. The time it should take to count from 0 to self.hit is given by self.delay , which is used to calculate the refresh interval in self.update_rate.
This should work fine, but the time it takes to get from 0 to self.hit isn't appropriate, and I'm very aware that it's a bug in the arithmetic I'm using to calculate the update interval.

The calculation runs on:

Code: Select all

if self.update_rate is None:
    self.update_rate = self.delay / self.hit
What I need at this point is some advice or help to find the correct calculation for this operation, since the code itself works correctly, except for the count delay.

I appreciate the help guys!
Last edited by CharlieFuu69 on Sun Feb 20, 2022 7:41 pm, edited 1 time in total.

User avatar
Ocelot
Eileen-Class Veteran
Posts: 1883
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: Arithmetic needed to animate a numeric counter

#2 Post by Ocelot » Sun Feb 20, 2022 6:26 pm

Your problem isn't with arithmetics. The value you return from your function is not binding. It merely means that function will be called again before that much time passes. It is completely possible that function will be called again before time specified. You need to keep track of time passed yourself. This is what st and at are for.

If you wish to keep your code structure like you already have, you can change your class as following:

Code: Select all

    class AnimatedCounter:
        def __init__(self, hit, delay=1.0, start=0):
            self.value = start # Current value
            self.hit = hit # The value to be reached
            self.delay = delay ## The time it takes to get from 0 to self.hit

            self.update_rate = float(self.delay) / abs(self.hit - self.value)
            self.last_hit = None # last time updated
            self.update_displayable()

        def update_displayable(self):
            self.displayable = Text("%s" % self.value)

        def count(self, st, at):
            if self.value == self.hit:
                return self.displayable, None

            if self.last_hit is None:
                self.last_hit = st

            if (self.last_hit + self.update_rate) < st:
                self.last_hit = st
                self.value += (1 if (self.value < self.hit) else -1)
                self.update_displayable()

            return self.displayable, self.last_hit + self.update_rate - st
There are some improvements: you can specify starting value as well as target, it supports both increasing and decreasing counters, caches displayable for perfomance reasons and stops updating when it reaches the goal.
< < insert Rick Cook quote here > >

User avatar
CharlieFuu69
Regular
Posts: 30
Joined: Mon Nov 11, 2019 10:32 pm
Projects: Current projects using Ren'Py : "Tears: The First Love!" (Visual Novel at 90%) , "ElectroBasics Electronic Quiz!" (Educative game at 45%).
Location: Chile
Contact:

Re: [SOLVED] Arithmetic needed to animate a numeric counter

#3 Post by CharlieFuu69 » Sun Feb 20, 2022 7:43 pm

Wooah, I see I messed up over something too small. It never crossed my mind to apply the code that way.
Thanks for the help!!!

Post Reply

Who is online

Users browsing this forum: span4ev