public override bool GivePowerTo(BCBlockGameState gamestate, GameCharacter gamechar) { BCBlockGameState.Soundman.PlaySound("1up"); BasicFadingText bft = new BasicFadingText("1-Up", Location, new PointF(0, -2), new Font(BCBlockGameState.GetMonospaceFont(), 14), new Pen(Color.Black,2), new SolidBrush(Color.Green), 500); gamestate.playerLives++; gamestate.Forcerefresh = true; gamestate.Defer(() => gamestate.GameObjects.AddLast(bft)); return true; }
public override void BehaviourAdded(Paddle toPaddle, BCBlockGameState gamestate) { base.BehaviourAdded(toPaddle, gamestate); gamestate.Defer(()=>{ addedobject = new ProxyObject((po, gs) => { PerformFrame(toPaddle, gamestate); return false; }, null); gamestate.GameObjects.AddLast(addedobject); }); }
public bool PowerUpCallback(BCBlockGameState gamestate) { float randgen = (float)BCBlockGameState.rgen.NextDouble() * Spawnchancesum; int useindex = RandomValueToIndex(randgen, spawnchance); Type grabtype = spawntypes[useindex]; SizeF useSize = new SizeF(16, 16); PointF useposition = new PointF(gamestate.GameArea.Width * (float)BCBlockGameState.rgen.NextDouble(), (gamestate.GameArea.Height - 72) * (float)BCBlockGameState.rgen.NextDouble()); GameEnemy genenemy = (GameEnemy)Activator.CreateInstance(grabtype, useposition, useSize); gamestate.Defer(() => { gamestate.GameObjects.AddLast(genenemy); AddScore(gamestate, 10); }); return true; }
public override bool PerformFrame(BCBlockGameState gamestate) { BCBlockGameState.IncrementLocation(gamestate, ref _Location, Velocity); framecounter++; if (framecounter >= NextDeployment) { framecounter = 0; NextDeployment = BCBlockGameState.rgen.Next(10, 30); ExplosionEffect ee = new ExplosionEffect(Location, 10 + (float)(BCBlockGameState.rgen.NextDouble() * 20)); ee.DamageBlocks = false; //doesn't hurt blocks... ee.ShowOrbs = false; gamestate.Defer(() => { gamestate.GameObjects.AddLast(ee); BCBlockGameState.Soundman.PlaySound("explode"); }); } return !gamestate.GameArea.Contains(new Point((int)Location.X, (int)Location.Y)); }
public override bool PerformFrame(BCBlockGameState gamestate) { bool retval = base.PerformFrame(gamestate); //add some particles around the edges of the explosion, moving outward... if (gamestate.Particles.Count((w)=>!w.Important) < BCBlockGameState.MaxParticles) { for (int i = 0; i < (int)(25f * 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.6) - 0.3); PointF addpointLocation = new PointF(Location.X + (float)Math.Cos(randomangle) * _CurrentRadius, Location.Y + (float)Math.Sin(randomangle) * _CurrentRadius); //create a dustparticle... PointF PointSpeed = new PointF((float)(Math.Cos(randomangle) * usespeed), (float)(Math.Sin(randomangle) * usespeed)); Particle addparticle = null; if (i % 5 != 0) { addparticle = new DustParticle(addpointLocation, PointSpeed); } else if (_ShowOrbs) { //LightOrb... LightOrb lo = new LightOrb(addpointLocation, ExplosionColor, (float)BCBlockGameState.rgen.NextDouble() * 10 + 5); lo.Velocity = PointSpeed; addparticle = lo; } if (addparticle != null) gamestate.Particles.Add(addparticle); } } //each frame, check for blocks that are within the given radius. Hell with it, we'll check their centerpoints... if (gamestate.PlayerPaddle != null) { //if( if (DamagePaddle && BCBlockGameState.RectangleIntersectsCircle(gamestate.PlayerPaddle.Getrect(), Location, _CurrentRadius)) { gamestate.PlayerPaddle.HP -= 1f; } } if (_EffectObjects) { //find all GameObjects that implement IExplodable. //we might be bothered to do the same for Balls, I suppose. No promises. IEnumerable<IExplodable> result = BCBlockGameState.Join<IExplodable>( (from ball in gamestate.Balls where ball is IExplodable && (BCBlockGameState.Distance(Location,ball.Location) < _CurrentRadius) select ball as IExplodable), (from obj in gamestate.GameObjects where obj is IExplodable select obj as IExplodable)); //in order to prevent contention issues, we will defer the loop that "effects" each item until the next gametick iteration starts. gamestate.NextFrameCalls.Enqueue(new BCBlockGameState.NextFrameStartup(() => { foreach (var iterateresult in result) { PointF useVelocityEffect = new PointF(Math.Max(1,Velocity.X),Math.Max(1,Velocity.Y)); iterateresult.ExplosionInteract(this, Location, useVelocityEffect); } })); } List<Block> removethese = new List<Block>(); if (_DamageBlocks) { var blowemup = from p in gamestate.Blocks where BCBlockGameState.Distance(Location.X, Location.Y, p.CenterPoint().X, p.CenterPoint().Y) < _CurrentRadius select p; if (blowemup.Any()) { foreach (var loopblock in blowemup) { //destroy it. if (loopblock is DestructionBlock) { //special handling for combos Debug.Print("DestructionBlock detected in ExplosionEffect..."); (loopblock as DestructionBlock).ComboCount = this.ComboCount + 1; } if (DestroyAll || loopblock.MustDestroy()) { loopblock.StandardSpray(gamestate); removethese.Add(loopblock); } } lock (gamestate.Blocks) { foreach (Block removeit in removethese) { //get angle between the center of the explosion and the block's center. double Angle = BCBlockGameState.GetAngle(CenterPoint(), removeit.CenterPoint()); int useSpeed = BCBlockGameState.ClampValue((int)_MaxRadius / 2, 1, 5); PointF useVelocity = BCBlockGameState.GetVelocity(useSpeed, Angle); cBall tempball = new cBall(new PointF(removeit.CenterPoint().X-useVelocity.X,removeit.CenterPoint().Y-useVelocity.Y), useVelocity); tempball.PreviousVelocity = useVelocity; tempball.Behaviours.Add(new TempBallBehaviour()); //add a proxy behaviour to remove it as well. //tempball.Behaviours.Add(new ProxyBallBehaviour("ExplosionEffect", null, proxyperformframe, null, null, null, null, null, null)); //gamestate.Balls.AddLast(tempball); List<cBall> discardlist = new List<cBall>(); try { //this is... well, cheating... //we cannot add GameObjects to the List, except by plopping them in the ref AddedObject parameter. //however, we cannot "force" the PerformBlockHit of a block (say a destruction block) to add a GameObject (another ExplosionEffect, in that case) //we cheat. we swap out the entire gamestate.GameObject LinkedList with a new one, call the routine, and then //we add any added GameObjects to our ref parameter, and swap the old list back in, hoping nobody notices our //audacity to fiddle with core game state objects... var copiedref = gamestate.GameObjects; gamestate.GameObjects = new LinkedList<GameObject>(); removeit.PerformBlockHit(gamestate, tempball); gamestate.Blocks.Remove(removeit); var tempadded = gamestate.GameObjects; gamestate.GameObjects = copiedref; //now we add the ones we need to add to our ref array. I feel dirty. gamestate.Defer(() => { foreach (var iterate in tempadded) { gamestate.GameObjects.AddLast(iterate); } }); } catch { } //we don't add the ball to our GameState, so we don't have to worry about it persisting :D //the idea is that we want to invoke the actions of the block (which for many blocks will simply be destroyed). //at the same time, some blocks might react weirdly to having temporary balls tossed into their centers, so we make it so the ball will only live for //two frames by adding a proxyballbehaviour that ensure that. //gamestate.Blocks.Remove(removeit); gamestate.Forcerefresh = true; } //changed: instead of removing them, create a temporary ball at their center point. } } } return retval; }
public override bool PerformFrame(BCBlockGameState gamestate) { List<Block> removethem = new List<Block>(); foreach (Block iterateblock in gamestate.Blocks) { if (TouchesBlock(iterateblock) && iterateblock != OriginalBlock) { if (isBlockDestructable(iterateblock)) { gamestate.Forcerefresh = true; if (!ignorelist.Contains(iterateblock)) { var currobjects = gamestate.GameObjects; gamestate.GameObjects = new LinkedList<GameObject>(); BCBlockGameState.Block_Hit(gamestate, iterateblock,Velocity); //AddObjects.AddRange(gamestate.GameObjects); //gamestate.Defer(()=>gamestate.GameObjects.A gamestate.GameObjects = currobjects; removethem.Add(iterateblock); } } else { //the block isn't destructable. We need to be destroyed. gamestate.Defer(() => gamestate.GameObjects.Remove(this)); } } } foreach (Block removeit in removethem) { gamestate.Blocks.Remove(removeit); } base.PerformFrame(gamestate); return !gamestate.GameArea.Contains(ObjectRectangle.Corners()); }
public override bool PerformBlockHit(BCBlockGameState parentstate, cBall ballhit) { if (CurrentMode == PowerupBlockMode.BlockMode_Filled) { if (isEmergePower()) { try { TransitoryBlockObject tbo = new TransitoryBlockObject(this); parentstate.Defer(()=>parentstate.GameObjects.AddLast(tbo)); tbo.TransitionComplete = TransitFunc; CurrentMode = PowerupBlockMode.BlockMode_Transitory; BumpObjects(parentstate); } catch (Exception err) { Debug.Print(err.ToString()); } } else { //call transitfunc directly. TransitFunc(parentstate, null); } } base.PerformBlockHit(parentstate, ballhit); BCBlockGameState.Soundman.PlaySound("bump"); return false; }
public override bool PerformFrame(BCBlockGameState gamestate) { if (Frozen) return false; PointF usedoffset=PointF.Empty; BCBlockGameState.IncrementLocation(gamestate, ref _Location, _Velocity,ref usedoffset); _Poly.Offset(usedoffset); if (!(new Polygon(gamestate.GameArea).Contains(_Poly))) { //reflect var result = GeometryHelper.PolygonCollision(new Polygon(gamestate.GameArea), _Poly, Velocity); var copied = new PointF(-result.MinimumTranslationVector.X, -result.MinimumTranslationVector.Y); if (Math.Abs(result.MinimumTranslationVector.X) > Math.Abs(result.MinimumTranslationVector.Y)) { //mirror X speed. Velocity = new PointF(-Velocity.X, Velocity.Y); } else { Velocity = new PointF(Velocity.X, -Velocity.Y); } } _Velocity = _VelocityDecayFunction(this, _Velocity); CurrAngle += AngleSpeed; _AngleSpeed = _AngleSpeedDecayFunction(this, _AngleSpeed); //check for ball collisions. foreach (cBall checkball in gamestate.Balls) { Polygon ballpoly = checkball.GetBallPoly(); if (_Poly.IntersectsWith(ballpoly) && !InvokeBeforeObstacleHit(gamestate,checkball,this)) { //only if it intersects. Vector Adjustment; GeometryHelper.PolygonCollisionResult pcr = GeometryHelper.PolygonCollision(_Poly, ballpoly, new Vector(checkball.Velocity.X+Velocity.X, checkball.Velocity.Y+Velocity.Y)); Adjustment = pcr.MinimumTranslationVector; checkball.Velocity = checkball.Velocity.Mirror(pcr.MinimumTranslationVector); checkball.Velocity = new PointF(checkball.Velocity.X, checkball.Velocity.Y); checkball.Location = new PointF(checkball.Location.X - Adjustment.X, checkball.Location.Y - Adjustment.Y); BCBlockGameState.Soundman.PlaySound("bounce"); //determine percentage of "knockback" to us based on the ratio between the ball radius and our average radius. float ourAverage = _Poly.AverageRadius(); float ballradii = checkball.Radius; float ratio = ballradii / ourAverage; PointF mCenter = GetRectangle().CenterPoint(); Velocity = new PointF(Velocity.X + pcr.MinimumTranslationVector.X * ratio, Velocity.Y + pcr.MinimumTranslationVector.Y * ratio); //get angle between the ball's previous location (assumed from the velocity) and it's current pos, //with our center point as the pivot. PointF PrevPosition = checkball.PrevLocation; PointF CurrLocation = checkball.Location; var PrevAngle = BCBlockGameState.GetAngle(mCenter, PrevPosition); var CurrentAngle = BCBlockGameState.GetAngle(mCenter, CurrLocation); AngleSpeed = CurrentAngle - PrevAngle; //reduce our size, as well. _Poly = _Poly.Scale(0.9f); if (_Poly.Area() < MinimumSize && !InvokeObstacleHit(gamestate,checkball,this)) { //Fire the OnDestroy event if(!InvokeObstacleDestroy(gamestate,checkball,this)) return true; //tweak: make it explode or something, too. } } } if (_fShoot) { if (delayoffset++ == _ShootDelay) { delayoffset = 0; //shoot lightning. Because lightning is da' shit. //choose a random point on this polygon. PointF selectedpoint = BCBlockGameState.Choose(Poly.Points); //get angle between that point and the paddle. //if there is no paddle, use a random value. double fireangle = gamestate.PlayerPaddle != null ? BCBlockGameState.GetAngle(selectedpoint, gamestate.PlayerPaddle.CenterPoint()) : BCBlockGameState.rgen.NextDouble() * Math.PI * 2; PointF createdvel = BCBlockGameState.VaryVelocity(new PointF((float)Math.Cos(fireangle), (float)Math.Sin(fireangle)), Math.PI / 12); LightningShot ls = new LightningShot(selectedpoint, createdvel) { DamageBlocks = false, DamagePaddle = true }; gamestate.Defer(() => gamestate.GameObjects.AddLast(ls)); } } return !gamestate.GameArea.IntersectsWith(_Poly.GetBounds().ToRectangle()); }
public AttractRepulseDestructor(BCBlockGameState gstate, AttractionRepulsionBlock BlockA, AttractionRepulsionBlock BlockB) { //calculate the appropriate vectors. OriginalBlocks = new AttractionRepulsionBlock[] { BlockA, BlockB }; PointF midpoint = BCBlockGameState.MidPoint(BlockA.CenterPoint(), BlockB.CenterPoint()); double AtoB = BCBlockGameState.GetAngle(BlockA.CenterPoint(), midpoint); double BtoA = BCBlockGameState.GetAngle(BlockB.CenterPoint(), midpoint); double AuseAngle = BtoA; //default to "repel" double BuseAngle = AtoB; //if they are not the same colour... if (!(BlockA.BlockColor.R == BlockB.BlockColor.R && BlockA.BlockColor.G == BlockB.BlockColor.G && BlockA.BlockColor.B == BlockB.BlockColor.B)) BCBlockGameState.Swap(ref AuseAngle, ref BuseAngle); //swap, if the colour RGB triplets are unequal we want to "attract" rather than repel. //their initial speed will be zero. Aggregates = new BoxDestructor[] { new BoxDestructor(BlockA, PointF.Empty), new BoxDestructor(BlockB, PointF.Empty) }; //but we will change their 'velocitydecay' 0.05 for now, in the appropriate direction. Aggregates[0].VelocityDecay = new PointF((float)Math.Cos(AuseAngle) * defaultinitialspeed, (float)(Math.Sin(AuseAngle) * defaultinitialspeed)); Aggregates[1].VelocityDecay = new PointF((float)(Math.Cos(BuseAngle) * defaultinitialspeed), (float)(Math.Sin(BuseAngle) * defaultinitialspeed)); Aggregates[0].VelocityIncrement = Aggregates[0].VelocityDecay; Aggregates[1].VelocityIncrement = Aggregates[1].VelocityDecay; Aggregates[0].VelocityDecay = new PointF(1 + Math.Abs(Aggregates[0].VelocityDecay.X), 1 + Math.Abs(Aggregates[0].VelocityDecay.Y)); Aggregates[1].VelocityDecay = new PointF(1 + Math.Abs(Aggregates[1].VelocityDecay.X), 1 + Math.Abs(Aggregates[1].VelocityDecay.Y)); //now we need to add the BoxDestructor to the gamestate. //we do not remove the Blocks, instead deferring that to the block itself to decide. //it is also the caller's responsibility to add this instance to the GameObjects list as well. gstate.Defer(() => { gstate.GameObjects.AddLast(Aggregates[0]); gstate.GameObjects.AddLast(Aggregates[1]); }); }
protected void AddScore(BCBlockGameState ParentGame, int scoreadd, String prefixString) { //PointF MidPoint = new PointF(mBlockrect.Left + (mBlockrect.Width / 2), mBlockrect.Top + (mBlockrect.Height / 2)); String usestring; PointF MidPoint = new PointF(Location.X + Size.Width / 2, Location.Y + Size.Height / 2); int addedscore = scoreadd + (Math.Sign(scoreadd) * ParentGame.GameObjects.Count * 10); if (String.IsNullOrEmpty(prefixString)) usestring = addedscore.ToString(); else usestring = prefixString + "(" + addedscore.ToString() + ")"; ParentGame.GameScore += addedscore; //ParentGame.GameObjects.AddLast(new BasicFadingText(usestring, MidPoint, new PointF(((float)BCBlockGameState.rgen.NextDouble() * 0.2f) * -0.1f, ((float)BCBlockGameState.rgen.NextDouble()) * -0.7f), new Font(BCBlockGameState.GetMonospaceFont(), 16), null, null)); ParentGame.Defer(() => ParentGame.GameScore += addedscore); ParentGame.GameObjects.AddLast(new BasicFadingText(usestring, MidPoint, new PointF(((float)BCBlockGameState.rgen.NextDouble() * 0.2f) * -0.1f, ((float)BCBlockGameState.rgen.NextDouble()) * -0.7f), new Font(BCBlockGameState.GetMonospaceFont(), 16), null, null)); //ParentGame.EnqueueMessage(usestring); }
public override bool PerformBlockHit(BCBlockGameState parentstate, cBall ballhit) { parentstate.Defer(()=> parentstate.GameObjects.AddLast(new ProxyObject(proxyfunction, null))); return base.PerformBlockHit(parentstate, ballhit); }
public virtual List<Block> PerformFrame(BCBlockGameState ParentGameState,ref List<cBall> ballsadded,ref List<cBall> ballsremove) { PreviousVelocity = Velocity; //returns the blocks that were affected by the frame (changed or moved). //PointF NextPosition = new PointF(Location.X + Velocity.X, Location.Y + Velocity.Y); PointF NextPosition = Location; BCBlockGameState.IncrementLocation(ParentGameState, ref NextPosition, Velocity); //RectangleF NextPositionBorders = new RectangleF(NextPosition.X - Radius, NextPosition.Y - Radius, Radius, Radius); NormalizeSpeed(); if(ballsadded==null) ballsadded = new List<cBall>(); RectangleF rectangleborders = new RectangleF(Location.X-Radius,Location.Y-Radius,Radius*2,Radius*2); PrevLocation=Location; //Location = new PointF(Location.X+Velocity.X,Location.Y+Velocity.Y); Location = NextPosition; TrailData.Enqueue(new TrailItemData(Location,Radius)); while (TrailData.Count > _Trails) TrailData.Dequeue(); BCBlockGameState wholeref = ParentGameState; List<Block> affectedblocks = InvokePerformFrame(this, ParentGameState, ref ballsadded,ref ballsremove); if(affectedblocks==null) affectedblocks = new List<Block>(); if (wholeref != null) { /*if (isTempBall) { for (int i = 0; i < (int)(10 * BCBlockGameState.ParticleGenerationFactor); i++) { ParentGameState.Particles.Add(new FireParticle(this)); } }*/ //check for collision with the walls... Rectangle clientrect = wholeref.GameArea; bool DoEmitSound=false; bool didhit=false; didhit = CheckWallCollision(rectangleborders, clientrect, ref DoEmitSound); //CheckBall.Y + CheckBall.radius >= Paddle.Y And CheckBall.Y - _ //CheckBall.radius < Paddle.Y + Paddle.PHeight Or (((CheckBall.Y - _ //CheckBall.Yspeed + CheckBall.radius) >= Paddle.Y And CheckBall.Y - _ //CheckBall.Yspeed - CheckBall.radius < Paddle.Y + Paddle.PHeight) And _ //Sgn(CheckBall.Yspeed) = 1) if (wholeref.PlayerPaddle != null) { /* if (rectangleborders.IntersectsWith(wholeref.PlayerPaddle.Getrect()) && Math.Sign(Velocity.Y) == 1) // Paddle paddle = wholeref.PlayerPaddle; //if((Location.Y + Radius >= paddle.Position.Y) && (Location.Y - // Radius < paddle.Position.X+paddle.PaddleSize.Width ) || (((Location.Y - Velocity.Y + Radius) >= paddle.Position.Y && // Location.Y - Velocity.Y - Radius < paddle.Position.Y+paddle.PaddleSize.Height) && Math.Sign(Velocity.Y)==1)) // if (Location.Y + Radius >= paddle.Position.Y && (Location.Y - Radius <= (paddle.Position.X + paddle.PaddleSize.Width))) { //the X coordinate checks out here... { wholeref.PlayerPaddle.Impact(wholeref, this); } } * */ wholeref.PlayerPaddle.CheckImpact(wholeref, this, true); } bool HitBottom=false; if (rectangleborders.Bottom > clientrect.Bottom) { didhit = true; HitBottom=true; DoEmitSound=false; } if (didhit) { numImpacts++; switch (invokeHitWall(wholeref, this)) { case HitWallReturnConstants.HitBall_Default: if (HitBottom) { ParentGameState.invokeballhitbottom(this); ParentGameState.Defer(() => ParentGameState.Balls.Remove(this)); } // break; case HitWallReturnConstants.HitBall_Destroy: ParentGameState.invokeballhitbottom(this); ParentGameState.Defer(() => ParentGameState.Balls.Remove(this)); break; case HitWallReturnConstants.HitBall_Preserve: //the ball is preserved... if (HitBottom) { Velocity = new PointF(Velocity.X,-Velocity.Y); Location = new PointF(Location.X,ParentGameState.GameArea.Bottom-Radius); } break; } } // BCBlockGameState.Soundman.PlaySound("bounce", 0.9f); if(DoEmitSound) BCBlockGameState.Soundman.PlaySound(GetWallHitSound(), 0.9f); affectedblocks.AddRange(CheckBlocks(ParentGameState, ref ballsadded, wholeref)); } return affectedblocks; }
public override bool PerformFrame(BCBlockGameState gamestate) { bool returnvalue = base.PerformFrame(gamestate); switch (_ShotState) { case BuilderShotState.BSS_Projectile: List<Block> resulthittest = BCBlockGameState.Block_HitTest(gamestate.Blocks, getfullsize(), false); returnvalue = !returnvalue || resulthittest.Any(); if (returnvalue) { _ShotState = BuilderShotState.BSS_Expand; Velocity = new PointF(0, 0.01f); gamestate.Forcerefresh = true; } return false; case BuilderShotState.BSS_Expand: //if our size is the desired size of the block, create that block and return true. //otherwise, change out size and location to emulate "growing". if (this.ShotSize.Width >= BuildSize.Width && ShotSize.Height >= BuildSize.Height) { //grow phase completed. //create the block in the desired location. RectangleF desiredlocation = new RectangleF(Location.X, Location.Y, BuildSize.Width, BuildSize.Height); Block builtblock = (Block) Activator.CreateInstance(this.BuildBlock, desiredlocation); //add it to the game... gamestate.Blocks.AddLast(builtblock); //make sure to force a refresh, too. gamestate.Forcerefresh = true; gamestate.Defer( () => gamestate.GameObjects.AddLast(new ProxyObject(forcerefresher, null))); //return true to destroy outselves. //todo: maybe add "effects" here, too? return true; } else { //otherwise, we are in the growing phase. //growincrement could be null, if so, initialize it... if (Growincrement == null) { //initialize it to the difference between the final size and the current shot size, divided //by increments. Growincrement = new SizeF((BuildSize.Width - ShotSize.Width)/increments, (BuildSize.Height - ShotSize.Height)/increments); } //change size by growincrement. Location = new PointF(Location.X - Growincrement.Value.Width, Location.Y - Growincrement.Value.Height); ShotSize = new SizeF(ShotSize.Width + Growincrement.Value.Width*2, ShotSize.Height + Growincrement.Value.Height*2); } return false; } return false; }
public override bool getPowerup(BCBlockGameState gstate,Paddle onPaddle, GamePowerUp gpower) { if(onPaddle==null) return false; //don't accept it. //reject it with great prejudice. //move the location temporarily. PointF oldposition = gpower.Location; SizeF oldsize = gpower.Size; gpower.Location = PointF.Empty; //draw to a temporary bitmap. Bitmap drawtothis = new Bitmap(16, 16); Graphics useg = Graphics.FromImage(drawtothis); useg.Clear(Color.Transparent); gpower.Draw(useg); //reset position. gpower.Location = oldposition; gpower.Size = oldsize; //get average. var averagedpixel = Color.FromArgb((int)((from p in drawtothis.getPixels() select p.ToArgb()).Average())); ExplosionEffect ee = new ExplosionEffect(gpower.Location, 72); ee.ExplosionColor = averagedpixel; ee.DamageBlocks = false; ee.DamagePaddle = false; gstate.Defer(() => gstate.GameObjects.AddLast(ee)); //move gpower to above the paddle, and invert the Y speed. gpower.Location = new PointF(gpower.Location.X, onPaddle.BlockRectangle.Top - gpower.getRectangle().Height - 1); gpower.Velocity = new PointF(gpower.Velocity.X, -Math.Abs(gpower.Velocity.Y)*1.1f); return true; }
public override bool PerformFrame(BCBlockGameState gamestate) { DrawAngle += DrawAngleIncrement; BCBlockGameState.IncrementLocation(gamestate, ref _Location, Velocity); if (!gamestate.GameArea.Contains(new Rectangle(new Point((int)Location.X, (int)Location.Y), new Size((int)Size.Width, (int)Size.Height)))) { gamestate.Defer(() => gamestate.GameObjects.Remove(this)); return false; } //check to see if we hit the paddle: if (gamestate.PlayerPaddle != null) //check for null first... { if (gamestate.PlayerPaddle.Getrect().IntersectsWith(this.getRect())) { //DIE paddle! do some damage to the paddle. Let's say- 20. gamestate.PlayerPaddle.HP -= FireballDamage; //return false to delete this fireball. //TODO: add particle effects for the explosion or whatever. for (int i = 0; i < 15; i++) { gamestate.Particles.Add(new FireParticle(Location)); } gamestate.Defer(() => gamestate.GameObjects.Remove(this)); return false; } } return base.PerformFrame(gamestate); }
public override bool PerformFrame(BCBlockGameState gamestate) { spinshotbrush.RotateTransform((float)(Math.PI * 2 * (BCBlockGameState.rgen.NextDouble()))); Debug.Print("Spinshot Ball Location:" + OurBall.Location); foreach (var subobj in SubObjects) { subobj.PerformFrame(gamestate); } if (hasbeendestroyed) { OurBall.BallImpact -= OurBall_BallImpact; foreach (var subobj in SubObjects) { subobj.ReleaseBall(); } SubObjects = new List<SpinShotsubBallInfo>(); gamestate.Defer(() => gamestate.GameObjects.Remove(this)); } return hasbeendestroyed; }
public override void TouchTop(BCBlockGameState gamestate, List<Block> touched, Block mainblock) { Velocity = new PointF(Velocity.X, Math.Abs(Velocity.Y * 0.5f)); Block smackit = touched.First(); BCBlockGameState.Block_Hit(gamestate, smackit, Velocity); //smack it with the player's velocity. gamestate.Forcerefresh = true; gamestate.Defer(() => gamestate.Forcerefresh = true); }
public override bool PerformFrame(BCBlockGameState gamestate) { //What happens here? //not a whole lot, actually. //all we really need to check for is whether the two aggregates are "touching". If they are, create a explosion in that spot and remove them. if (Aggregates[0].ObjectRectangle.IntersectsWith(Aggregates[1].ObjectRectangle)) { float explosionsize = (BCBlockGameState.Distance(PointF.Empty, Aggregates[0].Velocity) + BCBlockGameState.Distance(PointF.Empty, Aggregates[1].Velocity)) / 2; //intersection. //get the midpoint between the two centers... PointF explosionzero = BCBlockGameState.MidPoint(Aggregates[0].ObjectRectangle.CenterPoint(), Aggregates[1].ObjectRectangle.CenterPoint()); BCBlockGameState.Soundman.PlaySound("bomb"); ExplosionEffect explode = new ExplosionEffect(explosionzero, explosionsize); //add it... gamestate.Defer(()=> { gamestate.GameObjects.AddLast(explode); gamestate.GameObjects.Remove(Aggregates[0]); gamestate.GameObjects.Remove(Aggregates[1]); gamestate.GameObjects.Remove(this); }); } return base.PerformFrame(gamestate); }
private void PerformFrame(Paddle toPaddle,BCBlockGameState gstate) { //add a random lightorb. if (offsetcall++ > 10) { offsetcall = 0; Color chosencolor = new HSLColor(BCBlockGameState.rgen.NextDouble() * 240, 240, 128); LightOrb lo = new LightOrb(toPaddle.BlockRectangle.RandomSpot(BCBlockGameState.rgen), chosencolor, 32); lo.Velocity = BCBlockGameState.GetRandomVelocity(0, 3); gstate.Defer(() => gstate.Particles.Add(lo)); } }