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; } } } }