Beispiel #1
0
def run_title():
    class Title: pass
    run.quit = False
    game = run.game

    title = Picture("title.png")
    subtitle = Picture("subtitle.png")
    menu = Picture("menu.png")
    menu2 = Picture("menu2.png")
    menu3 = Picture("menu3.png")
    menu3hl = Picture("menu3hl.png")

    cursor = Picture("mouse.png")

    if not run.config.nomusic:
        pygame.mixer.music.load(data.filepath("loop/menu.ogg"))
        pygame.mixer.music.play(-1)

    def button_ng():
        run.run_game()
        if not run.config.nomusic:
            pygame.mixer.music.load(data.filepath("loop/menu.ogg"))
            pygame.mixer.music.play(-1)
        title.next = pygame.time.get_ticks() + 1000.0 / run.FPS

    def button_next():
        if run.last_level < run.config.level: run.last_level += 1

    def button_prev():
        if run.last_level > 1: run.last_level -= 1

    def button_fs():
        run.config.fullscreen = not run.config.fullscreen
        run.config.save()
        main.main()

    def button_nm():
        run.config.nomusic = not run.config.nomusic
        if not run.config.nomusic:
            pygame.mixer.music.load(data.filepath("loop/menu.ogg"))
            pygame.mixer.music.play(-1)
        else:
            pygame.mixer.music.stop()
        run.config.save()

    def button_q():
        run.quit = True

    rects = (
        (220, 274, 417, 323, button_ng),
        (170, 344, 320, 400, button_fs),
        (340, 344, 470, 400, button_nm),
        (283, 417, 358, 466, button_q),
        (130, 260, 210, 286, button_next),
        (130, 301, 210, 326, button_prev),
        )

    selected = None
    t = 0
    title.next = pygame.time.get_ticks() + 1000 / run.FPS
    while not run.quit:

        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                run.quit = True
            elif e.type == pygame.KEYDOWN:
                if e.key == pygame.K_ESCAPE:
                    rects[3][4]()
                if e.key == pygame.K_RETURN:
                    rects[0][4]()
            elif e.type == pygame.MOUSEBUTTONUP:
                x, y = e.pos
                if e.button == 1:
                    if selected != None:
                        selected[4]()

        mx, my = pygame.mouse.get_pos()

        glClearColor(1, 0.6, 0.4, 1)
        glClear(GL_COLOR_BUFFER_BIT)

        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        glEnable(GL_TEXTURE_2D)
        glEnable(GL_BLEND)
        glBlendFunc(GL_ONE, GL_ONE)

        t += 1
        tt = (t * 4) % (480 + 512)

        game.background1.draw_centered(0, 0)
        game.background1.draw_centered(640, 480)
        game.background1.draw_centered(320, tt)
        game.background1.draw_centered(320, tt - 512 - 480)

        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        selected = None
        black = {"red" : 0, "green" : 0, "blue" : 0}
        beat = (t % 30)
        if beat < 20: beat = 0
        else:
            if beat < 25: beat = (beat - 20) / 5.0
            else: beat = 1 - (beat - 25) / 5.0
        d = (t / 30) % 3
        a, b, c = ((0.5, 0.5, 0), (0.5, 0, 0.5), (0, 0.5, 0.5))[d]
        flash = {"red" : beat * a, "green" : beat * b, "blue" : beat * c}
        d = 160.0
        if t < d:
            tt = 1 - t / d

            title.draw(0, 0 - tt * 480, **flash)
            subtitle.draw(0, 0 + tt * 480, **black)
            menu.draw(0 + tt * 640, 0, **black)
            menu2.draw(0 - tt * 640, 0, **black)
        elif t < d * 2:
            tt = t - d
            tt = tt / d

            title.draw(0, 0, **flash)
            subtitle.draw(0, -tt * 220, **black)
            menu.draw(240 * tt, 80 * tt, **black)
            menu2.draw(-80 * tt, 80 * tt, **black)
        else:
            tt = (t - d * 2) / d
            if tt > 1.0: tt = 1.0
            title.draw(0, 0, **flash)
            subtitle.draw(0, -220, **black)
            glPushMatrix()
            glTranslate(240 + 550, 80 + 350, 0)
            glRotate(10 * math.sin(1 * 2 * math.pi * (t - d * 2) / 60), 0, 0, 1)
            glTranslate(-550, -350, 0)
            menu.draw(0, 0, **black)
            glPopMatrix()
            menu2.draw(-80, 80, **black)
            menu3.draw(0, 0, red = 0, green = 0, blue = 0, alpha = tt)

            for r in rects:
                if mx >= r[0] and my >= r[1] and mx <= r[2] and my <= r[3]:
                    selected = r
                    glBlendFunc(GL_SRC_ALPHA, GL_ONE)
                    menu3hl.draw_part(r[0] - 8, r[1] - 8, r[0] - 8, r[1] - 8, r[2] + 8, r[3] + 8)
                    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
                    menu3.draw_part(r[0] - 8, r[1] - 8, r[0] - 8, r[1] - 8, r[2] + 8, r[3] + 8,
                        red = 1, green = 0.5, blue = 0, alpha = 0.5)
                    selected = r

            glBlendFunc(GL_SRC_ALPHA, GL_ONE)
            x, y = 395 + 230 * (run.last_level - 1) / 7, 245
            menu3hl.draw_part(x, y, x, y, 395 + 230 * run.last_level / 7, 290)
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
            menu3hl.draw_part(x, y, x, y, 395 + 230 * run.last_level / 7, 290,
                red = 1, green = 0.5, blue = 0, alpha = 0.5)

        cursor.draw_centered(mx, my)

        pygame.display.flip()

        ft = pygame.time.get_ticks()
        pygame.time.wait(int(title.next - ft))
        ft = title.next
        title.next = ft + 1000.0 / run.FPS
Beispiel #2
0
class Game:
    def __init__(self, vw, vh):
        self.vw = vw
        self.vh = vh
        self.level = 0

        self.background1 = Picture("clock.jpg")

    def restart(game):
        game.spatialhash = SpatialHash(64, 64, 64, 64)
        game.orbs = []

        game.decohash = SpatialHash(64, 64, 64, 64)
        game.deco = []

        game.active = []
        game.lasers = {}

        game.dragged = None
        game.drag = (0, 0)
        game.selected = None
        game.new_size = 10

        game.twist = 0

        cx = 64 * 32
        cy = 64 * 32
        game.x = cx
        game.y = cy
        game.radius = 1000

        game.view = View()
        game.view.x = 0
        game.view.y = 0
        game.view.angle = 0

        game.coins = 0
        game.rider = None

    def script1(game):

        game.player = Allefant(game.x, game.y + game.radius - 50, 20)
        game.player.spawn(game.spatialhash)
        game.orbs.append(game.player)

        game.active.append(game.player)

        outside = InverseOrb(game.x, game.y, game.radius)
        outside.spawn(game.spatialhash)
        game.orbs.append(outside)

    def script2(game):
        # ai = 360 / n
        # ao = 180 - ai = 180 - 360 / n
        # h*h + s2*s2 = r*r
        # s = 2 * r * sin(ai / 2)
        # h = 2 * r * cos(ai / 2)
        # c = n * s
        game.place(game.x, game.y, 30, 0, RoundBlock1)
        outerr = game.radius - 80
        vdist = 220
        a = 0
        while 1:
            r = outerr - vdist * a / (2 * math.pi)
            if r < vdist: break
            x = game.x + math.sin(a) * r
            y = game.y + math.cos(a) * r
            b = game.place(x, y, 30, -a * 180 / math.pi + 90, RoundBlock1)
            a += 122 / r
            
    def script3(game):
        r = game.radius + 20
        a = 0
        while a < math.pi * 2:
            x = game.x + math.sin(a) * r
            y = game.y + math.cos(a) * r
            b = game.placedeco(x, y, 18, 180 * -a / math.pi, Block1)
            a += 118.7 / r

    def script4(game, x, y, dx, dy):
        prev = None
        r = game.new_size
        for i in range(40):
            orb = Orb(x, y, r)
            orb.spawn(game.spatialhash)
            game.orbs.append(orb)

            x += dx * game.new_size * 2
            y += dy * game.new_size * 2
            if prev:
                orb.append(prev)
            prev = orb

    def script5(game):
        r = game.radius + 20
        a = 0
        while a < math.pi * 2:
            x = game.x + math.sin(a) * r
            y = game.y + math.cos(a) * r
            b = game.placedeco(x, y, 18, 180 * -a / math.pi - 90, Wall)
            a += 118.7 / r

    def script6(game):
        r = 400

        game.player = Allefant(game.x, game.y + r - 21, 20)
        game.player.spawn(game.spatialhash)
        game.orbs.append(game.player)
        game.active.append(game.player)

        outside = InverseOrb(game.x, game.y, r)
        outside.spawn(game.spatialhash)
        game.orbs.append(outside)

        a = 0
        r += 20
        while a < math.pi * 2:
            x = game.x + math.sin(a) * r
            y = game.y + math.cos(a) * r
            b = game.placedeco(x, y, 18, 180 * -a / math.pi, Block1)
            a += 118.7 / r

    def script7(game):
        for orb in game.orbs[:]:
            if orb.__class__ == Orb:
                game.remove(orb)
            elif orb.__class__ == Wall:
                a = orb.angle * math.pi / 180.0
                x = orb.x
                y = orb.y
                ax = math.sin(a)
                ay = -math.cos(a)
                game.place(x + 42 * ax, y + 42 * ay, 19, a, Orb)
                game.place(x - 42 * ax, y - 42 * ay, 19, a, Orb)
                game.place(x + 21 * ax, y + 21 * ay, 19, a, Orb)
                game.place(x - 21 * ax, y - 21 * ay, 19, a, Orb)
            elif orb.__class__ == Block1:
                a = orb.angle * math.pi / 180.0
                x = orb.x
                y = orb.y
                ax = math.cos(a)
                ay = math.sin(a)
                game.place(x + 42 * ax, y + 42 * ay, 19, a, Orb)
                game.place(x - 42 * ax, y - 42 * ay, 19, a, Orb)
                game.place(x + 21 * ax, y + 21 * ay, 19, a, Orb)
                game.place(x - 21 * ax, y - 21 * ay, 19, a, Orb)

    def colliders(self, x, y, r):
        orb = Orb(x, y, r)
        orb.hash = self.spatialhash
        return [x for x in orb.colliders() if not x.__class__ == InverseOrb]

    def render(self):
        px = (self.player.x - self.x) * 0.25
        py = (self.player.y - self.y) * 0.25
        glPushMatrix()
        glScalef(1 + 0.01 * math.cos(self.twist * math.pi * 2 / 120.0),
            1 + 0.01 * math.sin(self.twist * math.pi * 2 / 120.0), 1)
        self.background1.draw_centered(self.view.x - px, self.view.y - py)
        glPopMatrix()

        drawn = 0
        diagonal = (self.vw ** 2 + self.vh ** 2) ** 0.5
        x, y = self.player.x, self.player.y
        pvs = self.decohash.get_in_circle(x, y, diagonal / 2)
        for orb in pvs:
            orb.draw()
            drawn += 1

        pvs = self.spatialhash.get_in_circle(x, y, diagonal / 2)
        for layer in [-1, 0, 1]:
            for orb in pvs:
                if orb.layer() == layer:
                    orb.draw()
                    drawn += 1

        if run.run.debugging:
            for layer in [-1, 0, 1]:
                for orb in pvs:
                    if orb.layer() == layer:
                        orb.draw_debug()

        glLoadIdentity()
        run.run.font.write(0, 443, "Level %d/6" % self.level, alpha = 0.8)

        run.run.font.write(320, 443, "Health %.f" % self.player.health,
            red = 1, green = 0, blue = 0, alpha = 0.8, center = True)

        run.run.font.write(640, 443, "Coins %d/%d" % (self.player.coins, self.coins),
            red = 1, green = 0.8, blue = 0.1, alpha = 0.8, right = True)

        if self.rider:
            if not self.rider.dead:
                run.run.font.write(320, 400, "Boss %.f" % self.rider.lifes,
                    red = 1, green = 0.5, blue = 0, alpha = 0.8, center = True)
                

    def tick(self):
        for orb in self.active:
            if not orb.dead:
                d = (orb.x - self.player.x) ** 2 + (orb.y - self.player.y) ** 2
                if d < orb.activity_radius * orb.activity_radius:
                    orb.tick()
        self.view.x = self.player.x - 320
        self.view.y = self.player.y - 240

        self.twist += 1

    def insert_action(game, x, y):
        orb = Orb(x, y, game.new_size)
        orb.spawn(game.spatialhash)
        game.orbs.append(orb)

    def place(game, x, y, r, a, what):
        orb = what(x, y, r)
        orb.angle = a
        orb.spawn(game.spatialhash)
        game.orbs.append(orb)
        return orb

    def insert_stuff(game, x, y, what):
        r = {"Wall" : 20, "Python" : 15, "Rider" : 50, "Spikes" : 20,
            "RoundBlock1" : 30, "Coin" : 10, "Leprechaun" : 15, "Lever" : 15,
            "Laser" : 40, "Portal" : 20}
        orb = game.place(x, y, r[what], 0, getattr(sprites, what))
        orb.align()
        if orb.is_active(): game.active.append(orb)
        return orb

    def remove(game, orb):
        if not orb: return
        orb.disappear()
        if orb in game.orbs: game.orbs.remove(orb)
        if orb in game.deco: game.deco.remove(orb)
        if orb in game.active: game.active.remove(orb)

    def placedeco(game, x, y, r, a, what):
        orb = what(x, y, r)
        orb.angle = a
        orb.spawn(game.decohash)
        game.deco.append(orb)
        return orb

    def insert_block1(game, x, y):
        a = -game.view.angle
        b = game.place(x, y, 19, a, Block1)

    def insert_rotated_block1(game, x, y):
        a = -game.view.angle + 90
        b = game.place(x, y, 19, a, Block1)

    def insert_wall(game, x, y):
        a = -game.view.angle
        b = game.place(x, y, 19, a, Wall)

    def place_moving_ball(game, x, y, a, dx, dy):
        orb = Ball1(x, y, 30)
        orb.angle = a
        orb.spawn(game.spatialhash)
        orb.movex = dx
        orb.movey = dy
        game.orbs.append(orb)
        game.active.append(orb)

    def place_moving_cogwheel(game, x, y, a):
        orb = Cogwheel(x, y, 25)
        orb.angle = a
        orb.spawn(game.spatialhash)
        orb.movex = 1
        game.orbs.append(orb)
        game.active.append(orb)

    def place_moving_spring(game, x, y):
        orb = Spring(x, y, 10)
        orb.align()
        orb.spawn(game.spatialhash)
        orb.movey = 1
        game.orbs.append(orb)
        game.active.append(orb)

    def save_level(self, num):
        fp = data.savepath("levels/%d" % num)
        f = open(fp, "w")
        for orb in self.deco:
            f.write("deco " + orb.__class__.__name__ + orb.as_string() + "\n")
        for orb in self.orbs:
            f.write("orbs " + orb.__class__.__name__ + orb.as_string() + "\n")
        f.close()

    def load_level(old, num):
        game = Game(old.vw, old.vh)
        game.restart()
        game.level = num
        fp = data.loadblock("levels/%d" % num)
        for line in fp:
            layername, classname, remainder = line.split(None, 2)

            if layername == "orbs":
                layer = game.orbs
                hash = game.spatialhash
            elif layername == "deco":
                layer = game.deco
                hash = game.decohash

            if classname == "Allefant":
                o = Allefant.from_string(remainder)
                o.spawn(hash)
                layer.append(o)
                game.player = o
            elif classname == "InverseOrb":
                o = InverseOrb.from_string(remainder)
                o.spawn(hash)
                layer.append(o)
            else:
                o = globals()[classname].from_string(remainder)
                o.spawn(hash)
                layer.append(o)
                if classname == "Laser":
                    game.lasers[o.id] = o
                if classname == "Coin": game.coins += 1
                if classname == "Rider": game.rider = o
            if o.is_active(): game.active.append(o)

        return game
Beispiel #3
0
def run_game():
    game = run.game = run.game.load_level(run.last_level)

    clock = pygame.time.Clock()

    debug_no_render = False

    if not run.config.nomusic:
        pygame.mixer.music.load(data.filepath("loop/level1.ogg"))
        pygame.mixer.music.set_volume(0.8)
        pygame.mixer.music.play(-1)

    cursor = Picture("mouse.png")

    if run.first_time:
        run.message = Message(["Move: Left/Right or A/D",
            "Jump: Up or W", "Interact: Down or S"])
        run.first_time = False

    fps = []
    quit = False
    next = pygame.time.get_ticks() + 1000.0 / run.FPS
    while not quit:

        p = game.player

        gx = p.x - game.x
        gy = p.y - game.y
        gd = (gx ** 2 + gy ** 2) ** 0.5

        if gd > 1:
            downx = gx / gd
            downy = gy / gd
        else:
            downx = 0
            downy = 1
        rightx = downy
        righty = -downx

        #gx /= game.radius
        #gy /= game.radius

        if gd > 30:
            gx = downx
            gy = downy
        else:
            gx = 0
            gy = 0

        mx, my = pygame.mouse.get_pos()
        rx = mx - game.vw / 2
        ry = my - game.vh / 2
        x = p.x + rightx * rx + downx * ry
        y = p.y + righty * rx + downy * ry

        game.reloaded = False

        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                quit = True
            elif e.type == pygame.KEYDOWN:
                if e.key == pygame.K_ESCAPE:
                    quit = True
                if e.key == pygame.K_RETURN:
                    if e.mod & pygame.KMOD_ALT:
                        pygame.display.toggle_fullscreen()
                if e.key == pygame.K_DOWN or e.key == ord("s"):
                    if run.message:
                        if not run.message.showfull: run.message.showfull = True
                        else: run.message = None
                if e.key == ord("p"):
                    run.paused = not run.paused
                if run.debugging:
                    if e.key == pygame.K_F12:
                        debug_no_render = not debug_no_render
                if run.editing:
                    edit.run = run
                    edit.game = game
                    edit.x = x
                    edit.y = y
                    edit.rightx = rightx
                    edit.righty = righty

                    for i in range(0, len(edit.commands), 2):
                        com, func = edit.commands[i : i + 2]
                        if (type(com) == str and e.key == ord(com)) or \
                            e.key == com: func()

            elif e.type == pygame.MOUSEBUTTONUP and run.editing:
                if e.button == 1:
                    game.selected = game.dragged
                    game.dragged = None
                    if game.selected: game.new_size = game.selected.r
            elif e.type == pygame.MOUSEBUTTONDOWN and run.editing:
                mx, my = e.pos

                if e.button == 1:
                    o = game.colliders(x, y, 10)
                    if o:
                        game.dragged = o[0]
                        game.drag = (x, y)
                if e.button == 3:
                    pass

        if game.reloaded:
            game = run.game
            continue

        if game.dragged:
            drx, dry = game.drag
            dro = game.dragged
            game.dragged.teleport_to(x + dro.x - drx, y + dro.y - dry)
            game.drag = (x, y)

        kx, ky = 0, 0
        k = pygame.key.get_pressed()
        if not run.editing:
            if k[pygame.K_a] and not k[pygame.K_d]: kx = -1
            if k[pygame.K_d] and not k[pygame.K_a]: kx = 1
            if k[pygame.K_w] and not k[pygame.K_s]: ky = -1
            if k[pygame.K_s] and not k[pygame.K_w]: ky = 1
        
        if k[pygame.K_LEFT] and not k[pygame.K_RIGHT]: kx = -1
        if k[pygame.K_RIGHT] and not k[pygame.K_LEFT]: kx = 1
        if k[pygame.K_UP] and not k[pygame.K_DOWN]: ky = -1
        if k[pygame.K_DOWN] and not k[pygame.K_UP]: ky = 1

        b1, b2, b3 = pygame.mouse.get_pressed()

        game.gravityx = gx * 2
        game.gravityy = gy * 2
        game.downx = downx
        game.downy = downy
        game.rightx = rightx
        game.righty = righty

        if run.paused:
            pass
        elif run.message:
            run.message.tick()
        elif run.game_over:
            run.game_over = False
            quit = True
        elif run.level_done:
            run.level_done = False
            run.last_level += 1
            game = run.game = game.load_level(run.last_level)
            if run.last_level > run.config.level:
                run.config.level = run.last_level
                run.config.save()
            continue
        else:
            p.kx = kx
            p.ky = ky
            game.tick()

        glClearColor(0, 0, 0, 1)
        glClear(GL_COLOR_BUFFER_BIT)

        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        game.view.angle = 180 * math.atan2(downx, downy) / math.pi
        p.angle = -game.view.angle
        game.view.x = p.x
        game.view.y = p.y
        glTranslate(game.vw / 2, game.vh / 2, 0)
        glRotate(game.view.angle, 0, 0, 1)
        glTranslate(-game.view.x, -game.view.y, 0)

        if not debug_no_render:
            game.render()

        glLoadIdentity()

        def show_fps():
            now = pygame.time.get_ticks()
            while fps and fps[0] <= now - 1000:
                fps.pop(0)
            ds = []
            for i in range(1, len(fps)):
                ds.append(1.0 * fps[i] - fps[i - 1])

            if ds:
                avg = sum(ds) / len(ds)
                avg = 1000.0 / avg
                a = 1000.0 / min(ds)
                b = 1000.0 / max(ds)
            else:
                avg = a = b = 0

            run.font.write(640, 0, "FPS: %.1f (%.1f - %.1f)" % (avg, b, a),
                right = True)
        #show_fps()

        if run.help:
            helptext = "\n"
            x = 0
            pos = 0
            for i in range(0, len(edit.commands), 2):
                func = edit.commands[i + 1]
                if func.__doc__: helptext += func.__doc__ + "\n"
                else: helptext += "?\n"
                pos += 1
                if pos == 10:
                    run.font.write(x, 0, helptext)
                    x += 150
                    pos = 0
                    helptext = "\n"
            run.font.write(x, 0, helptext)

        if run.message:
            run.message.display()

        if run.editing:
            cursor.draw_centered(mx, my)

        pygame.display.flip()

        t = pygame.time.get_ticks()
        fps.append(t)
        w = int(next - t)

        if w > 0:
            pygame.time.wait(w)
        # If we're lagging behind, we can either skip rendering some frames,
        # or slow down. We choose the latter.
        if w < -500:
            next = t
        next += 1000.0 / run.FPS