This is a bite-sized tutorial on shaking the screen in tModLoader [1.4.3]. It's usually used in boss fights and "heavy" weapons. Here's how you can implement it:
To add screenshake, we use the ModifyScreenPosition hook in ModPlayer. Let's make a new .cs file in a Players folder (for organization; this is usually good for beginners but you can decide where to put it). Here's what our code would look like:
public class ScreenshakePlayer : ModPlayer
{
public int screenshakeTimer;
public int screenshakeMagnitude;
public override void ModifyScreenPosition()
{
screenshakeTimer--;
if (screenshakeTimer > 0 )
{
Main.screenPosition += new Vector2(Main.rand.Next(screenshakeMagnitude * -1, screenshakeMagnitude + 1), Main.rand.Next(screenshakeMagnitude * -1, screenshakeMagnitude + 1));
}
}
}(check the ScreenshakePlayer.cs file attached below) Let's go over our code here:
- We declare a
screenshakeTimervariable. This is how long our screenshake lasts. Remember that it's in frames (1 second is 60 frames). - Next, we declare a
screenshakeMagnitudevariable. This is basically how much the screen shakes (how much the camera moves around). I recommend using a base of 6 and experimenting around. - In the ModifyScreenPosition hook, we decrement the
screenshakeTimervariable (decrease by 1). Because it decrements every frame, it'll be equal to 0 in the number of frames we've specified. - Now we check if
screenshakeTimeris more than 0. If it is, we continue shaking the screen. - Now we add our
screenshakeMagnitudetoMain.screenPositionby a random amount (the range is our magnitude in negative and our magnitude + 1). Voila! We've achieved a screenshake effect. But now we actually need to trigger it.
To trigger our screenshake, we simply need to change the values of screenshakeTimer and screenshakeMagnitude. For example, if we wanted to shake the screen when one of our projectiles hits an enemy, we'd use this code:
public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
Owner.GetModPlayer<ScreenshakePlayer>().screenshakeMagnitude = 4;
Owner.GetModPlayer<ScreenshakePlayer>().screenshakeTimer = 6; // This is 1/10th of a second
}We need a Player to call the GetModPlayer method. Here, I simply set Owner to Main.player[Projectile.owner]. You can probably find a way to get the Player for your need.
And that's pretty much it! Your screen will now shake when you trigger it.