Time : 28 november 2022 - november 9 2022
The 2D platformer I've crafted focuses on surmounting a series of demanding challenges across three distinct levels. The aim of this game is to successfully maneuver through each level and reach the finish line and avoiding any interruptions. I completed the development of this game within a two-week period
In my 2D platformer game, players can perform several actions like walking, jumping, double jumping, wall jumping, and sliding off walls. Despite these capabilities, the game maintains a slow pace, rewarding careful movement and precise control to navigate obstacles effectively. getting the right speed and jump height was challanging to find but it worked out.
public class PlayerMovement : MonoBehaviour
{
private Rigidbody2D rb;
private BoxCollider2D coll;
private Animator anim;
private float dirX = 0f;
[SerializeField] private float moveSpeed = 7f;
[SerializeField] private float jumpForce = 14f;
[SerializeField] private MovementState state;
[SerializeField] private LayerMask jumpableGround;
private SpriteRenderer sprite;
[SerializeField] private AudioSource jumpeffect;
private bool hasJumped = false;
private enum MovementState
{
idle,
running,
jumping,
falling,
on_wall
}
private float wallJumpTime = 0.2f;
private float wallSlideSpeed = 0.1f;
private float wallDistance = 0.58f;
private bool isWallSliding = false;
RaycastHit2D WallCheckHit;
private float jumpTime;
private bool isFacingRight = true;
void Start()
{
rb = GetComponent<Rigidbody2D>();
coll = GetComponent<BoxCollider2D>();
anim = GetComponent<Animator>();
sprite = GetComponent<SpriteRenderer>();
rb.freezeRotation = true;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
dirX = Input.GetAxisRaw("Horizontal");
rb.velocity = new Vector2(moveSpeed * dirX, rb.velocity.y);
if (Input.GetButtonDown("Jump"))
{
if (ISGrounded() || isWallSliding)
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
jumpeffect.Play();
if (hasJumped && !WallCheckHit) anim.SetTrigger("doublejump");
}
}
UpdateAnimationState();
}
private void UpdateAnimationState()
{
//MovementState state;
if (dirX > 0 && !isWallSliding)
{
state = MovementState.running;
sprite.flipX = false;
isFacingRight = true;
}
else if (dirX < 0 && !isWallSliding)
{
state = MovementState.running;
sprite.flipX = true;
isFacingRight = false;
}
else state = MovementState.idle;
if (rb.velocity.y > 0.1f && !isWallSliding)
{
state = MovementState.jumping;
}
else if (rb.velocity.y < -0.1f && !isWallSliding)
{
state = MovementState.falling;
}
else if (isWallSliding)
{
state = MovementState.on_wall;
}
anim.SetInteger("State", (int)state);
}
bool ISGrounded()
{
if (Physics2D.BoxCast(coll.bounds.center, coll.bounds.size, 0f, Vector2.down, 0.1f, jumpableGround))
{
hasJumped = false;
//jumpTime = Time.time + wallJumpTime;
return true;
}
else if (!hasJumped)
{
hasJumped = true;
return true;
}
else if (jumpTime > Time.time)
{
return false;
}
else
{
return false;
}
}
private void FixedUpdate()
{
if (isFacingRight)
WallCheckHit = Physics2D.Raycast(transform.position, new Vector2(wallDistance, 0), wallDistance, jumpableGround);
else
WallCheckHit = Physics2D.Raycast(transform.position, new Vector2(-wallDistance, 0), wallDistance, jumpableGround);
if (WallCheckHit && !ISGrounded() && dirX != 0)
{
isWallSliding = true;
jumpTime = Time.time + wallJumpTime;
}
else if (jumpTime < Time.time)
{
isWallSliding = false;
}
if (isWallSliding)
{
rb.velocity = new Vector2(rb.velocity.x, Mathf.Clamp(rb.velocity.y, wallSlideSpeed, float.MaxValue));
}
}
}