Forum Archive

My code won’t work

Slimebot32

I’m making a basic game (I’m new to python) and am wondering why the app freezes when I try to run this code.

import time
import random
from scene import *

class MyScene (Scene):
    def setup(self):
        self.background_color = '#6F6'
        self.ship = SpriteNode('spc:PlayerShip3Green')
        self.ship.position = self.size / 3
        self.add_child(self.ship)
        self.meteor = SpriteNode('spc:MeteorGrayBig4')
        while True:
            self.meteor.position = random.randint(0, 1000), random.randint(0, 750)
            self.add_child(self.meteor)
            time.sleep(1)

    def touch_moved(self, touch):
        x, y = touch.location
        move_action = Action.move_to(x, y, 0.3)
        move_action2 = Action.move_to(x, y, 1)
        self.ship.run_action(move_action)
        self.meteor.run_action(move_action2)

run(MyScene(), show_fps=True)
JonB

Scene is a little special. You must have a setup method, which returns once the scene is setup. Then, the engine calls update() or draw() at the fps rate. All scene methods should be written to exit quickly, as you don't actually directly change what is shown on screen -- instead the engine checks the state after update exits and renders the new positions on screen. Never use sleep, or have while True loops, etc, since that won't work the way you want.

Instead, you need to think in terms of time, or actions.

Take a look in your Examples folder, you will find a good game tutorial that walks you through a game in the scene module.

In your case your while True statement means setup never exits, and the scene never starts.

Slimebot32

Sorry, but I’m confused why spawn_meteor says it isn’t defined
```
import time
import random
from scene import *

class game (Scene):
def setup(self):
self.background_color = '#6F6'
self.ship = SpriteNode('spc:PlayerShip3Green')
self.ship.position = self.size / 3
self.add_child(self.ship)
self.meteor = SpriteNode('spc:MeteorGrayMed1')
def spawn_meteor():
self.add_child(self.meteor)
self.meteor.position = random.randint(0, 1000), random.randint(0, 750)

def update(self):
    if random.randint(0, 1000) == 1:
        spawn_meteor()

def touch_moved(self, touch):
    x, y = touch.location
    move_action = Action.move_to(x, y, 0.3)
    move_action2 = Action.move_to(x, y, 1)
    self.ship.run_action(move_action)
    self.meteor.run_action(move_action2)

run(game(), show_fps=True)```

mikael

@Slimebot32, you are missing self both in the method definition and in the way you are calling it. Look at the other methods for reference.

Slimebot32

Thanks! I’m also wondering how to make multiple children of meteor at once, is this possible?

```
import time
import random
from scene import *

class game (Scene):
def setup(self):
self.background_color = '#6F6'
self.ship = SpriteNode('spc:PlayerShip3Green')
self.ship.position = self.size / 3
self.add_child(self.ship)
self.meteor = SpriteNode('spc:MeteorGrayMed1')
def spawn_meteor(self):
self.add_child(self.meteor)
self.meteor.position = random.randint(0, 1000), random.randint(0, 750)

def update(self):
    if random.randint(0, 100) == 1:
        self.spawn_meteor()

def touch_moved(self, touch):
    x, y = touch.location
    move_action = Action.move_to(x, y, 0.3)
    move_action2 = Action.move_to(x, y, 1)
    self.ship.run_action(move_action)
    self.meteor.run_action(move_action2)

run(game(), show_fps=True)```

mikael

@Slimebot32, have a variable self.meteors which is a set(). In spawn, add a new SpriteNode to it and also add_child it to the scene. Whenever you need to e.g. move the meteors, go through all the meteors in the set (for meteor in self.meteors:).

Slimebot32

Thanks, how do you add_child for a set()?