private void Verlet(LineParticle p, float dt) { var temp = p.pos; p.pos += p.pos - p.oldPos + (p.acceleration * dt * dt); p.oldPos = temp; }
private void PoleConstraint(LineParticle p1, LineParticle p2, float restLength) { var delta = p2.pos - p1.pos; var deltaLength = delta.magnitude; var diff = (deltaLength - restLength) / deltaLength; p1.pos += delta * diff * lineSetting; p2.pos -= delta * diff * lineSetting; }
private void Start() { lineRenderer = GetComponent <LineRenderer>(); lineParticles = new LineParticle[numberOfJoints]; linePositions = new Vector3[numberOfJoints]; lineRenderer.positionCount = numberOfJoints; for (int i = 0; i < numberOfJoints; i++) { lineParticles[i] = new LineParticle(); } }
public void Render(IStateOwner pOwner, SKCanvas pRenderTarget, LineParticle Source, GameStateSkiaDrawParameters Element) { var PointA = TranslatePosition(pOwner, pRenderTarget, Source.Position, Element); var PointB = TranslatePosition(pOwner, pRenderTarget, Source.EndPoint, Element); var Alphause = TranslateAlpha(Source); using (SKPaint skp = new SKPaint() { Color = new SKColor(Source.Color.R, Source.Color.G, Source.Color.B, Alphause), StrokeWidth = 2 }) { pRenderTarget.DrawLine(PointA, PointB, skp); } }
public override bool PerformFrame(BCBlockGameState gamestate) { //hitscan. We only "take" a single frame to hit something. //first, normalize the Velocity. _Velocity = _Velocity.Normalize(); //now, starting from _Origin, advance position by _Velocity until we hit a block or leave the gamearea. List<Block> blockshit = new List<Block>(); PointF currpos = _Origin; PointF lastpos = _Origin; bool scancomplete = false; int spawnjump = 0; int particlecomparator = Math.Max(gamestate.Particles.Count-500, 2); //particlecomparator is our modulus. This will be modulo'd with spawnjump each iteration while (!scancomplete) { spawnjump++; currpos = new PointF(currpos.X + _Velocity.X, currpos.Y + _Velocity.Y); PointF diff = new PointF(currpos.X-lastpos.X,currpos.Y-lastpos.Y); //spawn some particles here. if (spawnjump>particlecomparator && Tracer) { spawnjump = 0; for (int i = 0; i < 1; i++) { float randomspot = (float)BCBlockGameState.rgen.NextDouble(); PointF randomoffset = new PointF(currpos.X + diff.X * randomspot, currpos.Y + diff.Y * randomspot); if (BCBlockGameState.rgen.NextDouble() > 0.5) { DustParticle dp = new DustParticle(randomoffset, 3, 25, _BulletColor); dp.Important = true; gamestate.Particles.Add(dp); } else { LightOrb dp = new LightOrb(randomoffset, Color.Green, 16); dp.TTL = 25; dp.Important = true; gamestate.Particles.Add(dp); } } } //are we outside gamearea? if (!gamestate.GameArea.Contains(currpos.ToPoint())) scancomplete = true; //have we hit a block? var hitblock = BCBlockGameState.Block_HitTestOne(gamestate.Blocks, currpos); if (hitblock != null && !blockshit.Contains(hitblock)) { blockshit.Add(hitblock); if(_Strength == HitscanStrengthConstants.hitscan_bullet) { //create a bullet at currpos, make it go in our direction. Bullet bb = new Bullet(currpos, _Velocity, false); bb.BulletBrush = new SolidBrush(Color.Transparent); //invisible bullet... gamestate.NextFrameCalls.Enqueue(new BCBlockGameState.NextFrameStartup(() => gamestate.GameObjects.AddLast(bb))); } else if(_Strength==HitscanStrengthConstants.hitscan_hit) { gamestate.NextFrameCalls.Enqueue(new BCBlockGameState.NextFrameStartup(() => BCBlockGameState.Block_Hit(gamestate, hitblock, _Velocity))); } if (!Penetrate) scancomplete = true; } lastpos = currpos; } if (!Tracer) { DustParticle pa = new DustParticle(Origin, 800,9000,Color.Transparent); DustParticle pb = new DustParticle(currpos,800,9000,Color.Transparent); pa.Velocity = PointF.Empty; pb.Velocity = PointF.Empty; LineParticle ls = new LineParticle(pa, pb,new Pen(Color.Yellow,1)); ls.Important = true; ls.TTL = 750; gamestate.Particles.Add(ls); //show the impact point. PointF Impactpoint = currpos; for (int i = 0; i < 14 * BCBlockGameState.Settings.ParticleGenerationFactor; i++) { Particle xp = BCBlockGameState.rgen.NextDouble() > 0.5 ? (Particle) new EmitterParticle(Impactpoint,(gstate,emitter,aint,bint)=> { float ssspeed = (float)BCBlockGameState.rgen.NextDouble() * 5 + 2; PointF ssusespeed = BCBlockGameState.VaryVelocity(new PointF(0,-ssspeed), Math.PI / 10); DustParticle addit = new DustParticle(emitter.Location, 40); addit.Velocity = ssusespeed; return addit; }) : (Particle)new DustParticle(Impactpoint); float speed = (float)BCBlockGameState.rgen.NextDouble() * 5 + 2; PointF usespeed = BCBlockGameState.VaryVelocity(new PointF(0,-speed), Math.PI / 10); xp.Velocity = usespeed; gamestate.Particles.Add(xp); } } return true; //we only exist for one frame. }
private void BobberThread() { int EffectLengthi = 5000; if (BobberThreadEffectFinish == null) { BobberThreadEffectFinish = DateTime.Now; } const int numeffects = 6; while (true) { lock (ImageBackBufferCanvas) { Thread.Sleep(40); Thread.SpinWait(15); while (Form.ActiveForm == null) Thread.Sleep(50); if (!this.Visible) { Thread.Sleep(50); //nothing to do, allow other threads to run. } else { DrawFrame(); } if (performingEffect) { bool doflip = false; TimeSpan EffectLength = DateTime.Now - BobberThreadEffectStart; //currently the only supported "effect" ,draws a bunch of particles across the screen halfway. (Y). imagesdraw.Clear(); if (EffectLength.TotalMilliseconds > EffectLengthi) { performingEffect = false; prevparticlepos = new PointF(0, 0); BobberThreadEffectFinish = DateTime.Now; } else { double currpercent = (double) EffectLength.TotalMilliseconds/(double) EffectLengthi; int Xpos = (int) (((float) (ImageBackBufferbitmap.Width*1.5)*currpercent) - ((float) (ImageBackBufferbitmap.Width*0.2f))); Debug.Print("Effect currpercent=" + currpercent); // PointF addparticlepos = new PointF(Xpos, ImageBackBufferbitmap.Height / 2); int effectnumber = EffectCount%numeffects; if (effectnumber%2 == 0) { Xpos = ImageBackBufferbitmap.Width - Xpos; doflip = true; } PointF addparticlepos = new PointF(Xpos, 163); if (prevparticlepos.X == 0 && prevparticlepos.Y == 0) prevparticlepos = addparticlepos; float usehue = (((float) currpercent*3)%1)*240; Color particlecolor = new HSLColor(usehue, 240, 120); const float maxoutspeed = 1f; const int numparticles = 25; Image[] usepics = null; System.Drawing.Size? usesize; switch (effectnumber) { case 0: case 2: usepics = new Image[] { rdash.BackgroundImage }; if (effectnumber == 2) addparticlepos = new PointF(addparticlepos.X, ((float) Math.Sin(addparticlepos.X/16)*8) + addparticlepos.Y); /*for (int addp = 0; addp < numparticles*2; addp++) { Particle addparticle = new DustParticle(addparticlepos, (float) (rg.NextDouble()*4), 7500, particlecolor); lock (DrawParticles) { DrawParticles.Add(addparticle); } }*/ //create a spectrum... const float numlines = 25; const int totalsize = 100; for (int i = 0; i < numlines; i++) { float useYoffset = (totalsize/2) + (((float) i/numlines)*totalsize); float pct = ((float) i/numlines); float percenthue = (pct*240); PointF offsetamount = new PointF(addparticlepos.X - prevparticlepos.X, addparticlepos.Y - prevparticlepos.Y); //PointF firstpoint = new PointF(addparticlepos.X, useYoffset); //PointF secondpoint = new PointF(firstpoint.X+offsetamount.X,firstpoint.Y+offsetamount.Y); PointF firstpoint = addparticlepos; PointF secondpoint = prevparticlepos; if (firstpoint.X > secondpoint.X) { firstpoint = new PointF(firstpoint.X + 2, firstpoint.Y); secondpoint = new PointF(secondpoint.X - 2, secondpoint.Y); } else { firstpoint = new PointF(firstpoint.X - 2, firstpoint.Y); secondpoint = new PointF(secondpoint.X + 2, secondpoint.Y); } //float phue = (percenthue + (Xpos/2)%240 )%240; float phue = percenthue%240; Color linecoloruse = new HSLColor(phue, 240, 120); float usevel = (pct - 0.5f)*5; DustParticle dust1 = new DustParticle(firstpoint, new PointF(0, usevel)); DustParticle dust2 = new DustParticle(secondpoint, new PointF(0, usevel)); LineParticle lp = new LineParticle(dust1, dust2, linecoloruse); lock (DrawParticles) { DrawParticles.Add(lp); if (Math.Truncate((double) Xpos)%15 == 0) { //add a 5-pointed star... //StarParticle staradd = new StarParticle(addparticlepos, BCBlockGameState.GetRandomVelocity(0,3), 5, 3, 6, Color.Yellow, Color.Black, (float)(rg.NextDouble() * 2)); CharacterDebris staradd = new CharacterDebris(addparticlepos, BCBlockGameState. GetRandomVelocity(0, 3), Color.Yellow, 8, 18); DrawParticles.Add(staradd); } } } /* Particle addParticleA = new DustParticle(addparticlepos, new PointF(0, -2)); Particle addParticleB = new DustParticle(addparticlepos, new PointF(0, 2)); LineParticle lp = new LineParticle(addParticleA, addParticleB, particlecolor); lock (DrawParticles) { DrawParticles.Add(lp); } */ break; case 1: case 3: usepics = new Image[] {rdash.BackgroundImage}; if (effectnumber == 3) addparticlepos = new PointF(addparticlepos.X, ((float) Math.Sin(addparticlepos.X/32)*16) + addparticlepos.Y); for (int addp = 0; addp < numparticles; addp++) { float ppercent = (float) addp/(float) numparticles; float usespeed = (float) (((maxoutspeed*2)*ppercent) - maxoutspeed); PointF speeduse = new PointF((float) (rg.NextDouble() - 0.5d), usespeed); particlecolor = new HSLColor(ppercent*240, 240, 120); //Particle addparticle = new PolyDebris(addparticlepos, rg.NextDouble() * 2, particlecolor, 3, 4, 3, 8); Particle addparticle = new PolyDebris(addparticlepos, speeduse, particlecolor, 3, 4, 3, 8); lock (DrawParticles) { DrawParticles.Add(addparticle); } } break; case 4: usepics = new Image[] { ttoaster.BackgroundImage }; for (int addp = 0; addp < numparticles*2; addp++) { particlecolor = Color.FromArgb(rg.Next(255), rg.Next(255), 0); Particle addparticle = new DustParticle(addparticlepos, (float) (rg.NextDouble()*4), 7500, particlecolor); lock (DrawParticles) { DrawParticles.Add(addparticle); } } break; case 5: /* */ //megaman sprites... //since these are loaded if (!mmimagesloaded) { mmimagesloaded = true; try { mmimages = BCBlockGameState.Imageman.getImageFrames("megaman"); } catch { mmimagesloaded = false; } } if (mmimagesloaded) { if ((DateTime.Now - lastmmFrameChange) > mmFrameDelayTime) { //advance the frame. mmimageframe++; } mmimageframe = mmimageframe%mmimages.Length; //they are... or should be, loaded now. usepics = new Image[] {mmimages[mmimageframe]}; usesize = new Size(usepics[0].Size.Width*3, usepics[0].Size.Height*3); } break; /* case 3: addparticlepos = new PointF(addparticlepos.X, ((float)Math.Sin(addparticlepos.X / 16) * 8) + addparticlepos.Y); for (int addp = 0; addp < numparticles; addp++) { Particle addparticle = new PolyDebris(addparticlepos, rg.NextDouble()*2, particlecolor, 3, 4, 3, 8); lock (DrawParticles) { DrawParticles.Add(addparticle); } } break; */ } drawimagedata dd = new drawimagedata(); //dd.DrawImage = (Image) usepic.Clone(); dd.ImageFrames = usepics; if (doflip) dd.DrawImage.RotateFlip(RotateFlipType.RotateNoneFlipX); dd.Location = addparticlepos; //imagesdraw.Add(new drawimagedata(BCBlockGameState.Imageman.GetLoadedImage("rdash") double ang = BCBlockGameState.GetAngle(prevparticlepos, addparticlepos); Debug.Print("chosen angle=" + ang); dd.Angle = ang; //if (doflip) dd.Angle += (float) Math.PI; imagesdraw.Add(dd); prevparticlepos = addparticlepos; } } else if ((DateTime.Now - BobberThreadEffectFinish.Value).TotalSeconds >= 60) { EffectCount++; EffectCount = EffectCount%numeffects; switch (EffectCount) { case 0: case 1: case 2: case 3: EffectLengthi = 5000; if (BCBlockGameState.Soundman != null) //can be null, if you press shift during startup and take a while on the screen presented... { if (BCBlockGameState.Soundman.HasSound("asboom")) { BCBlockGameState.Soundman.PlaySound("asboom", 3.0f); } } break; case 4: iSoundSourceObject grabsound; if (BCBlockGameState.Soundman != null) { if (((grabsound = BCBlockGameState.Soundman.GetSoundRnd("TTOASTER")) != null)) { grabsound.Play(false, 3.0f); } } break; case 5: if(BCBlockGameState.Soundman!=null) BCBlockGameState.Soundman.PlaySound("ray"); break; } Debug.Print("invoking effect #" + EffectCount); performingEffect = true; BobberThreadEffectStart = DateTime.Now; } } } }
private void BobberThread() { int EffectLengthi = 5000; if (BobberThreadEffectFinish == null) { BobberThreadEffectFinish = DateTime.Now; } const int numeffects = 6; while (true) { lock (ImageBackBufferCanvas) { Thread.Sleep(50); Thread.SpinWait(15); while (Form.ActiveForm == null) { Thread.Sleep(0); } if (!this.Visible) { Thread.Sleep(0); //nothing to do, allow other threads to run. } else { DrawFrame(); } if (performingEffect) { bool doflip = false; TimeSpan EffectLength = DateTime.Now - BobberThreadEffectStart; //currently the only supported "effect" ,draws a bunch of particles across the screen halfway. (Y). imagesdraw.Clear(); if (EffectLength.TotalMilliseconds > EffectLengthi) { performingEffect = false; prevparticlepos = new PointF(0, 0); BobberThreadEffectFinish = DateTime.Now; } else { double currpercent = (double)EffectLength.TotalMilliseconds / (double)EffectLengthi; int Xpos = (int) (((float)(ImageBackBufferbitmap.Width * 1.5) * currpercent) - ((float)(ImageBackBufferbitmap.Width * 0.2f))); Debug.Print("Effect currpercent=" + currpercent); // PointF addparticlepos = new PointF(Xpos, ImageBackBufferbitmap.Height / 2); int effectnumber = EffectCount % numeffects; if (effectnumber % 2 == 0) { Xpos = ImageBackBufferbitmap.Width - Xpos; doflip = true; } PointF addparticlepos = new PointF(Xpos, 163); if (prevparticlepos.X == 0 && prevparticlepos.Y == 0) { prevparticlepos = addparticlepos; } float usehue = (((float)currpercent * 3) % 1) * 240; Color particlecolor = new HSLColor(usehue, 240, 120); const float maxoutspeed = 1f; const int numparticles = 25; Image usepic = null; System.Drawing.Size?usesize; switch (effectnumber) { case 0: case 2: usepic = rdash.BackgroundImage; if (effectnumber == 2) { addparticlepos = new PointF(addparticlepos.X, ((float)Math.Sin(addparticlepos.X / 16) * 8) + addparticlepos.Y); } /*for (int addp = 0; addp < numparticles*2; addp++) * { * Particle addparticle = new DustParticle(addparticlepos, (float) (rg.NextDouble()*4), * 7500, particlecolor); * * * lock (DrawParticles) * { * DrawParticles.Add(addparticle); * } * }*/ //create a spectrum... const float numlines = 25; const int totalsize = 100; for (int i = 0; i < numlines; i++) { float useYoffset = (totalsize / 2) + (((float)i / numlines) * totalsize); float pct = ((float)i / numlines); float percenthue = (pct * 240); PointF offsetamount = new PointF(addparticlepos.X - prevparticlepos.X, addparticlepos.Y - prevparticlepos.Y); //PointF firstpoint = new PointF(addparticlepos.X, useYoffset); //PointF secondpoint = new PointF(firstpoint.X+offsetamount.X,firstpoint.Y+offsetamount.Y); PointF firstpoint = addparticlepos; PointF secondpoint = prevparticlepos; if (firstpoint.X > secondpoint.X) { firstpoint = new PointF(firstpoint.X + 2, firstpoint.Y); secondpoint = new PointF(secondpoint.X - 2, secondpoint.Y); } else { firstpoint = new PointF(firstpoint.X - 2, firstpoint.Y); secondpoint = new PointF(secondpoint.X + 2, secondpoint.Y); } //float phue = (percenthue + (Xpos/2)%240 )%240; float phue = percenthue % 240; Color linecoloruse = new HSLColor(phue, 240, 120); float usevel = (pct - 0.5f) * 5; DustParticle dust1 = new DustParticle(firstpoint, new PointF(0, usevel)); DustParticle dust2 = new DustParticle(secondpoint, new PointF(0, usevel)); LineParticle lp = new LineParticle(dust1, dust2, linecoloruse); lock (DrawParticles) { DrawParticles.Add(lp); if (Math.Truncate((double)Xpos) % 15 == 0) { //add a 5-pointed star... //StarParticle staradd = new StarParticle(addparticlepos, BCBlockGameState.GetRandomVelocity(0,3), 5, 3, 6, Color.Yellow, Color.Black, (float)(rg.NextDouble() * 2)); CharacterDebris staradd = new CharacterDebris(addparticlepos, BCBlockGameState. GetRandomVelocity(0, 3), Color.Yellow, 8, 18); DrawParticles.Add(staradd); } } } /* * Particle addParticleA = new DustParticle(addparticlepos, new PointF(0, -2)); * Particle addParticleB = new DustParticle(addparticlepos, new PointF(0, 2)); * LineParticle lp = new LineParticle(addParticleA, addParticleB, particlecolor); * * lock (DrawParticles) * { * DrawParticles.Add(lp); * } * * */ break; case 1: case 3: usepic = rdash.BackgroundImage; if (effectnumber == 3) { addparticlepos = new PointF(addparticlepos.X, ((float)Math.Sin(addparticlepos.X / 32) * 16) + addparticlepos.Y); } for (int addp = 0; addp < numparticles; addp++) { float ppercent = (float)addp / (float)numparticles; float usespeed = (float)(((maxoutspeed * 2) * ppercent) - maxoutspeed); PointF speeduse = new PointF((float)(rg.NextDouble() - 0.5d), usespeed); particlecolor = new HSLColor(ppercent * 240, 240, 120); //Particle addparticle = new PolyDebris(addparticlepos, rg.NextDouble() * 2, particlecolor, 3, 4, 3, 8); Particle addparticle = new PolyDebris(addparticlepos, speeduse, particlecolor, 3, 4, 3, 8); lock (DrawParticles) { DrawParticles.Add(addparticle); } } break; case 4: usepic = ttoaster.BackgroundImage; for (int addp = 0; addp < numparticles * 2; addp++) { particlecolor = Color.FromArgb(rg.Next(255), rg.Next(255), 0); Particle addparticle = new DustParticle(addparticlepos, (float)(rg.NextDouble() * 4), 7500, particlecolor); lock (DrawParticles) { DrawParticles.Add(addparticle); } } break; case 5: /* * */ //megaman sprites... //since these are loaded if (!mmimagesloaded) { mmimagesloaded = true; try { mmimages = BCBlockGameState.Imageman.getImageFrames("megaman"); } catch { mmimagesloaded = false; } } if (mmimagesloaded) { if ((DateTime.Now - lastmmFrameChange) > mmFrameDelayTime) { //advance the frame. mmimageframe++; } mmimageframe = mmimageframe % mmimages.Length; //they are... or should be, loaded now. usepic = mmimages[mmimageframe]; usesize = new Size(usepic.Size.Width * 3, usepic.Size.Height * 3); } break; /* * case 3: * * addparticlepos = new PointF(addparticlepos.X, ((float)Math.Sin(addparticlepos.X / 16) * 8) + addparticlepos.Y); * for (int addp = 0; addp < numparticles; addp++) * { * Particle addparticle = new PolyDebris(addparticlepos, rg.NextDouble()*2, particlecolor, 3, 4, 3, 8); * * * lock (DrawParticles) * { * DrawParticles.Add(addparticle); * } * } * break; */ } drawimagedata dd = new drawimagedata(); dd.DrawImage = (Image)usepic.Clone(); if (doflip) { dd.DrawImage.RotateFlip(RotateFlipType.RotateNoneFlipX); } dd.Location = addparticlepos; //imagesdraw.Add(new drawimagedata(BCBlockGameState.Imageman.GetLoadedImage("rdash") double ang = BCBlockGameState.GetAngle(prevparticlepos, addparticlepos); Debug.Print("chosen angle=" + ang); dd.Angle = ang; if (doflip) { dd.Angle += (float)Math.PI; } imagesdraw.Add(dd); prevparticlepos = addparticlepos; } } else if ((DateTime.Now - BobberThreadEffectFinish.Value).TotalSeconds >= 60) { EffectCount++; EffectCount = EffectCount % numeffects; switch (EffectCount) { case 0: case 1: case 2: case 3: EffectLengthi = 5000; if (BCBlockGameState.Soundman != null) //can be null, if you press shift during startup and take a while on the screen presented... { if (BCBlockGameState.Soundman.HasSound("asboom")) { BCBlockGameState.Soundman.PlaySound("asboom", 3.0f); } } break; case 4: iSoundSourceObject grabsound; if (BCBlockGameState.Soundman != null) { if (((grabsound = BCBlockGameState.Soundman.GetSoundRnd("TTOASTER")) != null)) { grabsound.Play(false, 3.0f); } } break; case 5: if (BCBlockGameState.Soundman != null) { BCBlockGameState.Soundman.PlaySound("ray"); } break; } Debug.Print("invoking effect #" + EffectCount); performingEffect = true; BobberThreadEffectStart = DateTime.Now; } } } }