/// <summary> /// Fires a projectile at the specific point, which is a world cordinate /// </summary> /// <param name="point">The point at which to fire a projectile</param> public void spawnProjectile(Vector3 point) { //Move the calculation into the x plane for simplicity Vector3 projDir = new Vector3((float)Math.Sqrt(Math.Pow(point.X - boss.location.X, 2) + Math.Pow(point.Z - boss.location.Z, 2)), (point.Y - boss.location.Y), 0.0f); double gravity = GameObject.gravity; //Following is adapted from http://en.wikipedia.org/wiki/Trajectory_of_a_projectile#Angle_required_to_hit_coordinate_.28x.2Cy.29 double velsquared = barrelProp.speed * barrelProp.speed; double sqrtPart = -Math.Sqrt(velsquared * velsquared - gravity * (gravity * projDir.X * projDir.X + 2 * projDir.Y * velsquared)); double theta; if(sqrtPart == sqrtPart) { //false when sqrtPart == NaN theta = Math.Atan((velsquared - sqrtPart) / (gravity * projDir.X)); } else { //Calculate how far in that direction we can get if(projDir.X == 0) { //Avoid divide by zero theta = Math.PI / 2; } else { double phi = Math.Atan(projDir.Y / projDir.X); double cosphi = Math.Cos(phi); double r = (gravity * velsquared * (1 - Math.Sin(phi))) / (gravity * gravity * cosphi * cosphi); r -= 0.01f; //This prevents a floating point roundoff bug projDir.X = (float)(r * cosphi); projDir.Y = (float)(r * Math.Sin(phi)); sqrtPart = -Math.Sqrt(velsquared * velsquared - gravity * (gravity * projDir.X * projDir.X + 2 * projDir.Y * velsquared)); theta = Math.Atan((velsquared - sqrtPart) / (gravity * projDir.X)); } } projDir.X = (float)Math.Cos(theta); projDir.Y = (float)Math.Sin(theta); //Take the x coordinate and restore it to the proper x/z direction double phi2 = Math.Atan((point.X - boss.location.X) / (point.Z - boss.location.Z)); if(point.Z < boss.location.Z) { phi2 += Math.PI; } projDir.Z = (float)(projDir.X * Math.Cos(phi2)); projDir.X = (float)(projDir.X * Math.Sin(phi2)); Vector3 projlocation = new Vector3(boss.location); //break the rendering tie between boss and projectile, or else they flicker projlocation.Z -= 0.001f; Projectile shot = new Projectile(projlocation, projDir, false, barrelProp, ps.player, (int)CombatType.barrel); // spawn the actual projectile if(ps.enable3d) { shot.cycleNumber = 1; } // add projectile to appropriate lists ps.objList.Add(shot); ps.renderList.Add(shot); ps.collisionList.Add(shot); ps.physList.Add(shot); ps.combatList.Add(shot); }
public void update(double time, PlayState playstate, Vector3 playerposn, Enemy me, bool enable3d, List<PhysicsObject> physList) { //update current animation me.cycleNumber = (int)(enable3d ? KidAnim.stand3d : KidAnim.stand2d); //Flip scale if necessary if(!enable3d) { if((me.location.X < playerposn.X && me.scale.X > 0) || (me.location.X > playerposn.X && me.scale.X < 0)) { me.scale = new Vector3(-me.scale.X, me.scale.Y, me.scale.Z); } } else { // 3D if(me.scale.X < 0) { me.scale = new Vector3(-me.scale.X, me.scale.Y, me.scale.Z); } } if (!me.frozen) { if (VectorUtil.dist(playerposn, me.location) <= 90) { if (me.attackdelayed) me.attacktimer = me.attacktimer + time; if (me.attacktimer > me.attackspeed) { me.attackdelayed = false; me.attacktimer = 0; } if (!me.attackdelayed) { Vector3 dir = VectorUtil.getdir(playerposn, me.location); //throw icecream Vector3 projlocation = me.location; Vector3 direction = VectorUtil.getdir(playerposn, me.location); if (!enable3d) { projlocation.Z += 0.001f; //break the rendering tie between enemy and projectile, or else they flicker } else { direction.Z = 0.0f; direction.NormalizeFast(); } Projectile shot = new Projectile(projlocation, direction, false, me.projectile, playstate.player); //Projectile shot = new Projectile(projlocation, direction, new Vector3(12.5f, 12.5f, 12.5f), new Vector3(6.25f, 6.25f, 6.25f), new Vector3(6.25f, 6.25f, 6.25f), true, true, playstate.enable3d, me.damage, 150, false, false, me.projectileSprite); playstate.objList.Add(shot); playstate.renderList.Add(shot); playstate.collisionList.Add(shot); playstate.physList.Add(shot); playstate.combatList.Add(shot); me.attackdelayed = true; } } else me.ChangeState(new Kidmoveto()); } }
public virtual void update(double time, PlayState playstate, Vector3 playerposn, bool enable3d) { if(prefalling) { if((mybox.location.Y - mybox.pbox.Y) <= preHeight) { setPosition(new Vector3(mybox.location.X, preHeight, mybox.location.Z)); velocity = mybox.velocity = myRope.velocity = new Vector3(0, 0, 0); pretimer = pretimer + time; if(pretimer >= pretime) { pretimer = 0; falling = true; prefalling = false; velocity = mybox.velocity = myRope.velocity = new Vector3(0, -200, 0); Projectile shot = new Projectile(new Vector3(mybox.location.X, preHeight - 0.12f, mybox.location.Z), new Vector3(0, -1, 0), false, projectile, playstate.player); // spawn the actual projectile shot.type = (int)CombatType.squish; // add projectile to appropriate lists playstate.objList.Add(shot); playstate.renderList.Add(shot); playstate.collisionList.Add(shot); playstate.physList.Add(shot); playstate.combatList.Add(shot); } } } if(falling) { if(mybox.velocity.Y == 0.0f) { //Wait for physics to stop the crate setPosition(new Vector3(mybox.location.X, minHeight, mybox.location.Z)); velocity = mybox.velocity = myRope.velocity = new Vector3(0, 0, 0); downtimer = downtimer + time; if(downtimer >= downtime) { downtimer = 0; falling = false; rising = true; velocity = mybox.velocity = myRope.velocity = new Vector3(0, 80, 0); shadowtimer = 1.25; } } } if(rising) { if(mybox.location.Y - mybox.pbox.Y >= maxHeight) { setPosition(new Vector3(mybox.location.X, maxHeight, mybox.location.Z)); velocity = mybox.velocity = myRope.velocity = new Vector3(0, 0, 0); rising = false; idle = true; } } //Update shadow if(prefalling || falling) { //Shadow increasing shadowtimer += time; myGround.frame3d = Math.Min((int)(shadowtimer * 22.0), 11); } else if(rising) { //Shadow decreasing shadowtimer -= time; myGround.frame3d = Math.Min((int)(shadowtimer * 22.0), 11); } else { //No shadow myGround.frame3d = 0; } }
/// <summary> /// Spawns the players projectile in the param direction /// </summary> /// <param name="playstate">a pointer to play state, for accessing the obj lists in playstate</param> /// <param name="direction">The direction to fire the projectile in</param> private void spawnProjectile(Vector3 direction) { Vector3 projlocation = new Vector3(location); //break the rendering tie between player and projectile, or else they flicker if(!enable3d) { projlocation.Z += 0.001f; } Projectile shot = new Projectile(projlocation, direction, true, curProjectile, playstate.player); // spawn the actual projectile //shot.accelerate(new Vector3(velocity.X, 0.0f, velocity.Z)); //account for player's current velocity // add projectile to appropriate lists playstate.objList.Add(shot); playstate.renderList.Add(shot); playstate.collisionList.Add(shot); playstate.physList.Add(shot); playstate.combatList.Add(shot); }