Any issue with skipping calls to renpy.render?

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
esrix
Regular
Posts: 28
Joined: Wed May 28, 2008 11:12 pm
Contact:

Any issue with skipping calls to renpy.render?

#1 Post by esrix »

I'm trying to incorporate a Pac-Man like game using a custom displayable and I plan on having a lot of entities (player character, enemies, pickups) running around on the screen. I am considering writing a sort of resource manager in a separate python class and using the Image function to load the image files and grabbing a render from them shortly afterwards.

With the pong minigame that ships with Ren'Py demo, I noticed this in the ball and paddles uses the following code every time the court is rendered:

Code: Select all

renpy.render(displayable, width, height, st, at)
I know it creates a render that can be blitted to the screen. What I'm wondering is if there is any consequence for not doing this on every render? For example, the following test code seems to work:

Code: Select all

    python:
        class dungeon(renpy.Displayable):
            def __init__(self):
                renpy.Displayable.__init__(self)
                self.x = 0
                self.y = 0
                self.img = Image( "ramza_sprite.png" ) #our hero
                self.ramza = renpy.render(self.img, 800, 600, 0, 0) #our hero's image
                self.left = 0
                self.right = 0
                self.up = 0
                self.down = 0

            def visit(self):
                return []
                
            # Updates the Mr. Ramza's position
            def render(self, width, height, st, at):

                # The Render object we'll be drawing into.
                r = renpy.Render(width, height)
                
                #movement
                if self.left == 1:
                    self.x-=1
                if self.right == 1:
                    self.x+=1
                if self.up == 1:
                    self.y-=1
                if self.down == 1:
                    self.y+=1
                #draw Ramza
                r.blit( self.ramza, (self.x, self.y) )
                renpy.redraw(self, 0)

                # Return the Render object.
                return r
                
            # Handles events.
            def event(self, ev, x, y, st):
                import pygame
                if ev.type == pygame.MOUSEBUTTONDOWN and ev.button == 1:
                    return 1
                else:
                    if ev.type == pygame.KEYDOWN or ev.type == pygame.KEYUP:
                        val = 0
                        if ev.type == pygame.KEYDOWN:
                            val = 1
                        
                        if ev.key == pygame.K_LEFT:
                            self.left = val
                        elif ev.key == pygame.K_RIGHT:
                            self.right = val
                        elif ev.key == pygame.K_UP:
                            self.up = val
                        elif ev.key == pygame.K_DOWN:
                            self.down = val
                        elif ev.key == pygame.K_SPACE:
                            renpy.call_in_new_context( "rawr" )
                    else:
                        raise renpy.IgnoreEvent()
The difference here is that renpy.render(self.img, 800, 600, 0, 0) is called in the displayable constructor. It seems like I could possibly gain a little bit of performance by not calling it for every entity each time it rendered. But I also know the demos are written the way they are for a reason.

Any thoughts?

User avatar
PyTom
Ren'Py Creator
Posts: 16096
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: Any issue with skipping calls to renpy.render?

#2 Post by PyTom »

The render contains image data, which isn't saved. So if you were to save a game with a render in it, it wouldn't be loadable.

renpy.render caches its result, so there's little reason not to call it. While the first call might be slow, the second and subsequent calls will be very fast.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

esrix
Regular
Posts: 28
Joined: Wed May 28, 2008 11:12 pm
Contact:

Re: Any issue with skipping calls to renpy.render?

#3 Post by esrix »

Alrighty. I'll try to plan my resource manager around calling renpy.render.

Thanks, PyTom.

User avatar
killdream
Veteran
Posts: 325
Joined: Wed Nov 05, 2008 1:05 pm
Projects: EVūL (WIP), insilo (WIP), Cute Demon Crashers!
Deviantart: robotlolita
Github: robotlolita
Location: World's End (aka Brazil)
Contact:

Re: Any issue with skipping calls to renpy.render?

#4 Post by killdream »

Other reason to call renpy.render at every frame is that if you're using an animation you'll have to update the image data, right?

And rule number 1 in programming says: NEVER try to optimize your code unless your really needs to. Optimizing takes some time and effort you could use into making other things and makes your code hard to maintain and debug D:

If your code is running slow after you finish it you can use profiling (Python comes with a cProfile module, but I'm not sure it's included in Ren'Py, so you'd probably have to copy it to your game folder) to see where you need to applicate your efforts in optimizing ^^

esrix
Regular
Posts: 28
Joined: Wed May 28, 2008 11:12 pm
Contact:

Re: Any issue with skipping calls to renpy.render?

#5 Post by esrix »

killdream wrote:Other reason to call renpy.render at every frame is that if you're using an animation you'll have to update the image data, right?
Yeah, I realized that last night right before I headed for bed.
killdream wrote:And rule number 1 in programming says: NEVER try to optimize your code unless your really needs to. Optimizing takes some time and effort you could use into making other things and makes your code hard to maintain and debug D:
No harm in me asking, though. Besides, if I ask, I could potentially learn something :D

Actually, another technical question while I'm at it: Is there any way to scale or rotate a render?

User avatar
killdream
Veteran
Posts: 325
Joined: Wed Nov 05, 2008 1:05 pm
Projects: EVūL (WIP), insilo (WIP), Cute Demon Crashers!
Deviantart: robotlolita
Github: robotlolita
Location: World's End (aka Brazil)
Contact:

Re: Any issue with skipping calls to renpy.render?

#6 Post by killdream »

Assuming renders are PyGame's surfaces, you can use the transform module in them.

Here's ugly example:

Code: Select all

import pygame
from pygame.locals import * # we shouldn't pollute namespace, but whatever

# given we have a variable render_surface that contains a rendered surface
# we should double its size and rotate it counter-clockwise 45 degrees =D
pygame.transform.rotozoom(render_surface, 2.0, -45)

User avatar
PyTom
Ren'Py Creator
Posts: 16096
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: Any issue with skipping calls to renpy.render?

#7 Post by PyTom »

Renders are not a pygame surface. But you can just render a RotoZoom or Transform... which will be more efficient when parts of the image are unchanged off-screen.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

esrix
Regular
Posts: 28
Joined: Wed May 28, 2008 11:12 pm
Contact:

Re: Any issue with skipping calls to renpy.render?

#8 Post by esrix »

So if I wanted to rotate Ramza 45 degrees and scale him up by 50%, it would be something like this?

Code: Select all

		ramza = im.Rotozoom(self.img, 45, 1.5)
		r.blit( ramza, (self.x, self.y) )
I'd test it otherwise, but I'm not at my home computer quite yet.

How would the Transform function be used for this?

esrix
Regular
Posts: 28
Joined: Wed May 28, 2008 11:12 pm
Contact:

Re: Any issue with skipping calls to renpy.render?

#9 Post by esrix »

Ah, I think I got it now:

Code: Select all

                t = Transform( self.img, None, 0.5, self.x, 1.5 )
                ramza = renpy.render( t, 800, 600, st, at)
Works rather well and rotates around the center, too :)

Post Reply

Who is online

Users browsing this forum: Majestic-12 [Bot]