예제 #1
0
        public void Update(MouseButtonState buttonState, Vector2 mousePos, PlatformCharacter shooter, List <PlatformObject> allObjects, List <Projectile> projectiles)
        {
            if (buttonState == null)
            {
                return;
            }

            if (buttonState.justPressed)
            {
                foreach (PlatformObject p in allObjects)
                {
                    if (p is ChemBlock && p.bounds.Contains(mousePos))
                    {
                        clicked       = (ChemBlock)(p as ChemBlock).GetPrimaryBlock();
                        clickedOffset = mousePos - clicked.pos;
                        break;
                    }
                }
            }
            else if (buttonState.justReleased)
            {
                clicked = null;
            }

            if (clicked != null)
            {
                Vector2 offset = mousePos - (clicked.pos + clickedOffset);
                clicked.velocity = offset;
            }
        }
예제 #2
0
        public Vector2 GetCorrection(ChemBlock block)
        {
            Point   gridPos = blocks[block];
            Vector2 origin  = GetOrigin();

            return(new Vector2(origin.X + gridPos.X * Game1.BLOCKSIZE - block.pos.X, origin.Y + gridPos.Y * Game1.BLOCKSIZE - block.pos.Y));
        }
예제 #3
0
        public override void Update(InputState input, List <PlatformObject> allObjects, List <Projectile> projectiles)
        {
            Vectangle myBounds = bounds;

            foreach (PlatformObject obj in allObjects)
            {
                if (obj is ChemBlock && !obj.destroyed && myBounds.Intersects(obj.bounds))
                {
                    ChemBlock block = obj as ChemBlock;

                    /*if (!block.chemGrid.IsInside(myBounds))
                     *  continue;
                     */

                    if (signature != block.chemGrid.GetSignature())
                    {
                        continue;
                    }

                    Game1.instance.platformLevel.Record(sellAction, sellPrice);
                    block.chemGrid.DestroyAll();
                    Game1.instance.platformLevel.UpdateAnyBlocksLeft();
                }
            }
        }
예제 #4
0
 public ChemGrid(ChemBlock solo)
 {
     blocks = new Dictionary <ChemBlock, Point> {
         { solo, Point.Zero }
     };
     horizontalBonds = new HashSet <Point>();
     verticalBonds   = new HashSet <Point>();
 }
예제 #5
0
        public void Destroy(ChemBlock block)
        {
            Point p = blocks[block];

            horizontalBonds.Remove(p);
            verticalBonds.Remove(p);
            horizontalBonds.Remove(new Point(p.X + 1, p.Y));
            verticalBonds.Remove(new Point(p.X, p.Y + 1));

            blocks.Remove(block);

            UpdateConnectivity();
        }
예제 #6
0
        public void Update(List <PlatformObject> allObjects)
        {
            pos += velocity;

            Point windowSize = Game1.instance.Window.ClientBounds.Size;

            if (pos.X < 0 || pos.Y < 0 || windowSize.X < pos.X || windowSize.Y < pos.Y)
            {
                destroyed = true;
            }

            PlatformObject collisionObj = null;

            foreach (PlatformObject obj in allObjects)
            {
                if (CanCollide(obj) && obj.bounds.Contains(pos))
                {
                    collisionObj = obj;
                }
            }

            if (collisionObj == null)
            {
                return;
            }

            destroyed = true;

            const float VELOCITY_TRANSFER = 0.2f;

            // hit this thing
            switch (action)
            {
            case ProjectileAction.RIVET:
                if (collisionObj is ChemBlock)
                {
                    ChemBlock body = (ChemBlock)collisionObj;
                    //Vector2 nailDirection = velocity;
                    //nailDirection.Normalize();
                    body.Nailed(Vector2.Zero - GetCollisionNormal(collisionObj.bounds, pos - velocity, pos));
                    body.velocity += velocity * VELOCITY_TRANSFER;
                    body.UpdatedVelocity();
                }
                break;

            case ProjectileAction.BUBBLE:
                SpawnBubble(collisionObj, pos, GetCollisionNormal(collisionObj.bounds, pos - velocity, pos), allObjects);
                break;
            }
        }
예제 #7
0
        public void Cut(Vectangle area, List <PlatformObject> objects)
        {
            HashSet <ChemGrid> gridsChecked = new HashSet <ChemGrid>();

            foreach (PlatformObject obj in objects)
            {
                ChemBlock block = obj as ChemBlock;
                if (block != null && !gridsChecked.Contains(block.chemGrid) && block.bounds.Intersects(area))
                {
                    gridsChecked.Add(block.chemGrid);

                    block.chemGrid.Split(area);
                }
            }
        }
예제 #8
0
 public override void HandleColliding(PlatformObject obj, Vector2 move)
 {
     if (obj is ChemBlock)
     {
         ChemBlock block = (ChemBlock)obj;
         if (!IsBondedWith(block) && nailDuration > 0)
         {
             Vector2 moveDir = move;
             moveDir.Normalize();
             if (nailDirection.DotProduct(moveDir) > 0.5f)
             {
                 NailOnto(block);
                 nailDuration = 0;
             }
         }
     }
 }
예제 #9
0
        public void AddNail(ChemBlock a, Vector2 direction)
        {
            Point aPos   = blocks[a];
            Point offset = new Point((int)Math.Round(direction.X), (int)Math.Round(direction.Y));

            if (!IsValidNailOffset(offset))
            {
                return;
            }

            Point bPos  = aPos + offset;
            bool  found = false;

            foreach (KeyValuePair <ChemBlock, Point> kv in blocks)
            {
                if (kv.Value == bPos)
                {
                    found = true;
                    break;
                }
            }

            // no block to connect to
            if (!found)
            {
                return;
            }

            if (offset.X == 1)
            {
                horizontalBonds.Add(aPos);
            }
            else if (offset.X == -1)
            {
                horizontalBonds.Add(aPos + offset);
            }
            else if (offset.Y == 1)
            {
                verticalBonds.Add(aPos);
            }
            else if (offset.Y == -1)
            {
                verticalBonds.Add(aPos + offset);
            }
        }
예제 #10
0
        public override void Update(InputState input, List <PlatformObject> allObjects, List <Projectile> projectiles)
        {
            Vectangle myBounds = bounds;

            foreach (PlatformObject obj in allObjects)
            {
                if (obj is ChemBlock && obj.bounds.Intersects(myBounds) && !obj.destroyed)
                {
                    ChemBlock block = (ChemBlock)obj;
                    block.chemGrid.DoOutput();

                    if (signature != null && block.chemGrid.GetSignature() != signature && (signature2 == null || block.chemGrid.GetSignature() != signature2))
                    {
                        Game1.instance.splashes.Add(new Splash("WRONG OUTPUT!", TextAlignment.CENTER, Game1.font, Color.Orange, new Vector2(300, 350), new Vector2(0, -5), 0.96f, 0, 3));
                    }
                }
            }
        }
예제 #11
0
        void SpawnBubble(PlatformObject objectHit, Vector2 pos, Vector2 direction, List <PlatformObject> allObjects)
        {
            Vectangle objectBounds = objectHit.bounds;

            if (objectHit is ChemBlock)
            {
                pos = objectBounds.Center + direction * 16;
            }

            while (objectBounds.Contains(pos))
            {
                pos += direction;
            }

            pos += direction * 17;
            Vectangle bubbleBounds = new Vectangle(pos - new Vector2(16, 16), new Vector2(32, 32));

            bool failed = false;

            foreach (PlatformObject obj in allObjects)
            {
                if (obj.bounds.Intersects(bubbleBounds))
                {
                    failed = true;
                    break;
                }
            }

            if (!failed)
            {
                Game1.instance.platformLevel.Record(FactoryCommandType.SPENDCRYSTAL);

                ChemicalElement c        = ChemicalElement.WHITE;
                ChemBlock       newBlock = new ChemBlock(c, c.ToTexture(false), bubbleBounds.TopLeft, bubbleBounds.Size, c.ToColor());
                if (objectHit is ChemBlock)
                {
                    newBlock.NailOnto((ChemBlock)objectHit);
                }
                allObjects.Add(newBlock);
            }
        }
예제 #12
0
 public void NailOnto(ChemBlock other)
 {
     chemGrid.AddNail(this, other);
 }
예제 #13
0
        public void UpdateConnectivity()
        {
            Dictionary <Point, ChemBlock> blockMapping = new Dictionary <Point, ChemBlock>();
            HashSet <Point> inactiveBlocks             = new HashSet <Point>();

            foreach (KeyValuePair <ChemBlock, Point> kv in blocks)
            {
                blockMapping.Add(kv.Value, kv.Key);
                inactiveBlocks.Add(kv.Value);
            }

            //now flood fill regions until everything is filled
            while (inactiveBlocks.Count > 0)
            {
                Point originPoint = inactiveBlocks.First();
                inactiveBlocks.Remove(originPoint);

                ChemBlock originBlock = blockMapping[originPoint];
                ChemGrid  newGrid     = new ChemGrid(originBlock);
                originBlock.chemGrid = newGrid;
                originBlock.UnbondFromGroup();

                List <Point> activeBlocks = new List <Point>()
                {
                    originPoint
                };
                List <Point> nextActiveBlocks = new List <Point>();
                List <Point> finalPositions   = new List <Point>();
                while (activeBlocks.Count > 0)
                {
                    foreach (Point p in activeBlocks)
                    {
                        Func <Point, bool> addBlock = pos =>
                        {
                            inactiveBlocks.Remove(pos);
                            nextActiveBlocks.Add(pos);
                            ChemBlock block = blockMapping[pos];
                            block.UnbondFromGroup();
                            block.chemGrid = null;
                            newGrid.AddNail(blockMapping[p], block);
                            return(false);
                        };

                        Point up    = new Point(p.X, p.Y - 1);
                        Point down  = new Point(p.X, p.Y + 1);
                        Point left  = new Point(p.X - 1, p.Y);
                        Point right = new Point(p.X + 1, p.Y);

                        if (verticalBonds.Contains(up) && inactiveBlocks.Contains(up))
                        {
                            addBlock(up);
                        }
                        if (verticalBonds.Contains(p) && inactiveBlocks.Contains(down))
                        {
                            addBlock(down);
                        }
                        if (horizontalBonds.Contains(left) && inactiveBlocks.Contains(left))
                        {
                            addBlock(left);
                        }
                        if (horizontalBonds.Contains(p) && inactiveBlocks.Contains(right))
                        {
                            addBlock(right);
                        }
                    }

                    List <Point> temp = activeBlocks;
                    temp.Clear();
                    activeBlocks     = nextActiveBlocks;
                    nextActiveBlocks = temp;
                }
            }
        }
예제 #14
0
        public void AddNail(ChemBlock a, ChemBlock b)
        {
            System.Diagnostics.Debug.Assert(a.chemGrid == this);

            Vector2 blockOffsetPixels = b.pos - a.pos;
            Point   blockOffset       = new Point((int)Math.Round(blockOffsetPixels.X / Game1.BLOCKSIZE), (int)Math.Round(blockOffsetPixels.Y / Game1.BLOCKSIZE));

            if (!IsValidNailOffset(blockOffset))
            {
                return;
            }

            Point a_in_aPos = blocks[a];
            Point b_in_bPos = b.chemGrid != null? b.chemGrid.blocks[b]: new Point(0, 0);
            bool  sameGrids = blocks.ContainsKey(b);

            if (!sameGrids)
            {
                Point b_in_aPos = a_in_aPos + blockOffset;
                if (b.chemGrid == null)
                {
                    blocks[b]  = b_in_aPos;
                    b.chemGrid = this;
                    a.BondWith(b);
                }
                else
                {
                    // merge the grids
                    Point gridOffset = b_in_aPos - b_in_bPos;
                    foreach (Point p in b.chemGrid.horizontalBonds)
                    {
                        horizontalBonds.Add(p + gridOffset);
                    }
                    foreach (Point p in b.chemGrid.verticalBonds)
                    {
                        verticalBonds.Add(p + gridOffset);
                    }
                    foreach (KeyValuePair <ChemBlock, Point> kv in b.chemGrid.blocks)
                    {
                        blocks[kv.Key]  = kv.Value + gridOffset;
                        kv.Key.chemGrid = this;
                        a.BondWith(kv.Key);
                    }
                }
            }

            // they're already connected, just add the bond
            if (blockOffset.X == 0)
            {
                if (blockOffset.Y == 1)
                {
                    verticalBonds.Add(a_in_aPos);
                }
                else
                {
                    verticalBonds.Add(a_in_aPos + blockOffset);
                }
            }
            else if (blockOffset.X == 1)
            {
                horizontalBonds.Add(a_in_aPos);
            }
            else
            {
                horizontalBonds.Add(a_in_aPos + blockOffset);
            }
        }
예제 #15
0
        public void Update(List <PlatformObject> objects)
        {
            if (!triggered)
            {
                return;
            }

            foreach (PlatformObject obj in objects)
            {
                if (obj.bounds.Intersects(bounds))
                {
                    return;
                }
            }

            ChemicalSignature signature = Game1.instance.platformLevel.SpawnInputChemical(inputIndex);

            if (signature == null)
            {
                return;
            }

            triggered = false;

            int height = signature.height;
            int width  = signature.width;

            float startX = bounds.CenterX - width * 32 / 2;
            float startY = bounds.CenterY - height * 32 / 2;
            float curX   = startX;
            float curY   = startY;

            ChemBlock[,] blocksSpawned = new ChemBlock[width, height];

            for (int col = 0; col < width; ++col)
            {
                for (int row = 0; row < height; ++row)
                {
                    ChemicalElement c = signature[col, row];
                    if (c != ChemicalElement.NONE)
                    {
                        ChemBlock newBlock = new ChemBlock(c, c.ToTexture(false), new Vector2(curX, curY), new Vector2(32, 32), c.ToColor());
                        objects.Add(newBlock);

                        blocksSpawned[col, row] = newBlock;

                        if (col > 0 && blocksSpawned[col - 1, row] != null)
                        {
                            blocksSpawned[col - 1, row].NailOnto(newBlock);
                        }

                        if (row > 0 && blocksSpawned[col, row - 1] != null)
                        {
                            blocksSpawned[col, row - 1].NailOnto(newBlock);
                        }
                    }

                    curY += 32.5f;
                }

                curX += 32.5f;
                curY  = startY;

                Game1.instance.platformLevel.UpdateAnyBlocksLeft();
            }
        }