Ejemplo n.º 1
0
    void UpdateStaticCollisions()
    {
        for (int i = 0; i < currentParticleCount; i++)
        {
            WaterParticle particle = waterParticles[i];

            if (math.lengthsq(particle.velocity) < 0.01)
            {
                continue;
            }

            float3 startPosition = particle.position;
            float3 nextPosition  = particle.position + particle.velocity * Time.deltaTime;

            for (int j = 0; j < boxes.Length; j++)
            {
                if (boxes[j].TestCollision(startPosition, nextPosition, out float ratio, out float3 normal))
                {
                    particle.velocity = math.reflect(particle.velocity, normal) * elasticity;
                    float3 dir = math.normalize(startPosition - nextPosition);
                    particle.position = math.lerp(startPosition, nextPosition, ratio) + (dir * particleRadius);
                    break;
                }
            }
            waterParticles[i] = particle;
        }
    }
Ejemplo n.º 2
0
    void SimulateStartingKopa()
    {
        if (IsPlugged)
        {
            WaterPlug.GetComponent <KopaWaterplug>().enabled = true;
            WaterCopaClue.SetActive(true);
            WaterParticle.SetActive(false);

            if (WaterContainer.GetComponent <WaterContainerHeight>())
            {
                WaterContainer.GetComponent <WaterContainerHeight>().AbsorbWater(timeToAbsorbWater);
            }
        }
        else
        {
            WaterPlug.GetComponent <KopaWaterplug>().enabled = false;
            WaterCopaClue.SetActive(false);
            WaterParticle.SetActive(true);

            if (WaterContainer.GetComponent <WaterContainerHeight>())
            {
                WaterContainer.GetComponent <WaterContainerHeight>().FillWater(timeToFillWater);
            }

            particleStartSpeed    = 7.5f;
            particleStartLifetime = 0.7f;

            AkSoundEngine.PostEvent("waterfall_loop", gameObject);
            StartCoroutine(stopSFX(timeToStopSFX));
        }
    }
Ejemplo n.º 3
0
    private void OnTapEvent(Vector3 position)
    {
        var worldPostion = _camera.ScreenToWorldPoint(position);

        worldPostion.z = 0;

        int           particleCount = _waterParticles.Count;
        float         distance      = 9999999.0f;
        WaterParticle selected      = null;

        for (int a = 0; a < _waterParticles.Count; ++a)
        {
            var pos = _waterParticles[a].Normal * _waterParticles[a].Position;
            pos.z = 0;
            float dist = Vector3.Distance(pos, worldPostion);

            if (dist < distance)
            {
                selected = _waterParticles[a];
                distance = dist;
            }
        }

        if (selected != null)
        {
            selected.Velocity = _clickForce;
        }
    }
Ejemplo n.º 4
0
 void UpdatePredictedPosition()
 {
     for (int i = 0; i < particles.Length; i++)
     {
         WaterParticle particle = particles[i];
         particle.predictedPosition += particle.deltaPressure;
     }
 }
Ejemplo n.º 5
0
 void UpdatePositions()
 {
     for (int i = 0; i < currentParticleCount; i++)
     {
         WaterParticle particle = waterParticles[i];
         particle.position += particle.velocity * Time.deltaTime;
         waterParticles[i]  = particle;
     }
 }
Ejemplo n.º 6
0
 void UpdateVelocity()
 {
     for (int i = 0; i < currentParticleCount; i++)
     {
         WaterParticle particle = waterParticles[i];
         particle.velocity += particle.acceleration * Time.deltaTime;
         waterParticles[i]  = particle;
     }
 }
Ejemplo n.º 7
0
 void UpdateAcceleration()
 {
     for (int i = 0; i < currentParticleCount; i++)
     {
         WaterParticle particle = waterParticles[i];
         particle.acceleration += gravity * Time.deltaTime;
         waterParticles[i]      = particle;
     }
 }
Ejemplo n.º 8
0
    private void WaterParticleDestroyed(WaterParticle water)
    {
        if (GameController.Instance.raceOver)
        {
            return;
        }

        waterList.Remove(water);
        waterCountChange.Invoke(waterList.Count);
    }
Ejemplo n.º 9
0
 void ApplyForcePredictPosition()
 {
     for (int i = 0; i < particles.Length; i++)
     {
         WaterParticle particle = particles[i];
         particle.velocity          += new float2(0, -9.81f) * Time.deltaTime;
         particle.predictedPosition += Time.deltaTime * particle.velocity;
         particles[i] = particle;
     }
 }
Ejemplo n.º 10
0
 public WaterParticle[] UpdateParticle()
 {
     WaterParticle[] self = new WaterParticle[] { this };
     if (!WithinOneZero(this.Position + Direction))
     {
         Direction *= -1f;
     }
     this.Position += Direction;
     return(self);
 }
Ejemplo n.º 11
0
        public void Execute(int index)
        {
            WaterParticle currentParticle = waterParticles[index];

            currentParticle.velocity += deltaTime * currentParticle.force / currentParticle.density;

            float3 previousPosition = currentParticle.position;
            float3 nextPosition     = currentParticle.position + deltaTime * currentParticle.velocity;

            //Might get corrected by collision
            currentParticle.position += deltaTime * currentParticle.velocity;


            GetAxisBound(ref currentParticle.position.x, ref currentParticle.velocity.x, boxSize.x);
            GetAxisBound(ref currentParticle.position.y, ref currentParticle.velocity.y, boxSize.y);
            GetAxisBound(ref currentParticle.position.z, ref currentParticle.velocity.z, boxSize.z);

            //const float BOUND_DAMPING = -.5f;
            //if (currentParticle.position.x - particleSize < 0.0f)
            //{
            //    currentParticle.velocity.x *= BOUND_DAMPING;
            //    currentParticle.position.x = particleSize;
            //}
            //if (currentParticle.position.x + particleSize > boxSize.x)
            //{
            //    currentParticle.velocity.x *= BOUND_DAMPING;
            //    currentParticle.position.x = boxSize.x - particleSize;
            //}
            //if (currentParticle.position.y - particleSize < 0.0f)
            //{
            //    currentParticle.velocity.y *= BOUND_DAMPING;
            //    currentParticle.position.y = particleSize;
            //}
            //if (currentParticle.position.y + particleSize > boxSize.y)
            //{
            //    currentParticle.velocity.y *= BOUND_DAMPING;
            //    currentParticle.position.y = boxSize.y - particleSize;
            //}

            ////bound checking
            //for (int i = 0; i < boxes.Length; i++)
            //    if(boxes[i].TestCollision(previousPosition, nextPosition, out float ratio, out float3 normal))
            //        HandleCollision(ref currentParticle, previousPosition, nextPosition, ratio, normal);


            //for (int i = 0; i < spheres.Length; i++)
            //    if (spheres[i].TestCollision(previousPosition, nextPosition, out float ratio, out float3 normal))
            //        HandleCollision(ref currentParticle, previousPosition, nextPosition, ratio, normal);

            //for (int i = 0; i < innerBoxes.Length; i++)
            //    if (innerBoxes[i].TestCollision(previousPosition, nextPosition, out float ratio, out float3 normal))
            //        HandleCollision(ref currentParticle, previousPosition, nextPosition, ratio, normal);

            waterParticles[index] = currentParticle;
        }
Ejemplo n.º 12
0
    //NOT WORKING
    public WaterParticle[] SubdevideParticles()
    {
        WaterParticle []
        SubParticles = new WaterParticle[WaveSystem.SubdivitionCount];

        for (int i = 0; i < WaveSystem.SubdivitionCount; i++)
        {
            SubParticles[i] = new WaterParticle(Position + Direction, Direction, DispersionAngle / WaveSystem.SubdivitionCount);
        }

        return(SubParticles);
    }
Ejemplo n.º 13
0
    void UpdateVelocityVerocityViscosityUpdatePosition()
    {
        for (int i = 0; i < particles.Length; i++)
        {
            WaterParticle particle = particles[i];
            particle.velocity = (1f / Time.deltaTime) * (particle.predictedPosition - particle.position);

            //apply vorcity confinement and XSPH viscosity

            particle.position = particle.predictedPosition;
        }
    }
Ejemplo n.º 14
0
    public void GenerateInitialParticleData()
    {
        float anglePerSegment = 3.14165f * 2.0f / (float)_segmentCount;

        for (int a = 0; a < _segmentCount; ++a)
        {
            WaterParticle particle = new WaterParticle();
            _waterParticles.Add(particle);

            particle.Normal   = new Vector3(Mathf.Sin(anglePerSegment * a), Mathf.Cos(anglePerSegment * a), 0);
            particle.Position = _waterSize;
            particle.Velocity = 0.0f;
        }
    }
Ejemplo n.º 15
0
        public void Execute(int index)
        {
            WaterParticle currentParticle = waterParticles[index];

            currentParticle.density = 0;
            for (int i = 0; i < waterParticles.Length; i++)
            {
                WaterParticle otherParticle = waterParticles[i];
                float3        diff          = otherParticle.position - currentParticle.position;
                float         sqrtDistance  = math.lengthsq(diff);
                if (sqrtDistance < radiusSq)
                {
                    //float x = radiusSq - sqrtDistance;
                    currentParticle.density += mass * poly6 * math.pow(radiusSq - sqrtDistance, 3);//;x * x * x;
                }
            }
            //The ideal gas law, relating pressure to the summed density
            currentParticle.pressure = gazConst * (currentParticle.density - restDensity);
            waterParticles[index]    = currentParticle;
        }
Ejemplo n.º 16
0
        public void Execute(int index)
        {
            float3        forcePressure   = 0;
            float3        forceViscosity  = 0;
            WaterParticle currentParticle = waterParticles[index];

            for (int i = 0; i < waterParticles.Length; i++)
            {
                if (i == index)
                {
                    continue;
                }

                WaterParticle otherParticle = waterParticles[i];
                float3        diff          = otherParticle.position - currentParticle.position;
                float         sqrtDistance  = math.lengthsq(diff);
                if (sqrtDistance < radiusSq)
                {
                    float  distance      = math.sqrt(sqrtDistance);
                    float3 ratioDistance = radius - distance;

                    // compute pressure force contribution
                    float3 forcePressure1 = -math.normalize(diff) * mass;
                    float3 forcePressure2 = (currentParticle.pressure + otherParticle.pressure) / (2 * otherParticle.density);
                    forcePressure += forcePressure1 * forcePressure2 * spikyGrad * (ratioDistance * ratioDistance);

                    // compute viscosity force contribution
                    //float3 forceVisc1 = viscosity * mass;
                    float3 forceVisc1 = viscosity * mass;
                    float3 forceVisc2 = (otherParticle.velocity - currentParticle.velocity) / otherParticle.density;
                    float3 forceVisc3 = viscosityKernel * ratioDistance;
                    forceViscosity += forceVisc1 * forceVisc2 * forceVisc3;
                }
            }

            float3 forceGravity = gravity * currentParticle.density;

            currentParticle.force = forcePressure + forceViscosity + forceGravity;

            waterParticles[index] = currentParticle;
        }
Ejemplo n.º 17
0
    private void InitParticles()
    {
        int length = size.x * size.y * size.z;

        waterParticles = new NativeArray <WaterParticle>(length, Allocator.Persistent);

        int i = 0;

        for (int x = 0; x < size.x; x++)
        {
            for (int y = 0; y < size.y; y++)
            {
                for (int z = 0; z < size.z; z++)
                {
                    WaterParticle waterParticle = new WaterParticle();
                    waterParticle.position = startPos + spacing * new float3(x, y, z);
                    waterParticles[i]      = waterParticle;
                    i++;
                }
            }
        }
    }
Ejemplo n.º 18
0
    void CalculateLambda()
    {
        float POLY6 = 315f / (65f * math.PI * math.pow(particleRadius, 9f));


        for (int i = 0; i < particles.Length; i++)
        {
            WaterParticle pi = particles[i];

            for (int j = 0; j < particles.Length; j++)
            {
                WaterParticle pj         = particles[i];
                float2        diff       = pj.position - pi.position;
                float         distanceSq = math.lengthsq(diff);
                if (distanceSq < particleRadius * particleRadius)
                {
                    float squaredRatio = particleRadius - distanceSq;
                    pi.density += mass * POLY6 * squaredRatio * squaredRatio * squaredRatio;
                }
            }
            //particle.density = Sum_j -> mass_jj * Kernel(pi-pj, h);
            float constraint = (pi.density / restDensity) - 1;
        }
    }
Ejemplo n.º 19
0
 void HandleCollision(ref WaterParticle currentParticle, float3 previousPosition, float3 nextPosition, float ratio, float3 normal)
 {
     currentParticle.velocity = math.reflect(currentParticle.velocity, normal) * collisionElasticity;
     currentParticle.position = previousPosition;//math.lerp(previousPosition, currentParticle.position, ratio) + (normal * particleSize * 1.1f);
 }
Ejemplo n.º 20
0
    protected override void Spawn(Vector3 position)
    {
        WaterParticle waterParticle = WaterParticleManager.Instance.SpawnWaterParticle(position);

        waterParticle.RB.drag = 10f;
    }
Ejemplo n.º 21
0
        private bool PerformFrameProxy(ProxyObject sourceobject, BCBlockGameState gamestate)
        {
            var pPaddle = gamestate.PlayerPaddle;
            if (pPaddle == null) return true;
            //"bleed"
            RectangleF paddlerect = pPaddle.Getrect();
            for (int i = 0; i < (int) (20f*BCBlockGameState.ParticleGenerationFactor); i++)
            {
                //add a random blood particle...
                PointF randomspot =
                    new PointF((float) (paddlerect.Width*BCBlockGameState.rgen.NextDouble() + paddlerect.Left),
                               (float) (paddlerect.Bottom));

                WaterParticle Bloodparticle = new WaterParticle(randomspot, Color.Red);
                Bloodparticle.Velocity = new PointF((float) BCBlockGameState.rgen.NextDouble()*2 - 1,
                                                    (float) BCBlockGameState.rgen.NextDouble() - 0.5f);

                gamestate.Particles.Add(Bloodparticle);
            }

            return false;
        }
Ejemplo n.º 22
0
 void Awake()
 {
     WaterPlug.GetComponent <KopaWaterplug>().enabled = true;
     WaterCopaClue.SetActive(true);
     WaterParticle.SetActive(false);
 }
Ejemplo n.º 23
0
    void LateUpdate()
    {
        timeElapsed += Time.deltaTime;
        frameCount++;

        // Check for frame skip
        if (emit && timeElapsed >= emitTimeInterval && fo.waterLines.Count > 0f && foamTexCount > 0)
        {
            frameCount  = 0;
            timeElapsed = 0;

            int emitted     = 0;
            int triedToEmit = 0;

            if (emissionPriority == EmissionPriority.HighestVelocity || emissionPriority == EmissionPriority.RandomVelocityWeighted)
            {
                waterLineSorted = fo.waterLines.OrderByDescending(p => p.tri.velocityMagTimesDot).ToList();
            }
            else
            {
                waterLineSorted = fo.waterLines.OrderByDescending(p => p.tri.dynamicForce.magnitude * p.tri.dotNormalVelocityNormal).ToList();
            }

            WaterLine fastestLine = waterLineSorted[0];

            // Check if object should emit
            if (fastestLine.tri.velocityMagnitude > sleepTresholdVelocity && fo.IsTouchingWater && fo.enabled)
            {
                int pointCount = fo.waterLines.Count;

                // Check if emit per frame valid
                if (emitPerCycle >= pointCount)
                {
                    emitPerCycle = Mathf.Max(0, pointCount - 1);
                }

                // If random weighted, take the first quater of the descending list
                if (emissionPriority == EmissionPriority.RandomVelocityWeighted || emissionPriority == EmissionPriority.RandomForceWeighted)
                {
                    int cnt = pointCount / 4;
                    if (cnt < emitPerCycle)
                    {
                        cnt = emitPerCycle;
                    }
                    if (cnt < waterLineSorted.Count)
                    {
                        waterLineSorted = waterLineSorted.Take(cnt).ToList();
                    }
                }

                // Emit allowed number of particles
                while (emitted < emitPerCycle)
                {
                    // Controls
                    if (emitted >= pointCount)
                    {
                        break;
                    }
                    if (triedToEmit >= pointCount)
                    {
                        break;
                    }

                    // Get emit position
                    line = null;

                    // Get one point from water line
                    if (emissionPriority == EmissionPriority.Random)
                    {
                        line = fo.waterLines[Random.Range(0, fo.waterLines.Count)];
                    }
                    else if (emissionPriority == EmissionPriority.RandomVelocityWeighted)
                    {
                        line = waterLineSorted[Random.Range(0, waterLineSorted.Count)];
                    }
                    else if (emitted < waterLineSorted.Count)
                    {
                        line = waterLineSorted[emitted];
                    }

                    // Create new particle
                    if (line != null && line.tri.velocityMagnitude > sleepTresholdVelocity)
                    {
                        WaterParticle wp = new WaterParticle();

                        // Determine position
                        Vector3 p = line.p0;
                        p -= line.tri.velocity * Time.deltaTime;

                        // Setup particle
                        GameObject particleGo = GameObject.CreatePrimitive(PrimitiveType.Quad);
                        Destroy(particleGo.GetComponent <MeshCollider>());
                        float scale = maxParticleSize;
                        particleGo.transform.localScale = new Vector3(scale, scale, scale);
                        particleGo.transform.rotation   = Quaternion.Euler(90f, 0f, Random.Range(0f, 360f));
                        particleGo.transform.parent     = particleContainer.transform;
                        MeshRenderer meshRenderer = particleGo.GetComponent <MeshRenderer>();
                        p.y = surfaceElevation + fo.WaterHeightFunction(p.x, p.z);
                        particleGo.transform.position = p;

                        // Mesh
                        Material matInstance = new Material(Shader.Find("WaterFX/WaterParticle"));
                        matInstance.SetTexture("_MainTex", foamTextures[Random.Range(0, foamTextures.Count)]);
                        meshRenderer.material             = matInstance;
                        meshRenderer.material.renderQueue = renderQueue;
                        meshRenderer.enabled = true;

                        // Particle dynamics
                        vel                = line.tri.normal * line.tri.velocityMagnitude;
                        localVel           = fo.transform.InverseTransformVector(vel);
                        localVel.z         = 0f;
                        vel                = fo.transform.TransformVector(localVel);
                        vel.y              = 0f;
                        wp.initialVelocity = vel * initialVelocityModifier;
                        wp.initialAlpha    = Mathf.Clamp(line.tri.dynamicForce.magnitude * 0.033f * initialAlphaModifier, 0f, maxInitialAlpha);

                        // Init
                        wp.initialColor   = Color.white;
                        wp.initialColor.a = wp.initialAlpha;
                        wp.initialScale   = particleGo.transform.localScale;
                        wp.go             = particleGo;
                        wp.t          = particleGo.transform;
                        wp.mr         = meshRenderer;
                        wp.timeToLive = particleLifetime;
                        wp.mat        = meshRenderer.material;
                        wp.initTime   = Time.time;

                        // Start from the beginning of the array, replacing the oldest particle
                        if (pIndex >= maxParticles - 1)
                        {
                            pIndex = 0;
                        }

                        if (waterParticles[pIndex] != null)
                        {
                            Destroy(waterParticles[pIndex].go);
                        }
                        waterParticles[pIndex] = wp;
                        pIndex++;
                        emitted++;
                    }

                    triedToEmit++;
                }
            }
        }

        // Update existing particles
        for (int i = waterParticles.Length - 1; i >= 0; i--)
        {
            wp = waterParticles[i];
            if (wp != null)
            {
                float timeLived = Time.time - wp.initTime;
                if (timeLived >= wp.timeToLive)
                {
                    Destroy(wp.go);
                    waterParticles[i] = null;
                }
                else
                {
                    float livedPercent = timeLived / wp.timeToLive;

                    wp.t.position  += Time.deltaTime * velocityOverTime.Evaluate(livedPercent) * wp.initialVelocity;
                    wp.t.localScale = wp.initialScale * sizeOverTime.Evaluate(livedPercent);

                    float currentAlpha = alphaOverTime.Evaluate(livedPercent);
                    if (currentAlpha < 0.05f && livedPercent > 0.4f)
                    {
                        Destroy(wp.go);
                        waterParticles[i] = null;
                    }
                    else
                    {
                        wp.mr.material.SetColor(
                            "_TintColor",
                            new Color(wp.initialColor.r, wp.initialColor.g, wp.initialColor.b, wp.initialColor.a * currentAlpha)
                            );
                    }
                }
            }
        }
    }
Ejemplo n.º 24
0
    void UpdateInterWaterParticleCollision(float3 minPosition, float3 maxPosition)
    {
        //cache it
        int resolutionCube = marchingCubeResolution * marchingCubeResolution * marchingCubeResolution;

        if (waterParticleCountPerVoxel == null || waterParticleCountPerVoxel.Length != resolutionCube)
        {
            waterParticleCollisionTensor     = new short[marchingCubeResolution, marchingCubeResolution, marchingCubeResolution, maxWaterParticlePerZone];
            waterParticleCountPerVoxel       = new byte[marchingCubeResolution, marchingCubeResolution, marchingCubeResolution];
            particleIndicesInCollisionTensor = new int3[particleCount];
        }
        else
        {
            Array.Clear(waterParticleCollisionTensor, 0, resolutionCube * maxWaterParticlePerZone);
            Array.Clear(waterParticleCountPerVoxel, 0, resolutionCube);
            Array.Clear(particleIndicesInCollisionTensor, 0, particleCount);
        }

        //float3 minPosition = cubeMarchineZone.bounds.min;
        //float3 maxPosition = cubeMarchineZone.bounds.max;
        float invResolution = 1f / marchingCubeResolution;
        float step          = math.distance(minPosition, maxPosition) * invResolution;
        float invStep       = 1f / step;

        //Broad phase
        for (int i = 0; i < particleCount; i++)
        {
            WaterParticle particle = waterParticles[i];
            int3          index    = WaterMarchingCube.GetPositionIndex(particle.position, minPosition, maxPosition, marchingCubeResolution, invStep);
            int           numberOfParticleInVoxel = waterParticleCountPerVoxel[index.x, index.y, index.z];
            if (numberOfParticleInVoxel < maxWaterParticlePerZone)
            {
                //Store the index of the particle in the grid
                particleIndicesInCollisionTensor[i] = index;
                waterParticleCollisionTensor[index.x, index.y, index.z, numberOfParticleInVoxel] = (short)i;
                waterParticleCountPerVoxel[index.x, index.y, index.z]++;
            }
        }

        //Narrow phase
        for (int i = 0; i < particleCount; i++)
        {
            //TODO check all 26 adjacent cells

            WaterParticle currentParticle         = waterParticles[i];
            int3          index                   = particleIndicesInCollisionTensor[i];
            int           numberOfParticleInVoxel = waterParticleCountPerVoxel[index.x, index.y, index.z];
            for (int j = 0; j < numberOfParticleInVoxel; j++)
            {
                int otherParticleIndex = waterParticleCollisionTensor[index.x, index.y, index.z, j];

                if (i == otherParticleIndex)
                {
                    break;
                }

                WaterParticle otherParticle = waterParticles[otherParticleIndex];
                float3        diff          = otherParticle.position - currentParticle.position;

                //No collision
                if (math.lengthsq(diff) > particleRadius * particleRadius)
                {
                    continue;
                }

                //TODO custom burstable functions
                //On collision vector keep they rejection, but swap projections
                float3 currentProjection = Vector3.Project(currentParticle.velocity, diff);
                float3 currentRejection  = currentParticle.velocity - currentProjection;

                float3 otherProjection = Vector3.Project(otherParticle.velocity, diff);
                float3 otherRejection  = currentParticle.velocity - otherProjection;

                //Swap
                currentParticle.velocity = (currentRejection + otherProjection) * elasticity;
                otherParticle.velocity   = (otherRejection + currentProjection) * elasticity;

                //currentParticle.position -= diff * particleRadius;
                //otherParticle.position += diff * particleRadius;

                waterParticles[i] = currentParticle;
                waterParticles[otherParticleIndex] = otherParticle;
            }
        }
    }
Ejemplo n.º 25
0
        public override bool PerformFrame(BCBlockGameState gamestate)
        {
            bool rval = base.PerformFrame(gamestate);

                for (int i = 0; i < (int)(50f * BCBlockGameState.ParticleGenerationFactor); i++)
                {
                    const float speedmult = 1;
                    //choose a random Angle...
                    double randomangle = Math.PI * 2 * BCBlockGameState.rgen.NextDouble();
                    //create the appropriate speed vector, based on our radius...
                    double usespeed = (_CurrentRadius / _MaxRadius) * speedmult; //should be proportional to how close we are to the maximum radius; max radius will have particles move 1...
                    usespeed += ((BCBlockGameState.rgen.NextDouble() * 0.5) - 0.25);

                    PointF addpointLocation = new PointF(Location.X + (float)Math.Cos(randomangle) * _CurrentRadius, Location.Y + (float)Math.Sin(randomangle) * _CurrentRadius);

                    //create a dustparticle...
                    Particle addparticle = null;
                    if ((i % 5 == 0) && _ShowOrbs)
                    {
                        addparticle = new LightOrb(addpointLocation, Color.Blue, 5 + (float)(BCBlockGameState.rgen.NextDouble() * 10));
                    }
                    else
                    {
                        addparticle = new WaterParticle(addpointLocation,
                                                                      new PointF((float)(Math.Cos(randomangle) * usespeed),
                                                                                 (float)(Math.Sin(randomangle) * usespeed)));
                    }

                    if (addparticle != null)
                    {
                        addparticle.Velocity = new PointF(addparticle.Velocity.X + Velocity.X, addparticle.Velocity.Y + Velocity.Y);
                        gamestate.Particles.Add(addparticle);
                    }

                }

                //is this the first call?
                if (!flInit)
                {
                    flInit = true;
                    //initialize data structures.
                    //the idea here is that createblocklocations will store the offset from the CreationEffect's location, rather than an absolute position.
                    for (float x = -_MaxRadius; x < (_MaxRadius); x += BlockCreateSize.Width)
                    {
                        for (float y = -_MaxRadius; y < (_MaxRadius); y += BlockCreateSize.Height)
                        {
                            //add a new rectangle to that cache
                            RectangleF createrect = new RectangleF(x, y, BlockCreateSize.Width, BlockCreateSize.Height);
                            //add it to the list.
                            createblocklocations.Add(createrect);

                        }

                    }

                }
                //createblocklocations has the offsets from our position. LINQ-ee-fy it to see if any need to be created.
                var createthese = from q in createblocklocations where BCBlockGameState.Distance(0, 0, q.CenterPoint().X, q.CenterPoint().Y) < _CurrentRadius select q;
                List<RectangleF> removethese = new List<RectangleF>();
                if (createthese.Any())
                {
                    //we need to create some blocks we do.
                    foreach (RectangleF looprect in createthese)
                    {

                        //create the PROPER rectanglef structure by cloning this one and offseting the clone.
                        RectangleF userect = looprect;
                        userect.Offset(Location.X, Location.Y);
                        Block createdblock = DefaultCreationFunction(gamestate, userect);
                        //add this block to the game.
                        gamestate.Blocks.AddLast(createdblock);
                        removethese.Add(looprect);

                    }

                    foreach (var removeit in removethese)
                    {
                        createblocklocations.Remove(removeit);

                    }

                    gamestate.Forcerefresh = true;

                }

                return rval;
        }
Ejemplo n.º 26
0
        protected override void Draw(SpriteBatch sb, Game game, float elapsedSeconds)
        {
            if (Treasure.Instance.TimeDilationFast)
            {
                elapsedSeconds *= 4;
            }

            elapsedSeconds    *= TimeDilation;
            mouseOverTile      = null;
            mouseOverCharacter = null;
            base.Draw(sb, game, elapsedSeconds);
            Primitives.FillRectangle(Root.Screen, Color.Black);
            Rectangle start = ToReal(new Rectangle(0, 0, 1, 1));

            Primitives.DrawRectangle(new Rectangle(start.X - 3, start.Y - 3, Session.MapWidth * TILESIZE + 6, Session.MapHeight * TILESIZE + 6), Color.White, 3);
            for (int x = 0; x < Session.MapWidth; x++)
            {
                for (int y = 0; y < Session.MapHeight; y++)
                {
                    var rectThisTile = new Rectangle(start.X + x * TILESIZE, start.Y + y * TILESIZE, TILESIZE, TILESIZE);
                    if (rectThisTile.Right < 0 || rectThisTile.Bottom < 0 || rectThisTile.X >= Root.ScreenWidth ||
                        rectThisTile.Y >= Root.ScreenHeight)
                    {
                        continue;
                    }
                    Session.Map[x, y].Draw(rectThisTile);
                    if (Root.IsMouseOver(rectThisTile))
                    {
                        mouseOverTile = Session.Map[x, y];
                    }
                }
            }

            foreach (var character in Session.Characters)
            {
                Point     p    = ToReal(character.Position);
                Rectangle rect = new Rectangle(p.X, p.Y, TILESIZE, TILESIZE);

                if (Root.IsMouseOver(rect))
                {
                    if (mouseOverCharacter == null || mouseOverCharacter.IsNPC || mouseOverCharacter.Dead)
                    {
                        mouseOverCharacter = character;
                    }
                }

                if (character.Dead)
                {
                    rect = new Rectangle(rect.X + 8, rect.Y + 8, rect.Width - 16, rect.Height - 16);
                }

                Primitives.DrawImage(Assets.TextureFromCard(character.Illustration), rect, character.Dead ? Color.Red : Color.White);
                if (character.ImmediateActivity != null)
                {
                    Writer.DrawProgressBar(new Rectangle(rect.X, rect.Y - 6, rect.Width, 4), Color.Yellow, character.ImmediateActivity.SecondsProgressed,
                                           character.ImmediateActivity.SecondsToComplete, null);
                }

                if (character == SelectedCharacter)
                {
                    Primitives.DrawRectangle(rect, Color.White);
                }
            }

            if (!Treasure.Instance.CheatMode)
            {
                for (int x = 0; x < Session.MapWidth; x++)
                {
                    for (int y = 0; y < Session.MapHeight; y++)
                    {
                        var rectThisTile = new Rectangle(start.X + x * TILESIZE, start.Y + y * TILESIZE, TILESIZE,
                                                         TILESIZE);
                        if (rectThisTile.Right < 0 || rectThisTile.Bottom < 0 || rectThisTile.X >= Root.ScreenWidth ||
                            rectThisTile.Y >= Root.ScreenHeight)
                        {
                            continue;
                        }

                        Tile tile = Session.Map[x, y];
                        if (tile.Blackened)
                        {
                            Primitives.FillRectangle(rectThisTile, Color.DarkBlue);
                        }
                    }
                }
            }

            for (int x = 0; x < Session.MapWidth; x++)
            {
                for (int y = 0; y < Session.MapHeight; y++)
                {
                    var rectThisTile =
                        new Rectangle(start.X + x * TILESIZE, start.Y + y * TILESIZE, TILESIZE, TILESIZE);
                    if (rectThisTile.Right < 0 || rectThisTile.Bottom < 0 || rectThisTile.X >= Root.ScreenWidth ||
                        rectThisTile.Y >= Root.ScreenHeight)
                    {
                        continue;
                    }
                    Tile tile = Session.Map[x, y];

                    foreach (Overhead overhead in tile.Overheads)
                    {
                        overhead.Draw(rectThisTile);
                    }

                    tile.Overheads.RemoveAll(oh => oh.UpdateAndPossiblyDelete(elapsedSeconds));
                }
            }

            for (int wi = 0; wi < Session.Particles.Count; wi++)
            {
                WaterParticle pp     = Session.Particles[wi];
                Point         asReal = ToReal(pp.Position);
                Primitives.DrawPoint(new Vector2(asReal.X, asReal.Y), Color.Blue, 6);
                pp.Position += pp.Speed * elapsedSeconds;
                pp.TimeLeft -= elapsedSeconds;
                if (pp.TimeLeft <= 0)
                {
                    Session.Particles.RemoveAt(wi);
                    wi--;
                }
            }

            DrawTopBar();
            DrawBottomBar();
            contextMenu?.Draw();
        }