Forum Archive

Random Invalid Syntax Error after defining a function

techteej

Hi all. I'm working on adding a high score to the Cloud Jump game previously posted on here, along with character selection. For the high score though, in it's own program, it works fine. But when I add it to this program, I get a Invalid Syntax error.

from scene import *
from sound import load_effect, play_effect
from random import randint, random
import console
import pickle
import os

IMAGE_WIDTH = 101
IMAGE_HEIGHT = 171
IMAGE_Y_OFFSET = -30
BLOCK_HEIGHT = 40
BLOCK_DEPTH = 80
DEAD_ZONE_MIN = -0.02
DEAD_ZONE_MAX =  0.02
PLAYER_CONTROL_SPEED = 2000
PLAYER_BOUNCE_VELOCITY = 1700
PLAYER_INITIAL_BOUNCE = 1700
MAX_CLOUD_DIST = 500
DIFFICULTY_Q = 100000.0
GAME_GRAVITY = 2000
GAME_WAITING = 0
GAME_PLAYING = 1
GAME_DEAD = 2
GAME_CHARACTER = 'PC_Character_Boy' # in case the user does not want to select

player_name = console.input_alert('What is your name? ').title()

# easier to change font later
BUTTON_FONT = 'SourceSansPro-Black' 
MENU_FONT = 'AgentOrange'
GAME_FONT = 'AppleSDGothicNeo-Bold'

# to reduce latency, preload effects in
load_effect('Boing_1')
load_effect('Crashing')
load_effect('Ding_3')

class CharacterSelect(Scene):
    def setup(self):
        center = self.bounds.center()   
        global p1_rect, p2_rect, p3_rect, p4_rect

        if self.size.w > self.size.h: # landscape
            p1_rect = Rect(40, 400, 250, 250)
            p2_rect = Rect(395, 400, 250, 250)
            p3_rect = Rect(735, 400, 250, 250)
            p4_rect = Rect(40, 80, 250, 250)

        if self.size.h > self.size.w: # portrait
            p1_rect = Rect(80, 735, 250, 250)
            p2_rect = Rect(400, 735, 250, 250)
            p3_rect = Rect(80, 395, 250, 250)
            p4_rect = Rect(400, 395, 250, 250)

    def draw(self):
        global p1_rect, p2_rect, p3_rect, p4_rect
        background(0.40, 0.80, 1.00)
        fill(0.00, 0.50, 1.00)

        image('PC_Character_Boy', *p1_rect)     
        image('PC_Character_Cat_Girl', *p2_rect)
        image('PC_Character_Horn_Girl', *p3_rect)   
        image('PC_Character_Princess_Girl', *p4_rect)

        fill(0.50, 1.00, 0.00)

        if self.size.w > self.size.h: # play button landscape
            self.playpx, self.playpy = (895, 10)
            self.playsx, self.playsy = (100, 100)
            rect(self.playpx, self.playpy, self.playsx, self.playsy)

        if self.size.h > self.size.w: # play button portrait
            self.playpx, self.playpy = (650, 10)
            self.playsx, self.playsy = (100, 100)
            rect(self.playpx, self.playpy, self.playsx, self.playsy)

        if self.size.w > self.size.h: 
            image('Typicons96_Right', 895, 10)
        if self.size.h > self.size.w:   
            image('Typicons96_Right', 650, 10)

    def check(self, x, y, posx, posy, sizex, sizey):
        if x >= posx and x <= posx + sizex:
            if y >= posy and y <= posy + sizey:
                return True
        return False

    def check_play(self, x, y):
        return self.check(x, y, self.playpx, self.playpy, self.playsx ,self.playsy)

    def touch_began(self, touch):
        pass

    def touch_moved(self, touch):
        pass

    def touch_ended(self, touch):
        x, y = touch.location
        global GAME_CHARACTER;

        if self.check_play(x, y): 
            main_scene.switch_scene(MyScene)

        if touch.location in p1_rect:
            GAME_CHARACTER = 'PC_Character_Boy'
            play_effect('Ding_3')
            main_scene.switch_scene(MyScene)

        if touch.location in p2_rect:
            GAME_CHARACTER = 'PC_Character_Cat_Girl'
            play_effect('Ding_3')
            main_scene.switch_scene(MyScene)

        if touch.location in p3_rect:
            GAME_CHARACTER = 'PC_Character_Horn_Girl'
            play_effect('Ding_3')
            main_scene.switch_scene(MyScene)

        if touch.location in p4_rect:
            GAME_CHARACTER = 'PC_Character_Princess_Girl'
            play_effect('Ding_3')
            main_scene.switch_scene(MyScene)

        else: 
            pass

class Player(object):
    def __init__(self):
        self.bounds = Rect()
        self.velocity = 0

    def draw(self):
        global GAME_CHARACTER
        tint(1,1,1)
        image(GAME_CHARACTER, self.bounds.x , self.bounds.y + IMAGE_Y_OFFSET)

class GroundBlock(object):
    def __init__(self):
        self.bounds = Rect()

    def draw(self):
        tint(1,1,1)
        image('PC_Grass_Block', self.bounds.x, self.bounds.y)

class Cloud (object):
    def __init__(self):
        self.shapes = []

        num_circles = randint(4, 5)
        for i in xrange(num_circles):
            x = i * 20 - ((num_circles/2)*30)
            y = (random()-0.5) * 30
            rad = randint(50, 100)
            self.shapes.append([x, y, rad])

        self.width = num_circles * 30 + 30
        self.bounds = Rect(0, 0, self.width, 60)

    def is_colliding(self, pos):
        startp = self.bounds.x - self.width/2
        endp = self.bounds.x + self.width/2
        if ((pos.x < endp) and (pos.x > startp) and
        (pos.y < (self.bounds.y + 30)) and
        (pos.y > (self.bounds.y + 10))):
            return True
        return False

    def draw(self):
        push_matrix()
        translate(self.bounds.x, self.bounds.y)
        no_stroke()
        fill(0.90, 0.90, 0.90)
        for i in self.shapes:
            ellipse(i[0], i[1] - 5, i[2], i[2])

        fill(1.00, 1.00, 1.00)
        for i in self.shapes:
            ellipse(i[0], i[1] + 5, i[2], i[2])

        pop_matrix()

class MyScene (Scene):
    def create_ground(self):
        for x in range((int(self.bounds.w) / IMAGE_WIDTH) + 1):
            block = GroundBlock()
            block.bounds = Rect(x * IMAGE_WIDTH, 0, IMAGE_WIDTH, IMAGE_HEIGHT)
            self.scenery.append(block)

    def generate_clouds(self):
        y = self.cloud_height
        while self.cloud_height < self.bounds.h * 2:
            q = min(self.climb, DIFFICULTY_Q)
            min_dist = int(MAX_CLOUD_DIST * q / DIFFICULTY_Q)
            max_dist = int(MAX_CLOUD_DIST / 2 + min_dist / 2)
            self.cloud_height += randint(min_dist, max_dist)
            cloud = Cloud()
            cloud.bounds.x = random() * (self.bounds.w - 150)
            cloud.bounds.y = self.cloud_height
            self.scenery.append(cloud)

    def cull_scenery(self):
        i = len(self.scenery)
        for sprite in self.scenery[:]:
            if sprite.bounds.top() < 0:
                self.scenery.remove(sprite)

    def control_player(self):
        tilt = gravity().x
        if(tilt < DEAD_ZONE_MIN) or (tilt > DEAD_ZONE_MAX):
            move = self.dt * tilt * PLAYER_CONTROL_SPEED
            self.player.bounds.x += move
            if(self.player.bounds.x < 0):
                self.player.bounds.x = 0
            elif(self.player.bounds.x > self.bounds.w - self.player.bounds.w):
                self.player.bounds.x = self.bounds.w - self.player.bounds.w

    def lower_scenery(self, y):
        self.climb += y
        self.cloud_height -= y
        for sprite in self.scenery:
            sprite.bounds.y -= y

    def run_gravity(self):
        player_y_move = self.dt * self.player.velocity
        scenery_y_move = 0
        old_velocity = self.player.velocity
        self.player.velocity -= self.dt * GAME_GRAVITY
        if(old_velocity > 0) and (self.player.velocity <= 0):
            self.player_apex_frame = True
        self.player.bounds.y += player_y_move
        if(self.player.bounds.y >= self.player_max_y):
            scenery_y_move = self.player.bounds.y - self.player_max_y
            self.player.bounds.y = self.player_max_y
            self.lower_scenery(scenery_y_move)
        elif(self.player.bounds.top() < 0):
            self.game_state = GAME_DEAD
            play_effect('Crashing')

    def collision_detect(self):
        bounce = False
        if(self.player.velocity < 0):
            p = Point(self.player.bounds.x + self.player.bounds.w/2, self.player.bounds.y)
            for sprite in self.scenery:
                if hasattr(sprite, 'is_colliding'):
                    collision = sprite.is_colliding(p)
                else:
                    collision = p in sprite.bounds
                if collision:
                    self.player.velocity = PLAYER_BOUNCE_VELOCITY
                    play_effect('Boing_1')
                    break

    def game_loop(self):
        if self.game_state == GAME_PLAYING:
            self.run_gravity()
            self.collision_detect()
            self.control_player()
            if self.player_apex_frame:
                self.cull_scenery()
                self.generate_clouds()
                self.player_apex_frame = False

    def shadow_text(self, s, x, y):
        tint(0,0,0)
        text(s, GAME_FONT, 48, x + 2, y - 2)
        tint(0.00, 0.50, 1.00)
        text(s, GAME_FONT, 48, x, y)

    def high_score(self):
        high_scores = {}

        if os.path.isfile('highscores.pkl'):
            with open("highscores.pkl", "rb") as h:
                high_scores = pickle.load(h)
        else:
            high_scores = {"Adam Smith": 65536, "John Doe": 10000}

        new_score = (player_name, str(int(self.climb / 10))

        if new_score[1] > high_scores[new_score[0]]:
            self.shadow_text('NEW HIGH SCORE!', self.bounds.w / 2, self.bounds.h * 0.75)
            high_scores[new_score[0]] = new_score[1]
        else:
            pass

        with open("highscores.pkl","wb") as out:
            pickle.dump(high_scores, out)

    def draw_text(self):
        if(self.game_state == GAME_WAITING):
            self.shadow_text('Tap Screen to Start', self.bounds.w / 2, self.bounds.h * 0.6)
            self.shadow_text('Tilt Screen to Steer', self.bounds.w / 2, self.bounds.h * 0.4)
        elif(self.game_state == GAME_PLAYING):
            self.shadow_text('Score : ' + str(int(self.climb / 10)), self.bounds.w / 2, self.bounds.h * 0.95)
        if(self.game_state == GAME_DEAD):
            self.shadow_text('Score : ' + str(int(self.climb / 10)), self.bounds.w / 2, self.bounds.h * 0.95)
            self.shadow_text('Game Over', self.bounds.w / 2, self.bounds.h * 0.6)
            self.shadow_text('Tap to Play Again', self.bounds.w / 2, self.bounds.h * 0.4)

    def setup(self):
        self.game_state = GAME_WAITING
        self.scenery = []
        self.climb = 0
        self.create_ground()
        self.cloud_height = 200
        self.generate_clouds()
        self.player = Player()
        self.player_apex_frame = False
        self.player.bounds = Rect(self.bounds.w / 2 - IMAGE_WIDTH / 2, BLOCK_HEIGHT + BLOCK_DEPTH / 2, IMAGE_WIDTH, IMAGE_HEIGHT)
        self.player_max_y = self.bounds.h * 0.6

    def draw(self):
        self.game_loop()
        background(0.40, 0.80, 1.00)
        for sprite in self.scenery:
            sprite.draw()
        self.player.draw()
        self.draw_text()

    def touch_began(self, touch):
        if self.game_state == GAME_WAITING:
            self.game_state = GAME_PLAYING
            high_scores = {}
        elif self.game_state == GAME_DEAD:
            self.setup()

class Start (Scene):    
    def draw(self):
        background(0.40, 0.80, 1.00) # light blue background color

        fill(0.50, 1.00, 0.00) # play button fill color

        if self.size.w > self.size.h: # play button landscape
            self.playpx, self.playpy = (320, 350)
            self.playsx, self.playsy = (358, 100)
            rect(self.playpx, self.playpy, self.playsx, self.playsy)

        if self.size.h > self.size.w: # play button portrait
            self.playpx, self.playpy = (200, 600)
            self.playsx, self.playsy = (358, 100)
            rect(self.playpx, self.playpy, self.playsx, self.playsy)

        fill(0.9803921568627451, 0.5019607843137255, 0.4470588235294118) # character select fill color

        if self.size.w > self.size.h: # character select button landscape
            self.characpx, self.characpy = (260, 230)
            self.characsx, self.characsy = (485, 100)
            rect(self.characpx, self.characpy, self.characsx, self.characsy)

        if self.size.h > self.size.w: # character select button portrait
            self.characpx, self.characpy = (140, 470)
            self.characsx, self.characsy = (485, 100)
            rect(self.characpx, self.characpy, self.characsx, self.characsy)

        tint(1.00, 1.00, 1.00) # white text color

        if self.size.w > self.size.h: 
            text('LaxJump', MENU_FONT, font_size=150.0, x=525.0, y=600.0)
        if self.size.h > self.size.w: 
            text('LaxJump', MENU_FONT, font_size=100.0, x=385.0, y=850.0)

        if self.size.w > self.size.h: 
            text('Play Game', BUTTON_FONT, font_size=65.0, x=500.0, y=400.0)
        if self.size.h > self.size.w: 
            text('Play Game', BUTTON_FONT, font_size=65.0, x=380.0, y=650.0)

        if self.size.w > self.size.h: 
            text('Character Select', BUTTON_FONT, font_size=64.0, x=503.0, y=285.0)
        if self.size.h > self.size.w: 
            text('Character Select', BUTTON_FONT, font_size=64.0, x=380.0, y=521)

        text('Welcome ' + str(player_name) + '!', BUTTON_FONT, font_size=20.0, x=self.bounds.w / 2, y=self.bounds.h / 12.0)

    def check(self, x, y, posx, posy, sizex, sizey):
        if x >= posx and x <= posx + sizex:
            if y >= posy and y <= posy + sizey:
                return True
        return False

    def check_character(self, x, y):
        return self.check(x, y, self.characpx, self.characpy, self.characsx ,self.characsy)

    def check_play(self, x, y):
        return self.check(x, y, self.playpx, self.playpy, self.playsx ,self.playsy)

    def touch_ended(self, touch):
        x, y = touch.location
        if self.check_play(x, y): main_scene.switch_scene(MyScene)
        if self.check_character(x, y): main_scene.switch_scene(CharacterSelect)
        else: pass

class MultiScene (Scene):
    def __init__(self, start_scene):
        self.active_scene = start_scene()

    def switch_scene(self, new_scene):
        self.active_scene = new_scene()
        self.setup()

    def setup(self):
        global screen_size
        screen_size = self.size
        self.active_scene.add_layer = self.add_layer
        self.active_scene.size = self.size
        self.active_scene.bounds = self.bounds
        self.active_scene.root_layer = self.root_layer
        self.active_scene.setup()

    def draw(self):
        self.active_scene.touches = self.touches
        self.active_scene.t = self.t
        self.active_scene.dt = self.dt 
        self.active_scene.draw()

    def touch_began(self, touch):
        self.active_scene.touch_began(touch)

    def touch_moved(self, touch):
        self.active_scene.touch_moved(touch)

    def touch_ended(self, touch):
        self.active_scene.touch_ended(touch)

main_scene = MultiScene(Start)
run(main_scene)
omz

Is the syntax error shown on any specific line?

techteej

Shown on line

    if new_score[1] > high_scores[new_score[0]]:

and if I comment that out, it skips to the next line with an invalid syntax

omz

The problem is in the line before that:

new_score = (player_name, str(int(self.climb / 10))

There's a closing parenthesis missing.

techteej

Thank you so much. The text does not display now, but I am sure that's a simple fix. I feel so stupid!