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
screenshakeTimer
variable. This is how long our screenshake lasts. Remember that it's in frames (1 second is 60 frames). - Next, we declare a
screenshakeMagnitude
variable. 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
screenshakeTimer
variable (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
screenshakeTimer
is more than 0. If it is, we continue shaking the screen. - Now we add our
screenshakeMagnitude
toMain.screenPosition
by 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.