コード例 #1
0
def main():
    pygame.init()
    SCREEN_WIDTH = 1000
    SCREEN_HEIGHT = 700
    SCREEN_CENTRE = Vector2(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)

    # Scale in pixels per metre
    # 100 pix = 1 AU
    UNIVERSE = Universe(CONST.AU / 100, 2**23)

    CAMERA = Camera(SCREEN_CENTRE)

    DISPLAY = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    CLOCK = pygame.time.Clock()
    FPS = 120

    moveData = {
        "mouseHeld": False,
        "tempRelMass": 1,
        "tempBody": None,
        "lastPos": (0, 0),
        "currentPos": (0, 0),
        "lastTime": -1,
        "currentTime": 0
    }

    bodies = []

    font = pygame.font.SysFont("monospace", 15)

    while True:
        DISPLAY.fill(BLACK)
        realDeltaT = (CLOCK.get_time() / 1000)
        UNIVERSE.update(realDeltaT)
        deltaT = UNIVERSE.deltaT(realDeltaT)

        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit()

            elif e.type == pygame.KEYDOWN:
                if e.key == pygame.K_PERIOD:
                    UNIVERSE.accelTime(2)
                elif e.key == pygame.K_COMMA:
                    UNIVERSE.accelTime(1 / 2)

            elif e.type == pygame.MOUSEBUTTONDOWN:
                if e.button == 1:
                    moveData["mouseHeld"] = True
                    moveData["tempRelMass"] = 1
                    moveData["currentPos"] = e.pos
                    moveData["lastPos"] = e.pos
                    moveData["lastTime"] = -1
                    moveData["currentTime"] = UNIVERSE.totalTime

                    # The body's position will be set later before drawing
                    moveData["tempBody"] = Body(
                        Vector2(), moveData["tempRelMass"] * CONST.ME)

                elif e.button == 4:
                    if moveData["mouseHeld"]:
                        if pygame.KMOD_SHIFT & pygame.key.get_mods():
                            moveData["tempRelMass"] *= 2**(2 / 3)
                        else:
                            moveData["tempRelMass"] *= 2**(1 / 3)
                        moveData["tempBody"].setMass(moveData["tempRelMass"] *
                                                     CONST.ME)
                    else:
                        CAMERA.resize(2)

                elif e.button == 5:
                    if moveData["mouseHeld"]:
                        if pygame.KMOD_SHIFT & pygame.key.get_mods():
                            moveData["tempRelMass"] /= 2**(2 / 3)
                        else:
                            moveData["tempRelMass"] /= 2**(1 / 3)
                        moveData["tempBody"].setMass(moveData["tempRelMass"] *
                                                     CONST.ME)
                    else:
                        CAMERA.resize(1 / 2)

            elif e.type == pygame.MOUSEBUTTONUP:
                if e.button == 1:
                    moveData["mouseHeld"] = False
                    tempBody = moveData["tempBody"]

                    beginPos = Vector2(moveData["lastPos"])
                    endPos = Vector2(moveData["currentPos"])

                    # Calculate last velocity of mouse
                    if not (pygame.KMOD_CTRL & pygame.key.get_mods()):
                        if moveData["currentTime"] - moveData["lastTime"] == 0:
                            print("Oops... zero-division avoided!")
                        else:
                            dampener = 2
                            distance = UNIVERSE.screenToWorld(
                                (endPos - beginPos)) / (CAMERA.scale *
                                                        dampener)
                            velocity = distance / (moveData["currentTime"] -
                                                   moveData["lastTime"])
                            tempBody.velocity = velocity

                    bodies.append(tempBody)
                    moveData["tempBody"] = None

                    print("Created body with mass {:.4e}kg".format(
                        tempBody.mass))

            elif e.type == pygame.MOUSEMOTION:
                if moveData["mouseHeld"]:
                    moveData["lastPos"] = moveData["currentPos"]
                    moveData["lastTime"] = moveData["currentTime"]
                    moveData["currentPos"] = e.pos
                    moveData["currentTime"] = UNIVERSE.totalTime

        CAMERA.handleInput(realDeltaT)

        # Update pos always, and now so that we can take into account any camera moves
        if moveData["mouseHeld"]:
            bodyPos = UNIVERSE.screenToWorld(
                CAMERA.reverseDrawPos(moveData["currentPos"]))
            moveData["tempBody"].setPos(bodyPos)

        if moveData["tempBody"]:
            moveData["tempBody"].draw(DISPLAY, CAMERA, UNIVERSE)

        for body in bodies:
            body.update(deltaT, bodies)

        for body in bodies:
            body.draw(DISPLAY, CAMERA, UNIVERSE)

        lineY = SCREEN_HEIGHT - 10
        pygame.draw.line(DISPLAY, WHITE, (10, lineY), (110, lineY), 2)

        drawText(DISPLAY,
                 readableDistance(UNIVERSE.scale * 100 / CAMERA.scale), font,
                 (120, lineY - 10), WHITE)

        # Draw UI
        drawText(DISPLAY, "Time scale: {}x".format(UNIVERSE.timeScale), font,
                 (10, 10), WHITE)
        drawText(
            DISPLAY,
            "Time elapsed: {}".format(secondsToTimeString(UNIVERSE.totalTime)),
            font, (10, 30), WHITE)
        # drawText(DISPLAY, "Camera scale: {:.2e}x".format(CAMERA.scale), font, (SCREEN_WIDTH - 10, 10), WHITE, False)

        pygame.display.update()
        CLOCK.tick(FPS)