Changeset 7639 for 2016/27/SimoR


Ignore:
Timestamp:
2016-07-02 21:59:20 (3 years ago)
Author:
sieerinn
Message:

Liikkuvat tasanteet toimii

Location:
2016/27/SimoR/SimplePhysicsTest
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • 2016/27/SimoR/SimplePhysicsTest/SimplePhysics/Game.cs

    r7638 r7639  
    11using System; 
     2using System.Collections.Concurrent; 
    23using System.Collections.Generic; 
     4using System.Linq; 
     5using System.Threading.Tasks; 
    36using Jypeli; 
    47using Jypeli.Widgets; 
     
    9093        } 
    9194 
    92         /// <summary> 
    93         /// Tarkistaa voisiko objekti törmätä tiileen, jos se liikkuisi 
    94         /// offset-vektorin verran pelimaailmassa. 
    95         /// </summary> 
    96         public bool CanCollide(Object obj, Vector offset) 
    97         { 
     95        public List<Object> Collisions(Object obj, Vector offset, bool shortCircuit = false) 
     96        { 
     97            var collisionList = new List<Object>(); 
     98 
    9899            var originalPosition = obj.Position; 
    99100            obj.Position += offset; 
     
    107108            var top = Math.Min(bottomLeft.Y + 1, tileMap.GetLength(1) - 1); 
    108109 
     110            Func<Object, bool> noCollision = (other) => 
     111                !other.IntersectsWith(obj) || 
     112                other.OneWayPlatform && !(obj.Bottom - offset.Y > other.Top - 1); 
     113 
    109114            // Tarkistetaan törmäykset tiilien kanssa. 
    110115            for (int x = left; x <= right; x++) 
     
    112117                for (int y = bottom; y <= top; y++) 
    113118                { 
    114                     if (tileMap[x, y] == null || !tileMap[x, y].IntersectsWith(obj)) 
     119                    if (tileMap[x, y] == null || noCollision(tileMap[x, y])) 
    115120                        continue; 
    116121 
    117                     if (tileMap[x, y].OneWayPlatform && !(obj.Bottom - offset.Y > tileMap[x, y].Top - 1)) 
    118                         continue; 
    119  
    120                     obj.Position = originalPosition; 
    121                     return true; 
     122                    collisionList.Add(tileMap[x, y]); 
     123 
     124                    if (shortCircuit) 
     125                    { 
     126                        obj.Position = originalPosition; 
     127                        return collisionList; 
     128                    } 
    122129                } 
    123130            } 
    124131 
    125132            // Tarkistetaan törmäykset muiden objektien kanssa. 
    126             for (int i = objectList.Count - 1; i >= 0; i--) 
    127             { 
    128                 if (i >= objectList.Count) continue; 
    129                 if (objectList[i] != obj && obj.IntersectsWith(objectList[i])) 
    130                 { 
    131                     obj.Position = originalPosition; 
    132                     return true; 
     133            foreach (var other in objectList) 
     134            { 
     135                if (other != obj && !noCollision(other)) 
     136                { 
     137                    collisionList.Add(other); 
     138 
     139                    if (shortCircuit) 
     140                    { 
     141                        obj.Position = originalPosition; 
     142                        return collisionList; 
     143                    } 
    133144                } 
    134145            } 
    135146 
    136147            obj.Position = originalPosition; 
    137             return false; 
     148            return collisionList; 
     149        } 
     150 
     151        public void UpdateMovingPlatform(Object obj, Time time) 
     152        { 
     153            var dt = time.SinceLastUpdate.TotalSeconds; 
     154            var objectsOnPlatform = new List<Object>(); 
     155 
     156            obj.Size += new Vector(4, 4); 
     157            foreach (var other in objectList) 
     158            { 
     159                if (other != obj && obj.IntersectsWith(other)) 
     160                { 
     161                    objectsOnPlatform.Add(other); 
     162                } 
     163            } 
     164            obj.Size -= new Vector(4, 4); 
     165 
     166            foreach (var other in objectsOnPlatform) 
     167            { 
     168                var movement = obj.Velocity * dt; 
     169                MoveObject(other, movement, dt); 
     170 
     171                if (obj.IntersectsWith(other)) 
     172                { 
     173                    other.OnCrushed(); 
     174                } 
     175            } 
     176 
     177            obj.Position += obj.Velocity * dt; 
    138178        } 
    139179 
     
    142182            var dt = time.SinceLastUpdate.TotalSeconds; 
    143183 
    144             // Lisätään objektin nopeuteen painovoima. 
    145             if (!obj.IgnoresGravity) 
     184            var groundObjects = Collisions(obj, new Vector(0, -2)); 
     185            if (groundObjects.Count > 0) 
     186            { 
     187                // Kitka maata vasten. 
     188                var highestFriction = groundObjects.Max(o => o.Friction); 
     189                var combinedFriction = highestFriction * obj.Friction; 
     190                obj.Velocity = new Vector(obj.Velocity.X * (1 - combinedFriction), obj.Velocity.Y); 
     191            } 
     192            else if (!obj.IgnoresGravity) 
     193            { 
     194                // Lisätään nopeuteen painovoima ilmassa ollessa. 
    146195                obj.Velocity += Gravity * dt; 
     196            } 
    147197 
    148198            // Lasketaan paljonko objektin pitäisi liikkua nopeutensa perusteella. 
    149199            var requiredMovement = obj.Velocity * dt; 
    150200 
     201            // Yritetään liikuttaa objektia. 
     202            MoveObject(obj, requiredMovement, dt); 
     203        } 
     204 
     205        private void MoveObject(Object obj, Vector requiredMovement, double dt) 
     206        { 
    151207            // Tarkistetaan törmäisikö objekti mihinkään, jos se liikkuisi 
    152208            // haluamansa matkan verran. 
    153             if (CanCollide(obj, requiredMovement)) 
     209            var collisions = Collisions(obj, requiredMovement); 
     210 
     211            if (collisions.Count > 0) 
    154212            { 
    155213                // Liikutetaan objekti törmäyksen kontaktipisteeseen. 
     
    177235            } 
    178236 
    179             // TODO: mitäs jos tiilelle halutaankin tägi ja handler? 
    180  
    181             // Tarkistetaan törmäykset muiden objektien kanssa. 
    182             // TODO: Tämä silmukka käydään nyt jo toisen kerran. Kerää törmäys tulokset CanCollide-aliohjelmasta? 
    183             for (int i = objectList.Count - 1; i >= 0; i--) 
    184             { 
    185                 if (i >= objectList.Count) continue; 
    186                 if (objectList[i] != obj && obj.IntersectsWith(objectList[i])) 
    187                 { 
    188                     obj.CollidedWith(objectList[i]); 
    189                 } 
    190             } 
    191  
    192             // Kitka maata vasten. 
    193             if (CanCollide(obj, new Vector(0, -2))) 
    194             { 
    195                 obj.Velocity = new Vector(obj.Velocity.X * (1 - obj.Friction), obj.Velocity.Y); 
     237            // Kutsutaan törmäyskäsittelijöitä. 
     238            foreach (var other in collisions) 
     239            { 
     240                obj.CollidedWith(other); 
    196241            } 
    197242        } 
     
    219264            while (Math.Abs(amount) > Math.Abs(unitStep)) 
    220265            { 
    221                 if (CanCollide(obj, step)) return true; 
     266                if (Collisions(obj, step, true).Count > 0) return true; 
    222267                obj.Position += step; 
    223268                amount -= unitStep; 
     
    226271            if (Math.Abs(amount) > 0) 
    227272            { 
    228                 if (CanCollide(obj, step * amount)) return true; 
     273                if (Collisions(obj, step * amount, true).Count > 0) return true; 
    229274                obj.Position += step * amount; 
    230275            } 
     
    251296            return TileToWorldPosition(point.X, point.Y); 
    252297        } 
    253          
     298 
    254299        public Object GetTileAt(int x, int y) 
    255300        { 
  • 2016/27/SimoR/SimplePhysicsTest/SimplePhysics/Object.cs

    r7638 r7639  
    4141        /// </summary> 
    4242        public bool IgnoresGravity { get; set; } 
     43 
     44 
     45        /// <summary> 
     46        /// Tapahtuu, kun olio murskautuu seinän ja liikkuvan staattisen objektin väliin. 
     47        /// </summary> 
     48        public event Action Crushed; 
    4349 
    4450        // Tägejä vastaavat törmäyskäsittelijät. 
     
    8894        } 
    8995 
     96        public void OnCrushed() 
     97        { 
     98            if (Crushed != null) 
     99            { 
     100                Crushed(); 
     101            } 
     102        } 
     103 
    90104        public override void Update(Time time) 
    91105        { 
  • 2016/27/SimoR/SimplePhysicsTest/SimplePhysicsTest/SimplePhysicsTest/SimplePhysicsTest.cs

    r7638 r7639  
    1818    { 
    1919        base.Update(time); 
    20         IsGrounded = Game.CanCollide(this, new Vector(0, -2)); 
     20        IsGrounded = Game.Collisions(this, new Vector(0, -2), true).Count > 0; 
    2121    } 
    2222} 
     
    3030    public MovingPlatform(Vector position, double width, double height) : base(width, height) 
    3131    { 
    32         direction = new Vector(0, 100); 
     32        direction = new Vector(100, 0); 
    3333        Position = startPosition = position; 
    34         IsStatic = true; 
     34        IgnoresGravity = true; 
    3535    } 
    3636 
    3737    public override void Update(Time time) 
    3838    { 
    39         if (Vector.Distance(startPosition, Position) > 200) 
     39        if (Vector.Distance(startPosition, Position) > 100) 
    4040        { 
    4141            direction = -direction; 
    4242        } 
    4343        Velocity = direction; 
    44         Position += Velocity * time.SinceLastUpdate.TotalSeconds; 
    45         base.Update(time); 
     44        Game.UpdateMovingPlatform(this, time); 
     45        //base.Update(time); 
    4646    } 
    4747} 
     
    6565        tilemap.SetTileMethod(Color.Black, CreateTile); 
    6666        tilemap.SetTileMethod(Color.FromHexCode("C6723D"), CreateOneWayTile); 
    67         tilemap.SetTileMethod(Color.FromHexCode("00FFFF"), CreateMovingPlatform); 
     67        tilemap.SetTileMethod(Color.FromHexCode("00FFFF"), CreateIceTile); 
     68        tilemap.SetTileMethod(Color.FromHexCode("FFFF00"), CreateMovingPlatform); 
     69        tilemap.SetTileMethod(Color.FromHexCode("B70909"), CreateDangerousBlock); 
    6870        tilemap.SetTileMethod(Color.Blue, CreatePlayer); 
    6971        tilemap.SetTileMethod(Color.Red, CreateEnemy); 
     
    8486    private void CreateTile(int x, int y) 
    8587    { 
    86         var tile = new SimplePhysics.Object(TileSize, TileSize); 
     88        var tile = new SimplePhysics.Object(TileSize, TileSize) { IsStatic = true }; 
    8789        tile.Color = Color.Green; 
    88         tile.IsStatic = true; 
     90        Add(tile); 
     91        SetTile(x, y, tile); 
     92    } 
     93 
     94    private void CreateIceTile(int x, int y) 
     95    { 
     96        var tile = new SimplePhysics.Object(TileSize, TileSize) { IsStatic = true }; 
     97        tile.Color = Color.Cyan; 
     98        tile.Friction = 0.0; 
     99        Add(tile); 
     100        SetTile(x, y, tile); 
     101    } 
     102 
     103    private void CreateDangerousBlock(int x, int y) 
     104    { 
     105        var tile = new SimplePhysics.Object(TileSize, TileSize) { IsStatic = true }; 
     106        tile.Color = Color.Red; 
     107        tile.Tag = "death"; 
    89108        Add(tile); 
    90109        SetTile(x, y, tile); 
     
    93112    private void CreateOneWayTile(int x, int y) 
    94113    { 
    95         var tile = new SimplePhysics.Object(TileSize, TileSize); 
     114        var tile = new SimplePhysics.Object(TileSize, TileSize) { IsStatic = true }; 
    96115        tile.Color = Color.Brown; 
    97         tile.IsStatic = true; 
    98116        tile.OneWayPlatform = true; 
    99117        Add(tile, -1); 
     
    105123        player = new SimplePlatformCharacter(TileSize * 0.98, TileSize * 1.98); 
    106124        player.Position = TileToWorldPosition(x, y); 
     125        player.Tag = "player"; 
     126        player.Crushed += player.Destroy; 
     127        Add(player); 
     128 
    107129        player.AddCollisionHandler("enemy", HitsEnemy); 
    108         Add(player); 
     130        player.AddCollisionHandler("death", (a, b) => player.Destroy()); 
    109131    } 
    110132 
     
    112134    { 
    113135        var pos = TileToWorldPosition(x, y); 
    114         var platform = new MovingPlatform(pos, TileSize, TileSize); 
     136        var platform = new MovingPlatform(pos, 3*TileSize, TileSize); 
    115137        Add(platform); 
    116138    } 
     
    120142        var enemy = new SimplePhysics.Object(TileSize * 0.99, TileSize * 0.99); 
    121143        enemy.Position = TileToWorldPosition(x, y); 
    122         enemy.Tag = "asdasd"; 
     144        enemy.Tag = "enemy"; 
    123145        Add(enemy); 
    124146    } 
Note: See TracChangeset for help on using the changeset viewer.