VG:Miscellaneous (VG2)

From MyProjectFun
Jump to: navigation, search

This page is composed of threads of a previous iteration of the ProjectFUN forums. It is stored here in the hopes that many of our students will find answers to questions they may have during their course(s).

Contents

Tower Defense Paths

I have been working on a tower defense game using the C# level2Engine and I have been having trouble getting the enemies to follow the path. I have a waypoint at each corner and I want the enemies to after colliding with the first waypoint head to the second.

Randomly Spawning Enemies

Student1: The code below is intended to make randomly spawned crates never collide with randomly spawned boxes, but it just doesn't work. There aren't any errors or anything, and Jarrod said that this should work, but we tested it and the boxes still spawn on top of the crates, which is kind of a big deal. This is part of a a larger function that handles the spawning and placement of the crates.

The DisplayLists are different and collision is enabled.

Sprite BoxCopy = CrateCopy.CollisionWithSprite("BoxCopy" );
while (Box != null)
{
  CrateCopy.Position = new Point2D(
    This.Game.RandFloat() * This.Game.WorldSize.Width,
    350 + This.Game.RandFloat() * (This.Game.WorldSize.Height - 350));
}

Instructor: Bad news: Can't be done. We had a student try this last summer, and we made valiant attempts trying to fix it. Sadly, there was no way that worked. Sorry. :-(

Student1: Are you absolutely sure? If this doesn't work, then there is a large potential to have things like enemy and powerup spawning not working at all, which would pretty much break the game.

Instructor: I tried for a week last summer and wasn't able to do it. Assume you can't, but I'll let you know if there is a way.

Student2: I don't know much about coding things solely in a C++ compiler but I have an idea that might work.

Why not try and coordinate the spawning of the two objects that you don't want in the same place?

If one spawns before the other than X amount of area around that object becomes a No Spawn Zone for the other sprite.

My best guess is you'd have to use an algorithm of some kind with a lot of trig equations in it to pull off this idea but it should work.

It should have two sets of equations working together at least. One for the amount of space left after the first sprite spawns and the other for the amount of space it takes up. There are a few others you'd need but this should help.

Migrating from FunEditor to IDE

Student: I'm one of the ones that uses only the FunEditor and I've been getting bored since it is too easy and I've been looking for a use for my compiler that is just sitting there at the moment. That and I've been wanting to try and convert one or more of my games I've made so far to a compiler made version.

The questions I want to ask are these:

What code do you all use for making your project tree?

What do you do about the other "needed" code the FunEditor auto generates?

What other things or files do you need to either make or link to your games?

Also does anyone have a spare blank set of what they are using?

I think that is it for my list of questions to the LV 2 student(s) and teacher(s) at the moment. Thanks for the help. :-D

Tracing "Parent" Sprites of Enemy Bullets

Student: I'm making a game where your character has this "laser beam" in front of him.

This "laser" doesn't do any direct damage, but will "reverse" enemy bullets and make those bullets home in on the same enemy that shot it (if that enemy is dead, it goes for the nearest one).

I need to know how to get the enemy bullet to "find" the original enemy. Any ideas?

Getting an Enemy to Follow the Closest Target

Student1: Can you make it so the enemy will go tword who is closest to it? Instructor: Get each player. Find the vector from the enemy to each player. Get the length of each vector (that gives you the distance to each player). If the first player is closer than the second, follow the first player. Otherwise, follow the second player.

Hint: Make each sentence a comment, and you have the algorithm.

Switching to a Newer Visual Studio Version

Student: Hey everyone I converted my shooter to 2010 C# version and I only have 1 problem in the program.cs were you change the viewport size it says "is not a valid Win32 application. (Exception from HRESULT: 0x800700C1)"

several other students noted the problem

Instructor: The problem is that Visual Studio 2010 uses a newer version of the .NET Framework by default than what our engine supports. You can change this by going to Project->Level2Engine Properties. Once there, change the Target Framework from .NET Framework 4 to .NET Framework 2.0. Once you have that, you're good to go with Visual Studio 2010!

Switching Levels

// Go to the second level
This.Game.SetCurrentLevel( "SecondLevel" );

Shooting Bullets Backward

Student: How could I modify the PlayerFire code to make the bullets shoot directly behind the sprite? thank you!

Instructor: BulletFireFN from Space Shooter has a speed variable. If that's negative, the bullet goes backwards. :-)

Student: Thanks, and another thing...

Like that one zombie game you showed us, how can I use text to give some of my weapons limited ammo and cooldowns that are depleted by the second?

Instructor: This is his code - I'll leave it to you to extract what you need from it:

// Laser Variables
static int laserCooldown = 1000;
static int shootTime = 250;
static int laserTimer = 250;
static int laserState = 0;
 
public static void PlayerLaserFN()
{
  // Fire State
  if (laserState == 0)
  {
    This.Game.FindTextObject("TillLaser" ).Color = Color.Green;
 
    if (This.Game.IsMousePressed(1)) 
    {
      // Fire laser
 
      Sprite RainbowLaser = This.Game.FindSprite("RainbowLaser" );
      if (RainbowLaser != null)
      {
        // Copy the bullet master
        Sprite RainbowLaserCopy = new Sprite(RainbowLaser);
 
        // Rename the bullet copy
        RainbowLaserCopy.Name = "RainbowLaserCopy";
 
        // Place the bullet
        float Bx = This.Sprite.Position.X +
        (This.Sprite.GetWidth() - RainbowLaserCopy.GetWidth()) / 2.0f;
        float By = This.Sprite.Position.Y +
        (This.Sprite.GetHeight() - RainbowLaserCopy.GetHeight()) / 2.0f;
        RainbowLaserCopy.Position = new Point2D(Bx, By);
 
        //Find the target
        Sprite Target = This.Game.FindSprite("Target" );
 
 
        // Calculate our vector
        float Dx = Target.Position.X +
        (Target.GetWidth() - RainbowLaserCopy.GetWidth()) / 2.0f;
        float Dy = Target.Position.Y +
        (Target.GetHeight() - RainbowLaserCopy.GetHeight()) / 2.0f;
        Point2D V = new Point2D(Dx - Bx, Dy - By);
        V = V / V.length();
 
        // Send the bullet on its way
        int speed = 10;
        RainbowLaserCopy.Velocity = V * speed;
 
        // Make the bullet unused
        RainbowLaserCopy.Unused = false;
      }
      // Sound of zombie ownage
      if (This.Game.IsMouseTriggered(1))
      {
        This.Game.PlaySoundEffect("Players Laser.wav" );
      }
 
 
      // Decrement timer
      laserTimer -= 1;
 
      // Check Timer
      if (laserTimer <= 0)
      {
        // Set state to 1
        laserState = 1;
 
        // Set Timer to laserCooldown
        laserTimer = laserCooldown;
 
      }
    }
  }
 
  // Cooldown State
  else if (laserState == 1)
  {
    This.Game.FindTextObject("TillLaser" ).Color = Color.Red;
 
    // Decrement timer
    laserTimer -= 1;
 
    // Check timer
    if (laserTimer <= 0)
    {
      // Set state to 0
      laserState = 0;
 
      // Set timer to shootTime
      laserTimer = shootTime;
    }
  }
}

Toggling Functions

Student: How I can you turn one function off and one on when C is pressed?

Instructor: We've talked about adding behaviors a lot with code that looks like

// Attach 8-way movement to the player
Player.Behavior += Behaviors.PlayerMoveEightWayFN;

However, we can also remove behaviors!

// Remove 8-way movement from the playerPlayer.Behavior -= Behavoirs.PlayerMoveEightWayFN;So, to toggle functions, you need a bool to keep track of which way the toggle is turned. Then you can add/remove behavior based on the bool.
// Bool to toggle player movement
public static bool PlayerMovesEightWay = true;
 
/// <summary>
/// Toggles the player movement controls
/// </summary>
public static void TogglePlayerMovementFN()
{
  // If the player presses C
  if (This.Game.IsTriggered(InputKey.C))
  {
    // Toggle the flag
    PlayerMovesEightWay = !PlayerMovesEightWay;
 
    // If our flag is true
    if (PlayerMovesEightWay)
    {
      // Add 8-way and remove angular movement
      This.Sprite.Behavior += Behaviors.PlayerMoveEightWayFN;
      This.Sprite.Behavior -= Behaviors.PlayerMoveRotationFN;
    }
    // Otherwise
    else
    {
      // Remove 8-way and add angular movement
      This.Sprite.Behavior -= Behaviors.PlayerMoveEightWayFN;
      This.Sprite.Behavior += Behaviors.PlayerMoveRotationFN;
    }
  }
}

Firing Bullets from Wing Mounted Cannons

Student: This ones a tough one it may require a lot of math. In my game there is a spaceship with two wing mounted guns, my ship can rotate and shoot and so far the bullets only come from the cockpit, how could I make the bullets come from the wing mounted guns and move their origins as the ship moves.

Instructor: 1. Rewrite GetHotSpot function in Sprite.cs - Replace the code in that function with the following:

public Point2D GetHotSpot(int index)
{
  // Don't do anything if we don't have to
  if (_angle == 0 && _scale.X == 1 && _scale.Y == 1)
    return Frame.HotSpots[index];
 
  // Get the hotspot
  PointF hotspot = Frame.HotSpots[index];
 
  // Find our angle in radians
  float angle = _angle * (float)Math.PI / 180.0f;
 
  // Calculate the x and y
  float x = _scale.X *
    ((float)Math.Cos(angle) * hotspot.X - (float)Math.Sin(angle) * hotspot.Y);
  float y = _scale.Y *
    ((float)Math.Sin(angle) * hotspot.X + (float)Math.Cos(angle) * hotspot.Y);
  // Return our point
  return new Point2D(x, y);
}

2. Add hot spots to your animation. Sadly, this feature doesn't work in the animation editor, so we have to add them manually. You should be able to open your .anim files in notepad or Notepad++ (you can open a .anim at DigiPen by right-clicking on the file and selecting Edit with Notepad++).

Once we have that open, it should look something like this:

BryceWalk1.png
3
.
.
;

Let me explain that file:

BryceWalk1.png <-- Filename of our image
3 <-- Delay for this frame in frames
. <-- Dot marks end of frame delay section
. <-- Dot marks end of hot spots section
; <-- Semicolon marks end of file

So, we need to add hot spots. Let's add two hot spots at x-y coordinates (0, 48 ) and (0, -48 ). (Note these points are offsets from the center of the frame.)

BryceWalk1.png
3
.
0,48
0,-48
.
;

There, we now have hot spots on that frame! If you have multiple frames, you'll have to do that for each frame :\

3. Use the hot spots. To do this, let's go to our bullet firing code. Where we place the bullet, we want to add in the hot spot to what we already have. Basically, it's like this:

// Place the copy on the player
float x = This.Sprite.Position.X +
  (This.Sprite.GetWidth() - BulletCopy.GetWidth()) / 2.0f
  + This.Sprite.GetHotSpot(0).X;
 
float y = This.Sprite.Position.Y +
  (This.Sprite.GetHeight() - BulletCopy.GetHeight()) / 2.0f
  + This.Sprite.GetHotSpot(0).Y;
 
BulletCopy.Position = new Point2D(x, y);

The GetHotSpot function takes the index of the hot spot we want, so we give it 0 to get our first hot spot (0,48) - remember that we programmers start counting at 0! If we instead wanted our second hot spot at (0,-48), we'd use This.Sprite.GetHotSpot(1);

That's the end of it! Hopefully that all makes sense. I've attached a screenshot of my results (firing two bullets, one at each hot spot).

firing two bullets, one at each hot spot

Loot Drops

Student: how can I make it so after I defeat an enemy the enemy drops money and how can I make it so after I collect certain amount of money change level?

Instructor: For dropping loot, see [Feature] Spawning a Sprite upon another Sprite's Deletion

For changing the level upon obtaining some amount of money, you'd just need to check how much money the player has. If that is greater than or equal to the amount to cause a level change, then change the level.

Move to Mouse Click

Student: Can you make it so a character moves to were the mouse is at on screen like a bullet… just not as fast?

sort of a runescape style of movement…

I plan to make my game co-op... on person controls the person on ground with key board while the other can control the dragon in the air with the mouse… do you foresee any issues I might have?

Instructor: It would work almost exactly like the bullet fire stuff - instead of making a BulletCopy and sending that toward the cursor, you just send the dragon toward the cursor. Just make your speed variable a lower number (like 3) and you should be good to go.

Source File Ordering

Student: Just for convenience, is there any way to make it so that the files in solution explorer aren't shown in alphabetical order? I want to switch some of my levels' placements on solution explorer. It would actually be easier for me to locate some of the levels/menus if they weren't in alphabetical order. Thanks

Instructor: Not that I know of. Instead, try renaming your levels so they'll show up in the order you want:

SplashLevel.cs -> 0_SplashLevel.cs
MenuLevel.cs -> 1_MenuLevel.cs
SpaceLevel.cs -> 2_SpaceLevel.cs

Placement Out of Range

Student: I want a way to keep a radius around my player character so that blocks I try to place out side of the certain radius will not work

I currently have a code that says

if (This.Game.FindSprite( "Player" ).Position.X - This.Game.FindSprite( "Hand" ).Position.X < 1 &&
This.Game.FindSprite( "Player" ).Position.Y - This.Game.FindSprite( "Hand" ).Position.Y < 1)

and all it does is not allow me to place blocks to the left or above the player

Instructor: What you're actually looking for looks more like this:

// Get the vector from player to hand
Point2D direction = This.Game.FindSprite("Hand" ).Position - This.Game.FindSprite("Player" ).Position;
 
// If within range
if (direction.length() < 64)
{
  // Action allowed (code goes here)
}

Map Collision

Student: Is it possible to place map collision in Visual Studio?

Instructor: No. We only have sprite collision - and that does not stop sprites from moving. For that, see the topic [Feature] Solid Collision

Sword Questions

Student: I need my sword to only appear on use and do damage on use

Instructor: Spawning a sword works like shooting a bullet. Instead of velocity, it just needs to have it's position set to in front of the player. Then, just have enemies check for collision with the sword instead of a bullet.

Student: Is there a way to have a sword disappear after the animation goes through once? without deleting the master sprite?

Instructor:

// If this animation is over
if ( This.Sprite.EndOfAnimation( This.Sprite.Animation ) )
{
  // Delete me
  This.Sprite.Delete();
}

Student: Now that I have the spawning of the sword down I need to get it to HFlip like the character but we never did that in class for the bullet.... unsure what to do and were to put the code....

Sorry that I need so much help...

Instructor: When you make a sword, set it's HFlip to the player's:

Sword.HFlip = This.Sprite.HFlip;

Ammo

Student1: Is it possible to make a ammo text object work so that when it hits 0, the character stops firing?

Instructor: I recommend making Ammo a public static int. Then you can do something like this:

// If we press fire and have ammo
if ( This.Game.IsTriggered( InputKey.Space ) && Ammo > 0 )
{
  // Fire
}

Student1: Where would I make a public static int/global data?

Student2: Make the public static int ammo; in your behaviors so that it can be accessed by all the levels :-D

Mount Objects

Student: I am trying to mount a turret onto a tank, and I am wondering how to move the turret to the tank's position.

Instructor: Attach a function to the turret that places it on the tank. It would go like this:

// Find the tank
// If we have the tank
// Set this sprite's position to the tank's position

Firing Angle

Student: Another question of mine is how to make a fired bullet angle in the direction it was fired.

Instructor: We need to calculate the angle we're sending our bullet - which we need to use the dot product. We'll calculate the angle in almost the exact same way as we did in Smash for the PlayerAnimateFN function. Once we have that angle, we need to convert it from radians to degrees, and the we can set the bullet's angle.

This is directly from Smash - here's where we calculate the angle, but we don't need PI8 or anything involving the player animation:

// Get some handy variables for Pi and Pi/8
float PI = (float)Math.PI;
float PI8 = PI / 8.0f;
 
// Start with no player HFlip
bool PlayerHFlip = false;
 
// Get our current animation and keep track of the new one
int CurrentAnimation = This.Sprite.Animation;
int NewAnimation = This.Sprite.Animation;
 
// Get the target sprite
Sprite Target = This.Game.FindSprite("Target" );
 
// If we can't find the target
if (Target == null)
{
  // Abort!
  return;
}
 
// Calculate our direction vector
Point2D direction = Target.Position - This.Sprite.Position;
 
// Normalize our direction vector
direction = direction / direction.length();
 
// Calculate the dot product between direction and up
float dotUp = -direction.Y;
 
// Calculate the angle between direction and right
float angleRight = (float)Math.Acos(direction.X);
 
// Set up our final angle
float angleFinal = 0;
 
// If we have a counter-clockwise rotation
if (dotUp > 0)
{
  // Use our angle between direction and right
  angleFinal = angleRight;
}
// Otherwise
else
{
  // Perform a clockwise rotation
  angleFinal = 2.0f * PI - angleRight;
}

After all that, we have the angle we want in radians. So, to get our angle in degrees, we want to multiply our angle by PI/180.0f. Finally, we can set the bullet's angle to our final angle.

Mass Producing Platforms

Student1: If we want many platforms on one level, do we have to make individual sprites? Or can we just create more via mass production of some sort and place them in separate areas?

Student2:

/// <summary>
/// Spawns a platform at the selected point.
/// </summary>
/// <param name="Position">The location where you want to place the block</param>
public static void SpawnBlockFN(Point2D Position)
{
  Sprite block = new Sprite(This.Game.FindSprite("MBlock" ));
  block.Unused = false;
  block.Name = "Platform";
  block.DisplayList = 1;
  block.Position = Position;
}

MBlock is my master block. If you place this code in the behaviors class, then you can create blocks where you want by doing Behaviors.SpawnBlockFN(new Point2D(x,y));

Instructor: You have to make them individually - however, there is a lovely tool called a for loop that you can use. Let me explain that, and, if you understand, you can use them to make many platforms with minimal effort.

Here's a for loop.

int x = 0; // variable to add to
for ( int i = 0 ; i < 10 ; ++i )
{
  x += i;
}

Basically, the for loop has a few different pieces:

for <-- this is a keyword to start a for loop
int i = 0 <-- this makes a variable i that starts at 0
i < 10 <-- at the beginning of each loop, we check to so if this is true. If so, we run the code in the for loop
++i <-- this happens at the end of the loop. This increments (adds 1 to) i
x += i; <-- code within the for loop

So, i starts at 0 and counts up to 9 - when it hits 10, we're done with the for loop and move along. My example for loop runs 10 times, adding to x each time.

So, x = 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45.

Now how does that help when we spawn platforms? i is an index variable, so when we make our platforms, we can multiply i by the width of the platform to get the current platform's x position. Here's a bit of an example with a screen shot of the result:

for (int i = 0; i < 10; ++i)
{
  Sprite Wall = new Sprite("Wall", "WallActor", new Point2D(i * 64, 400));
}

Student1: What if you want to place the platforms in different areas on the air? I now have a ground for my level, but do I have to create more sprites in order to place platforms more randomly throughout the level?

Instructor: Figure out where you want to place them and place them manually.

Upgrades

Student: my score function is here:

public static void PlayerUpgradeFN()
{
  Sprite Player = This.Game.FindSprite("Player" );
  if (Player.GetLocalData<PlayerData>().Score >= Player.GetLocalData<PlayerData>().LevelUp)
  {
    Sprite Upgrade = This.Game.FindSprite("Upgrade" );
    Upgrade.Unused = false;
 
    if (This.Game.IsTriggered(InputKey.U))
    {
      Player.GetLocalData<PlayerData>().RegenTimer = 120;
      Player.GetLocalData<PlayerData>().RegenMax = 120;
      Player.GetLocalData<PlayerData>().Score -= 1000;
      Player.GetLocalData<PlayerData>().LevelUp = 1500;
      Upgrade.Unused = true;
    }
    else if (Player.GetLocalData<PlayerData>().Score >= Player.GetLocalData<PlayerData>().LevelUp && Player.GetLocalData<PlayerData>().LevelUp >= 1500)
    {
      Upgrade.Unused = false;
      if (This.Game.IsTriggered(InputKey.U))
      {
        Player.GetLocalData<PlayerData>().Score -= 1500;
        Player.GetLocalData<PlayerData>().LevelUp = 2000;
        Upgrade.Unused = true;
      }
      else if (Player.GetLocalData<PlayerData>().Score >= Player.GetLocalData<PlayerData>().LevelUp && Player.GetLocalData<PlayerData>().LevelUp >= 2000)
      {
        Upgrade.Unused = false;
        if (This.Game.IsTriggered(InputKey.U))
        {
          RegenTimer = 60;
          RegenMax = 60;
          Score -= 2000;
          Player.GetLocalData<PlayerData>().LevelUp = 2500;
          Upgrade.Unused = true;
        }
      }
    }
  }
}

for some reason, on the second levelup, is just doesn't do anything, and whenI get 1500 points again, it loops and does nothing again

Instructor: Basically, you're logic just isn't quite right on this - a good attempt though! Here's a fixed up version of what you wrote (also, please write more comments!):

public static void PlayerUpgradeFN()
{
  Sprite Player = This.Game.FindSprite("Player" );
  if (Player.GetLocalData<PlayerData>().Score >= Player.GetLocalData<PlayerData>().LevelUp)
  {
    Sprite Upgrade = This.Game.FindSprite("Upgrade" );
    Upgrade.Unused = false;
 
    if (This.Game.IsTriggered(InputKey.U))
    {
      // If we're upgrading, set the upgrade to unused
      Upgrade.Unused = true;
 
      // First level up
      if (Player.GetLocalData<PlayerData>().LevelUp < 1500)
      {
        Player.GetLocalData<PlayerData>().RegenTimer = 120;
        Player.GetLocalData<PlayerData>().RegenMax = 120;
        Player.GetLocalData<PlayerData>().Score -= 1000;
        Player.GetLocalData<PlayerData>().LevelUp = 1500;
      }
      // Second level up
      else if (Player.GetLocalData<PlayerData>().LevelUp < 2000)
      {
        Player.GetLocalData<PlayerData>().RegenTimer = 60;
        Player.GetLocalData<PlayerData>().RegenMax = 60;
        Player.GetLocalData<PlayerData>().Score -= 1500;
        Player.GetLocalData<PlayerData>().LevelUp = 2000;
      }
      // More levels...
 
    }
  }
}

Menu Level

Student: hey, I know this sounds dumb, but I want to make a menu where it shows a background, and you press space to play, but how do you make them switch?

Instructor: Make a level with the initial behavior that sets the background. For the main behavior, you'll want something like this

// If I press space
{
  // Set the current level to my first level
}

Animation when Enemy Dies

Student: I was wondering if it is possible to to do an animation set when the enemy dies because I have animation frames so when the person hits the player, he dies with that animation. So instead of 1 frame like in smash, we did a star. So, just want multiple frames?

If possible?

Instructor: Very possible - just do what we did in Space Shooter for the EnemyExplode function. We had an entire explode animation, but it was only two frames. If you have a cool animation you want to use, it'll work exactly the same.

Storing High Scores

Student: I want a high score to not be lost when the program exits. Is there any way to preserve the variable?

Instructor: Not really - it requires file I/O, which is beyond the scope our our workshop. If I ever get it working in a way I'm comfortable explaining, then I'll let you know.

Sound Effects

Student: I'm trying to make a sound effect play when the targets get hit in my game. How would I assign it to the target so that it plays? I got the background music to play, but this one is different from that.

Instructor: This is very similar to what we did in Smash. Let me show you the function that destroyed snakes when they were hit by bullets.

/// <summary>
/// Handles enemy collision with a bullet
/// </summary>
public static void CollisionWithBulletFN()
{
  // Get the bullet that hit us
  Sprite Bullet = This.Sprite.CollisionWithSprite("BulletCopy" );
 
  // If we have that bullet
  if (Bullet != null)
  {
    // We should probably do something cool
    ParticleSystemCopyFN("Explode", This.Sprite.Position, 50);
    // Play a sound effect!
    This.Game.PlaySoundEffect("Explosion4.wav" );
 
    // We should probably add to the player's score
    This.Game.FindSprite("Player" ).GetLocalData<PlayerData>().Score += 25;
 
    // And finally, delete me
    This.Sprite.Delete();
  }
}

Basically, you'll want to do that sort of thing, but make sure you use the names of your bullets, sound effect, and player.

Double Jump

Student: How do you double jump in the platforming state machine?

Instructor: You have to make a few changes to the InAir state in PlatformStates.cs.

1. Add variables for number of jumps and maximum jumps: This should be done up at the top of the class where we declare our gravity variable. Mine looks like this now.

// Variables
const float gravity = 0.98f / 2.0f;
float numJumps = 0;
const float maxJumps = 2;

This allows for a total of two jumps - one on the ground, one in the air.

2. Initialize the numJumps variable in the OnEnter function: As is, the OnEnter function is empty in the standard platforming engine. We want to do something more like this.

public override void OnEnter(WorldObject Owner)
{
  // Set the number of jumps used so far
  numJumps = 1;
}

3. Add jumping in the air: We need to add a chunk of code to the Update function now. This needs to happen after applying gravity and before the air control for x-axis.

Here's what you want to add.

// Extra Jumps
float jumpStrength = 10.0f; // This should not be more than terminal velocity
// If the player hits up and we still have jumps
if (This.Game.IsTriggered(InputKey.Up) && numJumps < maxJumps)
{
  // Jump!
  This.Sprite.Velocity.Y = -jumpStrength;
  // Increment how many times we've jumped
  ++numJumps;
}

4. Maintaining this code: If you want to add more jumps, all you have to do is update the maxJumps variable (setting it to 4 gives you 4 jumps total). You'll want to make sure your jumpStrength matches the jumpStrength in the OnPlatform state. Also, jumpStrength should not be more than 20 - that would allow you to pass through collision. That's really about it!

Getting Score to Stay the Same

Student: Hi, I have 3 levels and I would like my score to transfer to the next level how do I do that?

Instructor: At the bottom of your first level (where you may have spawn timers), you want to add a public int PlayerScore.

Then, when you win a level, you want to get the player local data. Then, you can set PlayerScore to PD.Score.

Student: I did that and it didn't do anything…

Instructor: In your text object's function (possibly ScoreFN), use your PlayerScore variable instead of PD.Score.

Student: Now it just stays 0…

Instructor: Sounds like PlayerScore is never getting set to PD.Score. If it is, then make sure that PD.Score is ever going up (in Smash, we did this in CollisionWithBulletFN).

Student: I have that.

Instructor: So here's what it turned out to be:

The PlayerScore variable wasn't getting updated to be PD.Score.

Also, to keep the score between levels, you have to set the Player's local score to PlayerScore in the level initialization code.

Sound Effects Play "Weird"

Student: When I apply a sound effect to a certain button or collision, the sound effect will be this really long and loud sound that wasn't the sound effect. I think the problem is that it tries to stretch the effect to the whole time that I'm colliding the the object. How can I make it to just play the effect once and not stretch it out?

Instructor: What's actually happening is that the sound effect starts playing every frame that your sprites are colliding. We didn't have this problem in Smash since our snakes only played the sound effect just before deleting.

I'll need to do some research on a decent way to play a sound only once for persisting sprites, but you could probably accomplish this with just adding a timer until you're allowed to play the sound again. I'll let you know if I find a better way to do this.

Making Something Appear

Student: Hello, I would like to make something appear when I kill my boss, how do I do that?

Instructor: Ok, to make something appear when you kill your boss:

You probably have a function that causes the boss to "die" after a certain number of hits. The line of code that makes him die is probably something like this:

This.Sprite.Delete();

So, to make something else happen, put it in the function before that line of code.

Stopwatch

Student: OK, so I have a car and a finish line with collision. What I need is for the stop watch to start when I collide with the finish line and then stop when it collides again. I know its similar to score but I can't get the time to work.

Instructor: You need a public static variable or a PlayerData variable, one of the two. I suggest calling it WatchStarted. You also need a timer variable (again, public or in PlayerData). Then you need a function like this:
// If I collide with the finish line
{
  // If the watch is not started
  {
  // Set the watch started flag
 
  // Reset the timer to zero
  }
}
 
// If the watch is started
{
  // Increment the timer
}

The other trick is to get that to show up as minutes and seconds.

int minutes = timer / 3600;
 
int seconds = (timer % 3600) / 60;

And finally, setting a text object.

This.Text.Text = minutes.ToString() + ":" + seconds.ToString();

That will make it so your timer shows up as "3:14" when you have 3 minutes and 14 seconds left.

Making Player Bounce on Certain Sprites

Student: I want my character to be able to bounce on certain objects explained in the topic title. It would be nice if the height of his bounce depended on how high and fast he impacted on the ground.

Instructor: You want a behavior like this:

// Get the player colliding with me
// If I have such a player
// Set the player's Y velocity to his
// current Y velocity multiplied by -2.0f

That's all. Play with that -2.0f until you're happy with the results.

More Upgrades?

Student: How could I make An upgrade change certain sprite animations? and How Can I make a bullet explode into three bullets when it hits the enemy? And how can I make My player shoot in a shotgun like fashion(three bullets at once)? also, how can I make lightning shoot out of my player but not shooting a bunch of lightning shaped bullets, but one Short ranges bolt come out of my player Like Sith lightning?

Instructor: Part of the answer is figure it out for yourself.

That's a lot of features and we are not here to program your games for you, so try to figure some of that out. I'll post help to each one as I find time to do it, but that's a lot of time you'll have to try to get it working on your own.

Adding Gravity to Enemies

Student: I would like to add a walking enemy that has gravity and jumps when at the end of a platform. If you could give me the outline I'll try to figure it out.

Instructor: Currently, I've got no simple way of doing that - it would be somewhat tricky. I'll let you know if I get something up, but try to design around this.

Spawn Location

Student: Hey does anyone know how to make enemies spawn slightly off the screen.

Instructor: Basically, the way we do this is by picking a random location on a circle (centered in the center of your viewport) with a radius just large enough to be bigger than the screen. Here's the code for such a thing:

// Make a random angle
float angle = This.Game.RandFloat() * 2.0f * (float)Math.PI;
 
// Figure out how far it is to get just off the screen
float distance = (new Point2D(
  (This.Game.WorldSize.Width + EnemyCopy.GetWidth()) / 2,
  (This.Game.WorldSize.Height + EnemyCopy.GetHeight()) / 2)).length();
 
// Set the spawned enemy's position to a random point
EnemyCopy.Position = new Point2D(
  (float)Math.Cos(angle) * distance + This.Game.ViewportPosition.X + This.Game.ViewportSize.Width / 2,
  (float)Math.Sin(angle) * distance + This.Game.ViewportPosition.Y + This.Game.ViewportSize.Height / 2);

Bullets Not Firing at Certain Angles

Student1: At certain angles relative to the player, bullets don't fire, for some reason. Jarrod says he has no idea, and that I should ask the forums.

Here's the firing code, it's pretty much the same as the Smash code (Where the problem didn't happen):

public static void PlayerFireFN()
{
  //If the player clicks M1
  if (This.Game.IsMouseTriggered(0))
  {
    //Find the bullet
    Sprite Bullet = This.Game.FindSprite("Bullet");
 
    //Find the target
    Sprite Target = This.Game.FindSprite("Target");
 
    //If we have both
    if (Bullet != null && Target != null)
    {
      //calculate our starting position
      float StartX = This.Sprite.Position.X + (This.Sprite.GetWidth() - Bullet.GetWidth()) / 2.0f;
      float StartY = This.Sprite.Position.Y + (This.Sprite.GetHeight() - Bullet.GetHeight()) / 2.0f;
 
      //calculate our destination      float EndX = Target.Position.X + (Target.GetWidth() - Bullet.GetWidth()) / 2.0f;
      float EndY = Target.Position.Y + (Target.GetHeight() - Bullet.GetHeight()) / 2.0f;
 
      //copy the bullet
      Sprite BulletCopy = new Sprite(Bullet);
 
      //place the copy on our starting position
      BulletCopy.Position = new Point2D(StartX, StartY);
 
      //calculate our direction vector
      Point2D Direction = new Point2D(EndX - StartX, EndY - StartY);
      Direction = Direction / Direction.length();
 
      //send the bullet along the vector
      float speed = 30.0f;
      BulletCopy.Velocity = Direction * speed;
 
      //make bullet used
      BulletCopy.Unused = false;
    }
  }
}

Student2: If you have bullet deletion too, then the problem lies in not changing the name of the bullet you fired. The bullet the game refers to vanishes when deleting, making the search for the previous bullet source return false.

Instructor: The problem was that the bullets were not on the same display list as the player, so they were hitting the player and deleting.

Switching Weapons

Student: Can you hit a key to switch weapons so it acts as the current attack? If so, what is the code to do so?

Instructor: You would need something in PlayerData to decide which weapon to use, such as public int CurrentWeapon.

Then, you need a function to handle switching, that basically looks like:

// If the player triggers E
// Increment the current weapon
// If the current weapon is higher than the number of weapons we have
// Reset the current weapon to zero

With that attached to your player, you just need to update PlayerFireFN to include the use of different weapons.

// If current weapon is 0
// Fire the pistol
// If current weapon is 1
// Fire the shotgun
// If current weapon is 2
// Fire the red rubber ball

Getting to Change Lanes

Student: I have an idea I want to put into my game and I don't know how to do it. I want to have the ability to switch lanes with the w and s arrow keys. There would be 3 lanes to switch from to fight all the enemies. Here is a attachment at the bottom of this post to kind of illustrate what I mean. Its really a game changing idea I have no idea how to do. Hope you can help so please so kindly reply.

changingLanes1.tif

Add on to this idea. I want to make it sure that the enemies go in their lanes. Not random or following just in their designated lanes.

changingLanes2.png

Instructor: First of all, thanks for the picture to make things clear.

What you can do is add a behavior that looks like this:

// If the player triggers W or Up
// and the player's y is greater than 0
// Player's y position += Distance between lanes
// If the player triggers S or Down
// and the player's y is less than the world's height
// Player's y position -= Distance between lanes

Student: Here is the problem from the other thread. IF you can delete that one and look at this one. Then it would be helpful.

I somewhat understand the pseudo code that you gave me. This is what I got. When I attach the code to the player. It doesn't work, so not sure what is the problem.

float y = This.Sprite.Position.Y;
// If the player triggers W or Up and the player's y is greater than 0
if(((This.Game.IsTriggered(InputKey.W)) || (This.Game.IsTriggered(InputKey.Up))) && (y < 0))
{
  // Player's y position += Distance between lanes
  y += 10;
}
 
// If the player triggers S or Down and the player's y is less than the world's height
if (((This.Game.IsTriggered(InputKey.S)) || (This.Game.IsTriggered(InputKey.Down))) && (y > This.Game.WorldSize.Height))
{
  // Player's y position -= Distance between lanes
  y -= -10;
}
Maybe this screenshot will show it easier

Making Enemies Spawn in Zones

Student: I was wondering how we could make our enemies spawn in from certain areas of the map, like the corners, rather than randomly all over.

Instructor: Here's the basic idea

// Get a random number up to but not
// including however many spawn points you have
// If random number is 0
// Spawn at first spawn point
// If random number is 1
// Spawn at second spawn point
// If random number is 2
// Spawn at third spawn point

And so on…

Slowing Rate of Fire

Student: I want something to shoot, not at a bullet hose, but at a slower rate of fire. how would I do that? I already have the fire function that is a bullethose.

Instructor: Basically, we need a timer of some sort, either a public static int or using local data. The public static int is a bit easier, but isn't as clean. Basically, all you need is your usual player fire stuff with a bit extra to handle the timer.

// If the timer is up
if ( timer <= 0 )
{
  // Your player fire code stuff
 
  // Reset the timer
}
// Otherwise
else
{
  // Decrement the timer
  --timer;
}

Music Problems

Student: For some reason, the music I have wont play. I've tried a different file but it still wont play.

This is the line of code I am using:
// Start some background music
This.Game.PlayBackgroundMusic("Adv_1_Menu.wav");

Instructor: I have no idea what was wrong or how we fixed this. We opened the music file in Windows Media Player and then ran the game again after that test. Suddenly, it worked.

Broken Spawning

Student: My spawning is broken for some reason, Jarrod couldn't figure out why my enemy master sprite gets deleted, and it seems like you have to wait for another to spawn before you kill one.

Instructor: Turns out you were renaming your master sprite, not your copy. Then, you could never copy the master because he was labeled as a copy.

Turret Not Firing When It Should

Student: My turret will shoot bullets fine, but when I try to put in a bullet delete function the turret stops firing bullets. Here's a copy of my bullet delete function.My background is 1024x768 and the bullets should delete when they leave the map.

public static void BulletDeleteFN()
{
  // If we're colliding 
  if (This.Sprite.Collision())
  {
    This.Sprite.Delete();
  }
 
  // Calculate Edges
  float Left = -This.Sprite.GetWidth();
  float Right = This.Game.WorldSize.Width;
  float Top = -This.Sprite.GetHeight();
  float Bottom = This.Game.WorldSize.Height;
 
  // If we're off the edge of the world
  if ( This.Sprite.Position.X < Left
    || This.Sprite.Position.X > Right
    || This.Sprite.Position.Y < Top
    || This.Sprite.Position.Y > Bottom )
  {
    //Delete Me
    This.Sprite.Delete();
  }
 
  //...
}

a little while later…

I figured out my problem.

Don't need help anymore.

Instructor: I'm willing to guess your bullets were colliding with your turrets?

Score/Next Level

Student: Is there a way to make it so that once you get a high enough score, you advance to the next level?

Instructor: Make a behavior for the player that does the following:

// Get the player's data
// If the player's score is greater than [number of points to win]
// The player wins

Timer

Student: I need to put a timer that counts down and makes the game end. How would I do this?

Is it similar to the score?

Instructor: It would be somewhat similar to the EnemySpawnTimer from space shooter.

You need a public static int that gets reset in your level initialization function. In you level's main behavior, just decrement the timer every frame. When that timer hits zero, end the game (ending the game can be done with This.Game.EndGame() )

Then you need a text object, which will be similar to the player's score.

Low Gravity Movement

Student: In my game you are in space, I would like movement to have some drift and inertia in it. But currently it moves at constant speed and can stop immediately. I tried to add this code to at least test my idea. But it did not work at all.

//set speed 
float speed = 2;
//if hit A
if (This.Game.IsPressed(InputKey.A))
{
  // Go left
  x = x - 1;
  //increase speed
  speed = speed + 1;
}

Instructor: Instead of

float speed = 2;

Try this:

float speed = This.Sprite.Speed;

That will grab the speed you previously had as the base speed.

Non-repeating Background

Student: I have this viewport its a big long background. But when I use the code from smash

public static void PlayerViewportFN()
{
  code
  code
  code
  code
}
It turns out like this. see attached
non-repeating-background-problem.png

I have one background dont want a repeating background.

Instructor: At the top of player viewport stuff, we defined Left, Right, Top, and Bottom values. Basically, make sure these values don't include constant numbers (like +50). If that's not what needs to be fixed, then go to Program.cs under Engine->Utility and change the viewport size there to match your map size.

Student: Thanks I actually used PlayerHFlip and made my solution much much easier.

Lightning Go Away and Direction

Student: So... I got my lightning to fire, but I can't get it to go away... or turn the way the player is firing.

Instructor: Getting it to go away requires more information.

Turning the way the player is facing, assuming you're using the player's horizontal flip flag, means you could do the following:

// Get the player
Sprite Player = This.Game.FindSprite("Player" ) ;
 
// Set my hflip to the player's hflip
This.Sprite.HFlip = Player.HFlip;

Upgrades

Student: Can I change my score points to Exp or money and get upgrades with it? and also, how do I upgrade myself or others?

Instructor: Local data! Basically, you can use the score variable we had in PlayerData for experience points or money, or you can add those variables too. It's just a matter of earning points.

Pseudo-code example:

PlayerData
{
  // Variables
  public int health = 9;
  public int score = 0; // Used for upgrades!
  public int speed = 3; // Can be upgraded
  // Player needs 1000 points for first upgrade, we'll make this larger each upgrade
  public int levelUp = 1000;
}

In this example, I'm using score as my experience points. Speed is the only thing that I can upgrade right now, and I can only do so when I have 1000 score (or more). So, the upgrade function would look kind of like this (only giving you comments for the most part).

// A function to upgrade speed by pressing U
public static void PlayerUpgradeSpeed()
{
  // Get the player's data
 
  // If the player presses U
  // and has enough points
 
  // Subtract the amount we need to level
  // up from the player's score
 
  // Upgrade the player's speed
 
  // Increase the amount of score
  // needed to level up
}

Just make sure that you're using the PlayerData values you upgrade in your other functions. For this example, I would want to use the player's speed variable in my player's movement function.

Spawning, Overlapping, and Phasing Out

Student: When my targets spawn, they overlap each other. Is there a way that they won't overlap each other?

Also, I put the code in for my targets to phase out after phasing in in a state machine, but it isn't working. The targets phase in and don't phase out. Help?

Instructor: If your targets are spawning randomly, there's not really any good way to keep them from overlapping each other.

As for the state machine, turns out there was no code to actually switch from phase in to phase out.

Getting Sprite to Spin

Student: I would like to make my shuriken spin while they go through the air. What is the code, and where should it go?

Instructor: Make a new behavior to attach to your shuriken sprite. All it needs is one line of code:

// Spin the shurikenThis.Sprite.Angle += 13;

Moving View Port

Student: I know It has to be a function but I'm wondering the actual code... it seems it would be harder than mounting to a sprite (which I'm not doing) what I am wanting to do is being able to freely move the viewport.

Instructor: The best thing to do is attach something similar to the PlayerViewportFN function from Space Shooter to a sprite that has transparency of 1 (as in it is completely invisible). Then you just need something to move that sprite (like eight way movement). Once that sprite's moving, it should bring the viewport with it!

Lightning and Particle Effects

Student: In my game there are going to be attacks in which the player will launch lightning, fire, etc. I was wondering how to do this, and what you think the best way will be.

Instructor: See PlayerFireFN in Space Shooter and Smash. Instead of bullets, use lightning.

Getting Player to Jump Higher

Student: I have been using the platformer engine and I was wondering how I can make my player jump higher.

Instructor: In the PlatformStates.cs, in the Update function of the OnPlatform state, there is a variable called jumpStrength. It's set to 10.0f by default, but you can change it if you wish. Don't make it any higher than 20 though - the player would fall through platforms on the way down.

Changing Zoom Level

Student: For my game I have pretty large sprites, and I was wondering if there was a way to make the screen be more zoomed out from the player in the game? This would stop me from having to shrink all my sprites. Thanks.

Instructor: You can increase the viewport size in Program.cs under Engine->Utility. If that isn't enough, shrink the sprites.

Keeping Track of Completed Levels

Student1: Alright, so here's my problem.

My game is a game where you avoid zombies trying to find a flag spawned randomly in the level, and after getting it, you go through the level again (randomly spawned still).

My main problem though is trying to get my levels completed not to reset after resetting the level.

I'd love some help with this! Thank you!

Student2: trigger a +1 to a variable housed in the player data file upon winning of a level

Student1: Not quite what I need, I already tried that and it resets the variable when the level resets, so that doesn't work.

Instructor: Use a public static int instead.

Car Slows Down When Hitting Oil Spill

Student: Right now, my car is made to show a spin animation when it collides with an oil spill, now I need it to slow down as well. I've tried changing the speed, but it says that variable doesn't exist.

I have this as a function in player behaviors right now, but could it be a state machine instead?

Instructor: You can do either. As a behavior, you could multiply the player's velocity by 0.5f (or any value less than 1) to slow down the player. Basically, it works like this:

// The player has updated his movement
// via some movement function.
// If the player is colliding with oil
// Set the player's velocity to his
// current velocity multiplied by 0.5f

Particle System OnUpdate

Student: I am trying to apply a particle system to a copy and have it trigger for all of the copys lifespan. I have no clue how to do this and if anyone could help it would be great.

Instructor: The way we do that is with the particle system's main behavior. For example, assume we have a function ExplodeInitFN for the particle system's initialization, and a function ExplodeUpdateFN for the particle system to update each particle every frame they live. The way we build our particle system would look like this:

// Make the explode particle system using the star from Smash
Frame Star = new Frame("Art Assets\\Actors\\star.png", Color.Black);
ParticleSystem Explode = new ParticleSystem("Explode", Point2D._Zero, Star);
Explode.Unused = true;
Explode.ParticleInit = Behaviors.ExplodeInitFN;
Explode.ParticleUpdate = Behaviors.ExplodeUpdateFN;

Player Gravity

Note: this topic is out of date as we now have a specific build of the engine for platformers.

Student: I'm making a platformer on C#, and I've already made a new PlayerBehavior.cs with movement. However, My game requires gravity to work and I have no idea of how you would make a gravity engine. If someone could please tell me how to start and the variables/booleans that would be required to make it, I would very much appreciate it.

Instructor: Platformers are something we've never really focused on in any of our workshops since they require such a specialized engine to get them to work. Since we tried to keep our C# engine as general as possible, it does make platformers a bit more difficult. To solve this, here's a pretty simple platformer that uses our C# engine (see attachment).

This simply has a player jumping between two platforms. Hopefully, I've commented the code enough to make it accessible, but don't hesitate to ask questions about it!

Something that would be incredibly handy for our platformer is some easy way to make platform sprites. Sadly, the best solution I can offer is spawn function. The following code should be placed in PlatformHelpers.cs after the LandsOn function.

/// <summary>
/// Copies a master platform and places it at a given position.
/// </summary>
/// <param name="originalPlatform">A Sprite named "Platform" to copy.</param>
/// <param name="x">The x position to place the platform.</param>
/// <param name="y">The y position to place the platform.</param>
/// <returns>The new Platform sprite, copied from the original.</returns>
public static Sprite SpawnPlatform(Sprite originalPlatform, float x, float y)
{
  // Protection: If we are given a bad sprite
  if (originalPlatform == null)
  {
    // We can't copy it, so return null
    return null;
  }
 
  // Start by copying the original platorm
  Sprite newPlatform = new Sprite(originalPlatform);
 
  // Place this copy at our given position
  newPlatform.Position = new Point2D(x, y);
 
  // Return the copy
  return newPlatform;
}

To use this function, we would do something like the following. First, we need to make the original platform. After we have that, we can copy it as we wish.

// Make the original platform sprite
Sprite Platform = new Sprite("Platform", "PlatformActor", new Point2D(500, 420));
Platform.DisplayList = 1;
 
// Now use our spawn function to make another at 300, 400
Helpers.SpawnPlatform(Platform, 300, 400);

Changing Enemy Speed

Student: How do I change the speed of my enemies to make them faster or slower?

Instructor: If you're using the Follow function, it takes three parameters.

The first is the sprite to follow.

The second is how fast to follow that sprite.

The third is how handle turning toward that sprite (0 is just turn immediately, while closer to 1 gives a slower curve).

So, you want to change the second parameter.

Boss Firing Pattern

Student: How do I make the Boss shoot in a fan shape?

Instructor: You mean like the spreader weapon in the old game Contra?

Instead of creating one projectile at a time, you would create as many as you need (3 or 5 maybe) and then set their Vector Directions appropriately. A vector direction of (-1,0) represents directly left, for example. A direction of (-1,-1) is up-left, and a direction of (-1,1) is down-left.

The x-axis in computer graphics is usually like in your math class (positive to the right). The y-axis, though, is positive downward. The origin position (0,0) is the top-left corner of your level.

New Level

Student: I am making a second level with all the same things but new enemies replacing the old ones.What do I need to change,add, and lose on my second level?

Instructor: You should be able to change most things with the enemies, such as their movement for example. One important thing to remember for a new level is that any global variables you are using will need to be reset, unless it is like a score variable that needs to retain its value from level to level.

Winning with Rockets

Student1: I'm trying to get to win a level by destroying 30 rockets. What code should I right to make this happen?

Student2: Make a variable that counts the rockets spawned, make it count down from 30. the code after that should look about like this.

if (rocketcounter <= 0)
{
  this.game.setcurrentlevel = winlevel
}

The code for counting down the counter is about like this.

if (rocketcopy.delete == true)
{
  rocketcounter = -1
}

Instructor: Basically right, but make sure you're using the correct syntax.

Level Change Crash

Student1: When I try to change levels it crashes however when I just set the code in the arena to

This.Game.SetCurrentLevel("Arena")

it works just fine.

I double checked the spelling by using ctrl-c, ctrl-v.


Student2: Try something similar to what I did... make code something like this.

if (snakespawntimer <= 0 && eyeSpawntimer <= 0)
{
  This.game.setcurrentlevel("level2")
}

Might help... it's nothing more than a theory.

Instructor: What are you checking for in order to change the level? If you're checking for a sprite or something that doesn't exist, that could cause the crash.

Student1: The problem is that it only chrashs when it is not set to "Arena" as the level to change to.

Student2: Did you check and make sure of your level behaviors and backgrounds?

Instructor: This is a problem with using local data and changing levels. If you're trying to get local data, you should make sure that the sprite you have is valid (!= null) before trying to get its local data.

Particle System Position

Student: How do I make it so the particle system explodes at the center of my boss and not in the upperleft corner?

Instructor: We need to add half of the Boss's width and height to the position (which is the upper left corner).

For example, if we want the center along the x-axis...

This.Sprite.Position.X + This.Sprite.Frame.Width / 2.0f

The y-axis is very similar, just be sure to use Y and Height instead!

Shields, Firing and Restoring Health

Student1: I have the power up working now I want to know how to add

  • Shield
  • Fire more powerful shoots
  • Restored health

Student2: Well, for shield, you could make a variable for it, and then in the section where you take health away, check first that the shield is 0, and then hurt health.

Restoring health could just be a matter of increasing your health variable whenever you touch the health powerup.Firing more powerful shots? I would suggest making a new bullet, then firing that if a variable was more than 0 (make a variable, add 600 to it when you touch the powerup, minus one from it every frame)

Variables, variables, variables. Hope I could help.

Instructor: For a more powerful bullet, you could change the bullet copy's name to something like "PowerBullet". Then, check to see if the enemy is colliding with a sprite called "PowerBullet" and take more health away from them!

Student3:

public static void PlayerFireFN()
{
  // if we press space
  --TimerCount;
  if ((This.Game.IsPressed(InputKey.Space) || 
    This.Game.IsPressed(InputKey.LeftControl) || 
    This.Game.IsPressed(InputKey.RightShift)
    ) && TimerCount < 0)
  {
    int extrashots = 2;
    for (int i = 0 - extrashots; i < extrashots + 1; ++i)
    {
      // Find the palyer sprite
      Sprite Player = This.Game.FindSprite("PlayerSprite");
 
      // Find the master bullet sprite
      Sprite Bullet = This.Game.FindSprite("BulletMaster");
 
      // Copy the master bullet
      Sprite BulletCopy = new Sprite(Bullet);
 
      // Change the name of the copy
      BulletCopy.Name = "BulletCopy";
 
      // set the copy's postion to the player's position
      float ShotSpread = 72;
      float angle = (Player.Angle + (ShotSpread * i) + PulseStart * 13 ) 
        * (float)Math.PI / 180.0f;
      BulletCopy.Position = new Point2D(Player.Position) +
      new Point2D(((float)Math.Cos(angle) * 32) + 24,
        ((float)Math.Sin(angle) * 32) + 24);
      BulletCopy.Angle = (Player.Angle + (ShotSpread * i));
 
      // give the bullet some velocity
      float speed = 16;
      float x = (float)Math.Cos(angle) * speed;
      float y = (float)Math.Sin(angle) * speed;
      BulletCopy.Velocity = new Point2D(x, y);
 
      // Set the bullet to used
      BulletCopy.Unused = false;
    }
 
    // Add a counter
    if (PulseStart > 0)
    {
      TimerCount = PulseSpace;
      PulseStart--;
    }
    else
    {
      TimerCount = TimerReset;
      PulseStart = PulseCount;
    }
  }
}
//Variables for player fire
static int TimerCount = 0;
static int TimerReset = 60;
static int PulseSpace = 3;
static int PulseCount = 2; //one more than actual number
static int PulseStart = PulseCount;

Instructor: Looks good. Good job.

Spawning a Boss

Student: How do I make it so that when I kill 50 enemies the game spawns only 1 boss?

Instructor: If you made a bool value, say BossNotSpawned, that you would set to false after spawning the boss, you could check if you've killed your fifty enemies and BossNotSpawned. If that comes back true, spawn your boss and then set BossNotSpawned to false.

Student: My boss spawns but will not stop spawning.

Instructor: Make sure that when you spawn your boss, you make BossNotSpawned false. Also, make sure that you're checking your BossNotSpawned before spawning the boss!

Lose Screen

Student: I would like to put in a lose screen that happens once all of my city's are destroyed and go to the start screen when you press space.

Instructor: You need to make a lose level that will show a lose background and wait for the player to press some key (such as space) before returning to the main menu.

Make sure to make a new Background in CreateResources() that uses the filename of your lose background.

Then make your Level in CreateResources().

You'll need a function, probably LoseLevelInit(), that will set the master map to the background you made.

You'll then need a function, probably LoseLevelFN(), that checks to see if the player presses space. If so, then we set our current level to the menu level.

Make sure these behaviors are attached to your level correctly and that when you lose the game, your game sets the current level to your lose level.

Collision with Specific Animation

Student1: My player has this animation where he's on fire, and I want him to kill enemies when he's like this. How can I have the enemies check that they've hit the player in a certain animation?

Student2: Have the enemy check if it ran into the player then put && in the if statement and then check if Player Animation (The Animation number for the fire thingy) == true.

For example,

if (Player.CollisionWithSprite("Enemy")==true && Player.Animation(5) == true)
{
  This.Sprite.Delete == True
}

Then attach the behavior.

This would probably need editing so don't copy it exactly but you should be able to get the approximate idea.

Instructor: Looks good to me.

Setting Launch Position and Coils

Student1: I am trying to get my claw to not only follow the target but when it launches, it launches from the middle of the mane claw and have the coils follow that line as well.

If anyone has any ideas please help because I don't know why is isn't doing what I want it to do.

Student2: One thing that you probably could do is make a function that copy's a master loop in the chain and have them all linked so they can move freely but have to always be touching each other... or you could make it part of the animation and have it always go a certain distance.

Instructor: For getting the Claw to come out of your ClawShooter with nicely lined up positions, when you fire your claw, you need to use the following for the position of the copy of the Claw. (Make sure to modify the code to use your variable names.)

But first, some math explanation. We want to shoot our claw from the right of the shooter, so we need to add the shooter's width to the shooter's position to get our x. Our y value is a bit trickier, since we want to fire with our vertical center's matched. To do that, we start with our shooter's y position, add half of its height (so we launch from the shooter's vertical center), but then we subtract half of our claw's height so that we move the claw up enough so that the vertical center's match.

// Find the right side of our claw shooter
float x = This.Sprite.Position.X + This.Sprite.Frame.Width;
 
// Find the y position that matches our claw shooter's vertical center with the claw's vertical center
float y = This.Sprite.Position.Y + ( This.Sprite.Frame.Height / 2.0f ) - ( ClawCopy.Frame.Height / 2.0f );
 
// Give our claw copy its position
ClawCopy.Position = new Point2D( x , y );

Start Screen

Student1: I am trying to put a start screen on my level. But even when it is told to go to the start screen it says it does not exist and all attempts leave errors. please help!

Student2: Check and make sure that you have created the level under the create resources here section.

Then make sure that the "OnStart" area has thatas the start level thingy.

Instructor: A few things were wrong here.

First, we need to actually make the background in CreateResources(). Make sure we are looking for the correct filename.

Also in CreateResources(), we need to make our level and attach its behaviors (make sure these are the behaviors we want this level to have!).

Make sure any time we say This.Game.SetCurrentLevel( "LevelName" ); that "LevelName" matches the name we gave our level when we made it.


Spawning Multiple Sprites in Different Positions

Student1: I want my enemy sprites to spawn in 2 specific locations. right now I have it on a random integer right now so it spawns randomly everywhere on the map, I have tried changing it to a Point 2D but that gives a debug error. I don't know what I'm supposed to do. I also tried setting it to its viewportsize too, but that didn't work as well. What is the problem here?

Student2: You should try setting the RandInt thingy to a certain set of coordinates.

For example, RandInt(345, 567) && RandInt(683, 780)

These were random coordinates but I hope you get the picture.

Instructor: If you check out the Random Fun topic, it has the basics of making choices. However, here's some more thoughts on choosing between two specific points...

// Flip a coin
int choice = This.Game.RandInt(2);
 
// Need a variable to store our point
Point2D SpawnPoint = null;
 
// If we flipped "heads" (0)
if ( choice == 0 )
{
  // Set SpawnPoint to our first point (Do it yourself!)
}
// If we flipped "tails" (1)
if ( choice == 1 )
{
  // Set SpawnPoint to our second point (Do it yourself!)
}

Player Wrapping

Student: So I finally got my wrapping Background to work but when I run it my player goes with the background and then dissipates. I know im supposed to set the velocity to my player so it stays in the map but where do I put it + Whats the line of code I should put in for it to work?

Instructor: Your player needs to be running along with the screen.

Some sort of behavior needs to be attached to your player (like our 8-way movement) that starts off by setting the player's velocity to that of the ghost sprite you have moving the background.

Something like...

// Start the player moving rightward
This.Sprite.Velocity = new Point2D( 3.0f , 0.0f );
 
// ***8-way movement basics***
 
// Now set the velocity to include our background scrolling
This.Sprite.Velocity = This.Sprite.Velocity + new Point2D( x , y ) * speed;

Different Collision Types

Student: Help! I am trying to give a few different sprites different types of collision!

For example,

Player = BoundingBox
Bullet = BoundingCircle

I have tried a few ways but nothing seems to work!!

Instructor: This can't be done with the engine as is. You have to use circles for everything or boxes for everything. Those are your only options.

Student: NNNOOOOOOOOOOOOOOOOOO!!!!!!!

Accessing Player Data

Student: I have this playerdata value Energy, and I need to know how to access it and edit it remotely.

Who knew energy could be so hard...?

Instructor: First, the PlayerData needs to be attached to the player sprite - looks kinda like

Player.Data = new PlayerData();

Next, to access this in some function, we need to find the player sprite.

Sprite Player = This.Game.FindSprite( "Player" );

Finally get the player data from the player.

PlayerData pd = Player.GetLocalData<PlayerData>();

Now, we can get energy from the local data by doing something like (this subtracts 5 from it)

pd.Energy -= 5;

Wrapping a Background

Student1: Don't understand how to make a wrapping background for my game. Picture is 1600-600 pixel png image.

Student2: if you get the veiwport to move the background will always wrap.

Instructor: we just need the viewport to scroll with the player. We can either use the viewport scrolling function from Space Shooter (which needs to be called each frame by some behavior) or the viewport scrolling behavior we had in Smash (which we'd want to remove the parts about limiting the player's movement). Either way, attach the behavior to the player sprite.

Student3:

public static void ViewportFollowFN()
{
  // calculate where we want our x and y
  float x = This.Sprite.Position.X - 500;
  float y = This.Sprite.Position.Y - 700;
  // place viewport
  This.Game.ViewportPosition = new Point2D(x, y);
}

you put this code in the item Game Behaviors that is in Behaviors. you can change the 500 and 700 to put your person where you want it.

Destroying Buildings with Enemies

Student: I am trying to get my enemy rockets to destroy the selected buildings. How do I do this?

Instructor: First of all, the rockets and buildings need to be on different display lists.

Secondly, your buildings need some behavior attached that looks like the following.

// If I collide with a rocket
if ( This.Sprite.CollisionWithSprite( "Rocket" ) != null )
{
  // Destroy me!
  This.Sprite.Delete();
}

Player Does Not Duck or Jump

Student: I gave my player the options to jump and duck, I set it to my sprite and the animations to my actor. Yet when I run it and I try to jump or duck using the keys that are the commands, the player does not jump.

Whats the problem?

Instructor: Could be a few things. Make sure that you're using IsPressed instead of IsTriggered for your keys. Also, make sure that if you're resetting the animation to standing, it should be done before you check to see if he should jump or duck.

Another problem that may come up is that if we set the animation directly, it resets to the first frame of the animation every frame, so we never see an animation.

To fix this, we can do something like we did in Smash, and it is very important that we use else if statements so we only change to our usual animation if we're really not pressing anything.

// Get our old animation
int OldAnimation = This.Sprite.Animation;
 
// Prepare for a new animation
int NewAnimation = This.Sprite.Animation;
 
// If I press Space
if ( This.Game.IsPressed( InputKey.Space ) )
{
  // Change animation
  NewAnimation = 1;
}
// Otherwise, if I am pressing A
else if ( This.Game.IsPressed( InputKey.A ) )
{
  // Change to some other animation
  NewAnimation = 2;
}
// Otherwise
else
{
  // Use the usual animation
  NewAnimation = 0;
}
 
// If our animation is different
if ( NewAnimation != OldAnimation )
{
  // Actually change our animation
  This.Sprite.Animation = NewAnimation;
}

Sound

Student: Is there a way to make the effect sound quieter and the background music louder?

Instructor: The school computers do have some sound software called Audacity (which is free, so you can get it at home). However, it can be a bit complicated to use.

Regenerate Health

Student: How would I make a float such as my Energy regain 1 every 1.5 seconds?

Instructor: A timer would be the best answer. Have this timer decrement, such that when it hits zero, you give the player 1 energy. The trick is to reset the timer to a value that is equal to 1.5 seconds - but we use frames!

So, 60 frames per second times 1.5 seconds = 90 frames. That means reset your timer to 90 after giving the player energy.

Enemies Shoot

Student: How do I make the enemy shoot at my player?

Instructor: They need a timer (best done through local data). Have that timer decrement, and when it hits zero, copy a bullet and have it follow the player for a single frame (when you create it).

This will work a lot like when the player fires, but instead of when you press a specific fire key, you wait for the timer to hit zero.

Personal tools
Namespaces
Variants
Actions
Navigation
Engineering
Game Design
Multimedia Production
VG Programming
Downloads
Toolbox