Forum Archive

How do I combine two scenes?

janaaron97

I would like for someone to show me how to combine these two scenes into one:

from scene import *
class dumb (Scene):
    def setup(self):
        self.x = self.size.w * 0.5
        self.y = self.size.h * 0.5
    def draw(self):
        background(0.00, 0.00, 0.00)
        fill(1.00,1.00,1.00)
        g = gravity()
        self.x += g.x * 10
        self.y += g.y * 10 
        self.x = min(self.size.w - 100, max(0, self.x))
        self.y = min(self.size.h - 100, max(0, self.y))
        ellipse(self.x,self.y,100,100)



class real (Scene):
    def setup(self):
        self.x = self.size.w * 0.4
        self.y = self.size.h * 0.4
    def draw(self):
        background(0.00, 0.00, 0.00)
        fill(1.00,1.00,1.00)
        g = gravity()
        self.x += g.x * 10
        self.y += g.y * 10 
        self.x = min(self.size.w - 100, max(0, self.x))
        self.y = min(self.size.h - 100, max(0, self.y))
        rect(self.x,self.y,100,100)


run(dumb())
run(real())
zencuke

Use only one screen class and draw both shapes (rect and ellipse) in the draw method of the single class.

janaaron97

Is this what you meant?

from scene import *
class dumb (Scene):
    def setup(self):
        self.x = self.size.w * 0.5
        self.y = self.size.h * 0.5
    def draw(self):
        background(0.00, 0.00, 0.00)
        fill(1.00,1.00,1.00)
        background(0.00, 0.00, 0.00)
        fill(1.00,1.00,1.00)
        g = gravity()
        self.x += g.x * 10
        self.y += g.y * 10
        self.x = min(self.size.w - 100, max(0, self.x))
        self.y = min(self.size.h - 100, max(0, self.y))
        ellipse(self.x,self.y,100,100)
        rect(self.x,self.y,100,100)
run(dumb())

I tried that and it didn't work.

wradcliffe

@janaaron97 - you kind of got the right idea and the code actually does work. You should notice that you are drawing the circle first and then the box so the box is covering up the circle. Switch these around and you should see a box with a circle inside it. However, you need to go further and keep the position and size of each of these independent of each other. This is where you need decide how to build your program. There are numerous ways to go about it. You will want to take a look at Layers as one way. You need to look at some basic docs and tutorials to see what your tools are and then try to use them. Have a look at the Scene tutorial at: https://github.com/humberry/scene-tutorial first and also take a look at some of the games provided that use gravity like CloudJump

dgelessus

The code looks all right to me... what exactly do you mean, "it didn't work"? Did it raise an error? Did it not do what you expected/wanted? Did Pythonista crash? When something doesn't work like it should, please give enough details so we can understand what you are trying to do and what exactly goes wrong.

Anyway, I think I can imagine what you are thinking what the program does. I'll go over the draw method in a little detail:

background(0.00, 0.00, 0.00)
fill(1.00,1.00,1.00)
background(0.00, 0.00, 0.00)
fill(1.00,1.00,1.00)

The background function clears the scene and fills it with a single color, in this case black. fill sets the color used when drawing shapes (rectangles, ellipses), but doesn't do anything immediately. (There's no need to call these functions twice, because you're just repeating what you did before.)

g = gravity()
self.x += g.x * 10
self.y += g.y * 10
self.x = min(self.size.w - 100, max(0, self.x))
self.y = min(self.size.h - 100, max(0, self.y))

These statements get the device rotation, do some math and bounds checking and move self.x and self.y, which are later used when drawing the shapes.

ellipse(self.x,self.y,100,100)
rect(self.x,self.y,100,100)

Here's where your problem is (probably). ellipse draws an ellipsis (in this case a circle) with the given coordinates and size. rect does the same, but draws a rectangle (in this case a square). Because both the circle and the square are drawn in exactly the same spot, the square hides the circle.

Even when swapping these two statements so the circle is drawn second, you'll still only see a white square - remember that at the beginning the fill color is set to white, this applies to both the square and the circle. If you want to use different colors for the two shapes, you need to call fill again in between.

Here's a modified version of the draw method, which draws the circle on top of the square and using a different color. Look at the differences between the two versions and you'll probably understand what's going on.

    def draw(self):
        background(0.0, 0.0, 0.0)

        g = gravity()
        self.x += g.x * 10
        self.y += g.y * 10
        self.x = min(self.size.w - 100, max(0, self.x))
        self.y = min(self.size.h - 100, max(0, self.y))

        fill(1.0, 0.0, 0.0)
        rect(self.x, self.y, 100, 100)

        fill(0.0, 0.0, 1.0)
        ellipse(self.x, self.y, 100, 100)
ccc

Or use scene.Layers...

import scene

#color_black = scene.Color(0, 0, 0, .5)
#color_white = scene.Color(1, 1, 1, .5)
color_red   = scene.Color(1, 0, 0, .5)
color_green = scene.Color(0, 1, 0, .5)
color_blue  = scene.Color(0, 0, 1, .5)

class Circle(scene.Layer):
    def __init__(self, in_rect):
        super(self.__class__, self).__init__(in_rect)
        self.background = color_blue
        self.stroke     = color_green
        self.stroke_weight = 1

    def draw(self, a=1):
        super(self.__class__, self).draw()
        g = scene.gravity()
        self.frame.x += g.x * 10
        self.frame.y += g.y * 10
        scene.ellipse(self.frame.x, self.frame.y, self.frame.w, self.frame.h)

class Square(scene.Layer):
    def __init__(self, in_rect):
        super(self.__class__, self).__init__(in_rect)
        self.background = color_red
        self.stroke     = color_green
        self.stroke_weight = 1

    def draw(self, a=1):
        super(self.__class__, self).draw()
        g = scene.gravity()
        self.frame.x += g.x * 10
        self.frame.y += g.y * 10

class MyScene(scene.Scene):
    def __init__(self):
        scene.run(self)

    def setup(self):
        x, y = self.bounds.center()
        self.add_layer(Circle(scene.Rect(x-150, y-150, 100, 100)))
        self.add_layer(Square(scene.Rect(x+50, y+50, 100, 100)))

    def draw(self):
        scene.background(0, 0, 0)
        self.root_layer.update(self.dt)
        self.root_layer.draw()

MyScene()
janaaron97

Thank you guys very much. That helps!