示例#1
0
 private void PlaceCliffs(int level)
 {
     for (int x = 0; x < worldWidth; x++)
     {
         for (int y = 0; y < worldWidth; y++)
         {
             World.Tile tile = world.GetTile(x, y, level, World.Layer.Floor);
             if (tile == World.Tile.Pfb_Floor_Small ||
                 tile == World.Tile.Pfb_Water)
             {
                 for (int xx = -1; xx < 2; xx++)
                 {
                     for (int yy = -1; yy < 2; yy++)
                     {
                         if (x + xx >= 0 && x + xx < worldWidth && y + yy >= 0 && y + yy < worldWidth)
                         {
                             if (world.GetTile(x + xx, y + yy, level, World.Layer.Floor) == World.Tile.Underground)
                             {
                                 world.SetTile(x, y, level, World.Layer.Floor, World.Tile.Cliff);
                                 goto NextIteration;
                             }
                         }
                     }
                 }
             }
             NextIteration : continue;
         }
     }
 }
示例#2
0
 private void FillLayerRandomOnFloor(int level, World.Tile tile, float percentage, bool onlyPlaceOnEmptySpot)
 {
     for (int x = 0; x < worldWidth; x++)
     {
         for (int y = 0; y < worldWidth; y++)
         {
             // If there is floor below
             if (world.GetTile(x, y, level, World.Layer.Floor) == World.Tile.Pfb_Floor_Small)
             {
                 // Check if spot is open or not if applicable
                 if (world.GetTile(x, y, level, World.Layer.Object) != World.Tile.Empty && onlyPlaceOnEmptySpot)
                 {
                     // Do nothing if not empty
                 }
                 else
                 {
                     // Chance to place object
                     float randomFloat = Random.Range(0f, 1f);
                     if (randomFloat < percentage)
                     {
                         // Place object
                         world.SetTile(x, y, level, World.Layer.Object, tile);
                     }
                 }
             }
         }
     }
 }
示例#3
0
        private void AssignTask()
        {
            Task parent = new Task();
            Subtask constructBuilding = new Subtask();
            parent.AddSubtask(constructBuilding);

            if (building.GetPrimitiveObject().GetBuildingType() == BuildingType.Infrastructure)
            {
                for (int x = 0; x < building.GetTileSize().X; x++)
                {
                    for (int y = 0; y < building.GetTileSize().Y; y++)
                    {
                        Instruction workerTask = new Instruction();
                        World.Tile workTile = World.WorldController.GetTileAt(building.GetTilePosition() + new Vector2(x, y), isTileCoords: true);
                        if (workTile == null)
                            continue;

                        Process waitAtTile = new Process(workTile, 1f, onComplete => { });
                        workerTask.AddProcess(waitAtTile);

                        Process constructProcess = new Process(workTile, timeForEachJob, onComplete => {
                            Vector2 position = building.WorldSpaceToLocalSpace(onComplete.GetWorkTile().GetTileNumber());
                            RemoveConstructionRenderer(position);
                        });
                        constructProcess.RegisterOnTickHandle(onTick =>
                        {
                            float percentage = 80 - (onTick.GetRemainingTime() / onTick.GetProcessTime()) * 80;
                            Vector2 position = building.WorldSpaceToLocalSpace(onTick.GetWorkTile().GetTileNumber());
                            constructionRenderers[(int) position.X, (int) position.Y]?.SetPercentage(percentage);
                        });
                        workerTask.AddProcess(constructProcess);
                        constructBuilding.AddInstruction(workerTask);
                    }
                }
            }
            else
            {
                Instruction workerTask = new Instruction();
                World.Tile workTile = World.WorldController.GetTileAt(building.GetTilePosition(), isTileCoords: true);
                if (workTile == null)
                    return;

                Process waitAtTile = new Process(workTile, 1f, onComplete => { });
                workerTask.AddProcess(waitAtTile);

                Process constructProcess = new Process(workTile, timeForEachJob, onComplete => {
                    Vector2 position = building.WorldSpaceToLocalSpace(onComplete.GetWorkTile().GetTileNumber());
                    RemoveConstructionRenderer(position);
                });
                constructProcess.RegisterOnTickHandle(onTick =>
                {
                    float percentage = 80 - (onTick.GetRemainingTime() / onTick.GetProcessTime()) * 80;
                    Vector2 position = building.WorldSpaceToLocalSpace(onTick.GetWorkTile().GetTileNumber());
                    constructionRenderers[0, 0]?.SetPercentage(percentage);
                });
                workerTask.AddProcess(constructProcess);
                constructBuilding.AddInstruction(workerTask);
            }
        }
示例#4
0
        public void Think(long ctick)
        {
            if (CurTarget != null && CurTarget.Position.CurMap == Position.CurMap)
            {
                var dist = Point2D.Distance(CurTarget.Position.X, CurTarget.Position.Y, Position.X, Position.Y);

                if (TryAttack(CurTarget, dist, ctick))
                {
                    return;
                }

                if (dist > 18 || CurTarget.Position.CurMap != Position.CurMap)
                {
                    CurTarget = null;
                    return;
                }

                if (LastWalk + WalkSpeed < ctick)
                {
                    LastWalk         = ctick;
                    NavMesh          = new NavMesh(this.Position.CurMap);
                    CurTargetLastPos = CurTarget.Position.CurrentTile;
                    WalkPath         = FindPath(NavMesh.Tiles[Position.CurrentTile.X, Position.CurrentTile.Y],
                                                NavMesh.Tiles[CurTarget.Position.CurrentTile.X, CurTarget.Position.CurrentTile.Y]);
                    DoMove();
                }
            }

            if (CurTarget == null || CurTarget.Position.CurMap != Position.CurMap)
            {
                bool onscreen = false;
                foreach (var plyr in Position.CurMap.PlayersList)
                {
                    var dist = Point2D.Distance(plyr.Position.X, plyr.Position.Y, Position.X, Position.Y);
                    if (dist <= AggroRange)
                    {
                        CurTarget = plyr;
                        return;
                    }
                    if (dist <= 15)
                    {
                        onscreen = true;
                    }
                }
                if ((CurTarget == null || CurTarget.Position.CurMap != Position.CurMap) && onscreen)
                {
                    if (LastWalk + WalkSpeed < ctick)
                    {
                        LastWalk = ctick;
                        NavMesh  = new NavMesh(this.Position.CurMap);
                        var rndMoveTile = Position.CurrentTile.Neighbours[Dice.Random(Position.CurrentTile.Neighbours.Count - 1)];
                        WalkPath = FindPath(NavMesh.Tiles[Position.CurrentTile.X, Position.CurrentTile.Y],
                                            NavMesh.Tiles[rndMoveTile.X, rndMoveTile.Y]);
                        DoMove();
                    }
                }
            }
        }
示例#5
0
    public static bool BuildPath(Dictionary <Vector2Int, World.Tile> inGrid, Vector2 startPos, Vector2 endPos, ref Path outPath)
    {
        Vector2Int startPosInt = World.Get().GetGridLocation(startPos);
        Vector2Int endPosInt   = World.Get().GetGridLocation(endPos);

        if (!inGrid.ContainsKey(startPosInt) || !inGrid.ContainsKey(endPosInt))
        {
            return(false);
        }

        World.Tile start = inGrid[startPosInt];
        World.Tile end   = inGrid[endPosInt];

        List <World.Tile> open         = new List <World.Tile>();
        List <World.Tile> closed       = new List <World.Tile>();
        List <World.Tile> adjancencies = new List <World.Tile>();

        World.Tile current = start;

        open.Add(current);

        while (open.Count != 0 && !closed.Exists(x => x.Coordinates == end.Coordinates) && closed.Count < 10000)
        {
            current = open[0];
            open.Remove(current);
            closed.Add(current);
            adjancencies = World.Tile.GetAdjacentTiles(inGrid, current);

            foreach (World.Tile tile in adjancencies)
            {
                if (!closed.Contains(tile) && tile.IsTraversable())
                {
                    if (!open.Contains(tile))
                    {
                        tile.Parent           = current;
                        tile.DistanceToTarget = (tile.Coordinates - endPosInt).magnitude;
                        tile.Cost             = 1.0f + tile.Parent.Cost;
                        open.Add(tile);
                        open = open.OrderBy(t => t.F).ToList <World.Tile>();
                    }
                }
            }
        }

        if (!closed.Exists(x => x.Coordinates == endPosInt))
        {
            return(false);
        }

        World.Tile curr = closed[closed.IndexOf(current)];
        while (curr != null && curr.Parent != start)
        {
            outPath.PathPoints.Add(World.Get().GetWorldLocation(curr.Coordinates));
            curr = curr.Parent;
        }

        return(true);
    }
示例#6
0
 private void FillLayer(int level, World.Layer layer, World.Tile tile)
 {
     for (int x = 0; x < worldWidth; x++)
     {
         for (int y = 0; y < worldWidth; y++)
         {
             world.SetTile(x, y, level, layer, tile);
         }
     }
 }
示例#7
0
 private void ReplaceLayer(int level, World.Layer layer, World.Tile oldTile, World.Tile newTile)
 {
     for (int x = 0; x < worldWidth; x++)
     {
         for (int y = 0; y < worldWidth; y++)
         {
             if (world.GetTile(x, y, level, layer) == oldTile)
             {
                 world.SetTile(x, y, level, layer, newTile);
             }
         }
     }
 }
示例#8
0
        private static void tileUnderCursor()
        {
            World.Tile t = World.WorldController.GetMouseOverTile();
            if (t == null)
            {
                DebugConsole.instance.log("No tile under cursor");
                return;
            }

            DebugConsole.instance.log(t);
            DebugConsole.instance.log("Infrastructure Building: " + t.GetInfrastructureItem());
            DebugConsole.instance.log("Gameplay Building: " + t.GetGameplayItem());
        }
示例#9
0
    public static void InstantiateWorld(World world)
    {
        for (int level = 0; level < world.GetLevels(); level++)
        {
            for (int layer = 0; layer < 2; layer++)
            {
                for (int x = 0; x < world.GetWidth(); x++)
                {
                    for (int y = 0; y < world.GetWidth(); y++)
                    {
                        World.Tile tile = world.GetTile(x, y, level, layer);

                        // TODO: How to find prefabs in folders without having to explicitly name them, so that a majority
                        // of prefabs can be ran through one simple code instead of cases for every single prefab?
                        // How to avoid just having to move everything out into one massive folder?

                        if (tile == World.Tile.Pfb_Floor_Small)
                        {
                            Instantiate("Small Grid Test/" + tile.ToString(), x, level, y, 0);
                        }

                        else if (tile == World.Tile.Pfb_Water)
                        {
                            Instantiate("Terrain/" + tile.ToString(), x, level, y, 0);
                        }

                        else if (tile == World.Tile.Pfb_Entity_Slime)
                        {
                            Instantiate("Entities/" + tile.ToString(), x, level, y, 0);
                        }

                        else if (tile == World.Tile.Pfb_Flower)
                        {
                            // TEMP: Trickery to only place flowers in a checkerboard grid to avoid adjacent flowers
                            // This leaves ghost flowers in the data array and this code should be changed or removed
                            if (Mathf.Abs(x - y) % 2 == 0)
                            {
                                Instantiate("Foliage/" + tile.ToString(), x, level, y, 0);
                            }
                        }

                        else if (tile == World.Tile.Cliff)
                        {
                            SpawnCliffs(x, y, level, layer, world);
                        }
                    }
                }
            }
        }
    }
示例#10
0
        public List <World.Tile> FindPath(World.Tile fir, World.Tile sec)
        {
            AStar <World.Tile> astar = new AStar <World.Tile>(
                delegate(World.Tile t1, World.Tile t2)
            {
                var xdiff = (t1.X - t2.X);
                var ydiff = (t1.Y - t2.Y);
                return(Math.Sqrt(xdiff * xdiff + ydiff * ydiff));
            });

            astar.FindPath(fir, sec);//, runindex);

            return(astar.Path);
        }
示例#11
0
 private void FillLayerRandom(int level, World.Layer layer, World.Tile tile, float percentage)
 {
     for (int x = 0; x < worldWidth; x++)
     {
         for (int y = 0; y < worldWidth; y++)
         {
             // Chance to place object
             float randomFloat = Random.Range(0f, 1f);
             if (randomFloat < percentage)
             {
                 // Place object
                 world.SetTile(x, y, level, layer, tile);
             }
         }
     }
 }
        /// <summary>
        /// Safely gets the state of the neighboring tile at the specified location.
        /// </summary>
        /// <param name="tileStateIndex">The index in <see cref="TileStates"/> to modify.</param>
        private TileState SafeGetState(int x, int y, ProtoArray <World.Tile> tiles)
        {
            if (x < tiles.Width && x >= 0 && y < tiles.Height && y >= 0)
            {
                World.Tile neighbor     = tiles[x, y];
                Type       neighborType = neighbor.GetType();

                if (neighborType == this.CompatibleTile)
                {
                    return(TileState.Compatible);
                }
                if (neighborType == this.RepresentedTile)
                {
                    return(TileState.Identical);
                }

                return(TileState.Incompatible);
            }
            else
            {
                return(TileState.Compatible);
            }
        }
示例#13
0
    private static void SpawnCliffs(int x, int y, int level, int layer, World world)
    {
        // Ignore edges of map to avoid out of index error
        if (x == 0 || y == 0 || x == world.GetWidth() - 1 || y == world.GetWidth() - 1)
        {
            return;
        }

        // Spawn water bottom level
        if (level == 0)
        {
            Instantiate("Terrain/Pfb_Water", x, level, y, 0);
        }

        bool side = false;

        World.Tile leftTile        = world.GetTile(x - 1, y, level, layer);
        World.Tile rightTile       = world.GetTile(x + 1, y, level, layer);
        World.Tile topTile         = world.GetTile(x, y - 1, level, layer);
        World.Tile bottomTile      = world.GetTile(x, y + 1, level, layer);
        World.Tile topleftTile     = world.GetTile(x - 1, y - 1, level, layer);
        World.Tile toprightTile    = world.GetTile(x + 1, y - 1, level, layer);
        World.Tile bottomleftTile  = world.GetTile(x - 1, y + 1, level, layer);
        World.Tile bottomrightTile = world.GetTile(x + 1, y + 1, level, layer);

        // Left Cliff
        if (leftTile == World.Tile.Underground)
        {
            Instantiate("Terrain/Pfb_Cliff_Short", x, level, y, 180);
            side = true;
        }

        // Right Cliff
        if (rightTile == World.Tile.Underground)
        {
            Instantiate("Terrain/Pfb_Cliff_Short", x, level, y, 0);
            side = true;
        }

        // Top Cliff
        if (topTile == World.Tile.Underground)
        {
            Instantiate("Terrain/Pfb_Cliff_Short", x, level, y, 90);
            side = true;
        }

        // Bottom Cliff
        if (bottomTile == World.Tile.Underground)
        {
            Instantiate("Terrain/Pfb_Cliff_Short", x, level, y, 270);
            side = true;
        }

        // Place floor if no side, meaning only corner
        if (side == false)
        {
            Instantiate("Small Grid Test/Pfb_Floor_Small", x, level, y, 0);
        }

        //Top Right Corner
        if (toprightTile == World.Tile.Underground &&
            topTile == World.Tile.Cliff &&
            rightTile == World.Tile.Cliff)
        {
            Instantiate("Terrain/Pfb_Cliff_Corner_Short", x, level, y, 90);
        }

        // Top Left Corner
        if (topleftTile == World.Tile.Underground &&
            topTile == World.Tile.Cliff &&
            leftTile == World.Tile.Cliff)
        {
            Instantiate("Terrain/Pfb_Cliff_Corner_Short", x, level, y, 180);
        }

        // Bottom Right Corner
        if (bottomrightTile == World.Tile.Underground &&
            bottomTile == World.Tile.Cliff &&
            rightTile == World.Tile.Cliff)
        {
            Instantiate("Terrain/Pfb_Cliff_Corner_Short", x, level, y, 0);
        }

        // Bottom Left Corner
        if (bottomleftTile == World.Tile.Underground &&
            bottomTile == World.Tile.Cliff &&
            leftTile == World.Tile.Cliff)
        {
            Instantiate("Terrain/Pfb_Cliff_Corner_Short", x, level, y, 270);
        }
    }
示例#14
0
        public static List <World.Tile> GetAdjacentTiles(Dictionary <Vector2Int, World.Tile> inGrid, World.Tile tile)
        {
            List <World.Tile> temp = new List <World.Tile>();

            Vector2Int coordinates = tile.Coordinates;

            if (inGrid.ContainsKey(coordinates + Vector2Int.up))
            {
                temp.Add(inGrid[coordinates + Vector2Int.up]);
            }

            if (inGrid.ContainsKey(coordinates + Vector2Int.down))
            {
                temp.Add(inGrid[coordinates + Vector2Int.down]);
            }

            if (inGrid.ContainsKey(coordinates + Vector2Int.left))
            {
                temp.Add(inGrid[coordinates + Vector2Int.left]);
            }

            if (inGrid.ContainsKey(coordinates + Vector2Int.right))
            {
                temp.Add(inGrid[coordinates + Vector2Int.right]);
            }

            return(temp);
        }
示例#15
0
文件: Fire.cs 项目: Natsirtt/ggj-2019
 public void SetWorldTile(World.Tile tileToGiveToFireScript)
 {
     GridTile = tileToGiveToFireScript;
 }
示例#16
0
文件: Fire.cs 项目: Natsirtt/ggj-2019
    // Update is called once per frame
    void Update()
    {
        if (!shouldUpdate)
        {
            return;
        }

        if (!spawnedInitialWorkers && GridTile.TileType == World.Tile.Type.Hearth)
        {
            spawnedInitialWorkers = true;
            for (int i = 0; i < World.Get().GenerationParameters.resources.startingWorkers; i++)
            {
                GameObject worker = World.Get().SpawnWorker(this, false);
                ListOfWorkers.Add(worker);
            }
        }
        if (needsToActivate)
        {
            Activate();
            needsToActivate = false;
        }
        if (nextHouseSpawnTick <= Time.time)
        {
            World.Tile tile = influence.OrderBy(t => Random.value).ToList().Find(t => t.TileType == World.Tile.Type.Grass && !world.GetTilesInRadius(t.Coordinates, world.GenerationParameters.infrastructures.minimumManhattanDistanceBetweenHouses).Any(neighbour => neighbour.TileType == World.Tile.Type.House));
            if (tile != null)
            {
                world.SetTileType(tile.Coordinates, World.Tile.Type.House);
            }
            nextHouseSpawnTick = Time.time + Random.Range(world.GenerationParameters.infrastructures.houseSpawnPerSecondInterval.x, world.GenerationParameters.infrastructures.houseSpawnPerSecondInterval.y);
        }

        burnProgress += Time.deltaTime * currentBurnRatePerSecond;
        if (burnProgress >= 1f)
        {
            int woodBurnt = Mathf.FloorToInt(burnProgress);
            if (globalInventory.CurrentWood < woodBurnt)
            {
                // Warn the player, dim down the fire?
                Shrink();
                burnProgress = 0f;
                return;
            }
            globalInventory.RemoveWood(woodBurnt);
            burnProgress -= (float)woodBurnt;
        }
        spawnProgress += Time.deltaTime * currentWorkerSpawnRate;
        if (spawnProgress >= 1f)
        {
            int spawning = Mathf.FloorToInt(spawnProgress);
            spawnProgress = spawnProgress - spawning;
            while (spawning > 0)
            {
                // TODO randomize this position
                GameObject worker = world.SpawnWorker(this);
                listOfAssociatedWorkers.Add(worker);
                spawning -= 1;
            }
        }
        foreach (JobDispatcher.Job job in Jobs.chopJobs())
        {
            Debug.DrawLine(transform.position, world.GetWorldLocation(job.Coordinates));
        }
    }
示例#17
0
 World.Tile RandomMoveTile(World.Tile pos)
 {
     return(null);
 }
示例#18
0
    /// <summary>
    /// Update state, must be called once in each game loop
    /// </summary>
    /// <param name="world"></param>
    /// <param name="frame"></param>
    public override void Update(World world)
    {
        Orientation motion = Orientation.None;

        base.Update(world);

        switch (state)
        {
        case State.Stand:
            break;

        case State.Walk:
            break;

        case State.Jump:
            break;

        case State.Fall:
            break;

        case State.Crouch:
            break;
        }

        /* andar o correr */
        if (floor)
        {
            if (Graphics.Window.GetInput(Input.Button_A))
            {
                targetSpeed = runSpeed;
                aspeed      = 4;
            }
            else
            {
                targetSpeed = runSpeed / 2;
                aspeed      = 6;
            }
        }

        /* andar a la derecha */
        if (Graphics.Window.GetInput(Input.Right))
        {
            motion  = orientation = Orientation.Right;
            xspeed += dvx;
            if (xspeed > targetSpeed)
            {
                xspeed = targetSpeed;
            }
        }
        else if (floor && xspeed > 0)
        {
            xspeed -= dvx;
            if (xspeed < 0)
            {
                xspeed = 0;
            }
        }

        /* andar a la izquierda */
        if (Graphics.Window.GetInput(Input.Left))
        {
            motion  = orientation = Orientation.Left;
            xspeed -= dvx;
            if (xspeed < -targetSpeed)
            {
                xspeed = -targetSpeed;
            }
        }
        else if (floor && xspeed < 0)
        {
            xspeed += dvx;
            if (xspeed > 0)
            {
                xspeed = 0;
            }
        }

        /* iniciar salto */
        if (Graphics.Window.GetInput(Input.Button_B))
        {
            if (!jumping && floor)
            {
                jumping = true;
                t0Jump  = frame;
            }
        }
        else if (jumping)
        {
            jumping = false;
        }

        /* salto */
        if (jumping && frame - t0Jump < timeJump)
        {
            yspeed = -jumpSpeed;
        }

        /* gravedad */
        else if (!floor)
        {
            yspeed += dvy;
            if (yspeed > fallSpeed)
            {
                yspeed = fallSpeed;
            }
        }

        /* posicion actual */
        int oldx = Fixed.Get(x_fix);
        int oldy = Fixed.Get(y_fix);

        /* actualiza posicion */
        x_fix += xspeed;
        y_fix += yspeed;
        x      = Fixed.Get(x_fix);
        y      = Fixed.Get(y_fix);

        int tmpx = x;
        int tmpy = y;

        /* ajusta posición final */
        if (x < 0)
        {
            x      = 0;
            xspeed = 0;
        }
        else if (x > world.Width - 16)
        {
            x      = world.Width - 16;
            xspeed = 0;
        }

        /* salto */
        if (y < oldy)
        {
            floor = false;
            int[] points = { 4, 12 };
            int   c;
            for (c = 0; c < points.Length; c++)
            {
                World.Tile tile = world.GetTile(x + points[c], y);
                if (tile.Type == World.Type.Solid || tile.Type == World.Type.Question)
                {
                    y      = (y + 16) & ~15;
                    yspeed = 0;
                    t0Jump = 0;
                    if (tile.Type == World.Type.Question)
                    {
                        new Bumper(world, Game.objects, 0, tile.Row, tile.Col, 51);
                    }
                }
                else if (tile.Type == World.Type.Coin)
                {
                    world.ClearTile(tile.Row, tile.Col);
                    new Collect(world, tile.Col * 16, tile.Row * 16);
                    Game.AddCoin();
                }
            }
        }

        /* reposo/caída */
        else
        {
            int[]      points = { 4, 12 };
            int        c;
            World.Tile tile;
            floor = false;
            for (c = 0; c < points.Length; c++)
            {
                tile = world.GetTile(x + points[c], y + height);
                if (tile.Type == World.Type.Solid || tile.Type == World.Type.OneWay || tile.Type == World.Type.Question)
                {
                    y     &= ~15;
                    floor  = true;
                    yspeed = 0;
                }
                else if (tile.Type == World.Type.Coin)
                {
                    world.ClearTile(tile.Row, tile.Col);
                    new Collect(world, tile.Col * 16, tile.Row * 16);
                    Game.AddCoin();
                }
            }
        }

        /* izquierda */
        if (x < oldx)
        {
            int[] points = { 0, 8, 16, 24, 31 };
            int   c;
            for (c = 0; c < points.Length; c++)
            {
                World.Tile tile = world.GetTile(x, y + points[c]);
                if (tile.Type == World.Type.Solid || tile.Type == World.Type.Question)
                {
                    x      = (x + 16) & ~15;
                    xspeed = 0;
                }
                else if (tile.Type == World.Type.Coin)
                {
                    world.ClearTile(tile.Row, tile.Col);
                    new Collect(world, tile.Col * 16, tile.Row * 16);
                    Game.AddCoin();
                }
            }
        }

        /* derecha */
        else if (x > oldx)
        {
            int[] points = { 0, 8, 16, 24, 31 };
            int   c;
            for (c = 0; c < points.Length; c++)
            {
                World.Tile tile = world.GetTile(x + width, y + points[c]);
                if (tile.Type == World.Type.Solid || tile.Type == World.Type.Question)
                {
                    x     &= ~15;
                    xspeed = 0;
                }
                else if (tile.Type == World.Type.Coin)
                {
                    world.ClearTile(tile.Row, tile.Col);
                    new Collect(world, tile.Col * 16, tile.Row * 16);
                    Game.AddCoin();
                }
            }
        }

        /* reajusta fix si se ha corregido */
        if (tmpx != x)
        {
            x_fix = Fixed.Set(x);
        }
        if (tmpy != y)
        {
            y_fix = Fixed.Set(y);
        }

        /* actualiza mundo */
        if (xspeed > 0)
        {
            if (x - world.X > 160)
            {
                world.X = x - 160;
            }
            if (world.X + Graphics.Hres > world.Width)
            {
                world.X = world.Width - Graphics.Hres;
            }
        }
        else if (xspeed < 0)
        {
            if (x - world.X < 120)
            {
                world.X = x - 120;
            }
            if (world.X < 0)
            {
                world.X = 0;
            }
        }

        /* dibuja */
        if (orientation == Orientation.Right)
        {
            flags &= ~TileFlags.FlipX;
        }
        else if (orientation == Orientation.Left)
        {
            flags |= TileFlags.FlipX;
        }
        sprite.Flags = flags;

        sprite.SetPosition(x - world.X, y - world.Y);

        /* parado */
        if (xspeed == 0 && yspeed == 0)
        {
            sprite.Picture = 0;
        }
        /* en salto */
        else if (yspeed < 0)
        {
            sprite.Picture = 7;
        }
        /* en caída */
        else if (yspeed > 0)
        {
            sprite.Picture = 8;
        }
        /* en carrera */
        else if (orientation == Orientation.Right && xspeed > 0 || orientation == Orientation.Left && xspeed < 0)
        {
            sprite.Picture = (frame / aspeed) % 3;
        }
        /* frenado */
        else
        {
            sprite.Picture = 9;
        }
    }