Back to Projects

2 Puzzled 2 Solve

Previous Pause Next

Time: Ongoing
Start Date: Summer 2015
Role: Generalist Programmer
Tools: C#, Unity
Platforms: PC
Description:

2 Puzzled 2 Solve is a puzzle platforming game with a unique twist: the player controls both their character and the world they move through. The player needs to navigate through levels from point A to B by jumping around in platforming mode and shifting and rotating the level as a sliding puzzle in puzzle mode. All levels are connected with each other through an overworld where players can unlock new levels and progress through the game by collecting items and learning new things about the game mechanics. The game also has an accessible and easy to use level editor which has been designed so that players can immediately jump in and start to create their own levels.



2 Puzzled 2 Solve is developed by a small two-man team. I have the responsibility for the technical implementation while my partner (Jesse Ravensbergen) is mainly responsible for the design of the game. My main area of work for this project was in the gameplay area to implement features as specified in the design and trying and get the feel of the game as good as possible. Besides working on gameplay I implemented several other systems including a fully functional in-game level editor, customized UI framework and event based input handling. Most systems are built in such a way that anyone on the team can modify all the important data either through a Unity inspector window or via external JSON files.

A code sample taken from the bounce block implementation. There is little code required to setup new block behaviours allowing to rapidly prototype and implement new block behaviours.
using Audio;
using Game.Messages;
using UnityEngine;

namespace Game.Blocks
{
	public class BounceBlockComponent : BlockComponent
	{
		protected override void Awake()
		{
			base.Awake();
			SurfaceType = EBlockSurfaceType.Bounce;

			GetOwner().LinkMessage<PlayerBallCollisionStartMessage>(OnPlayerBallCollided);
		}

		private void OnPlayerBallCollided(PlayerBallCollisionStartMessage a_Arg)
		{
			if (a_Arg.VelocityLostInCollision.sqrMagnitude > 1.0f)
			{
				AudioSourceManager.GetInstance().PlayOneShot("BounceBlockBounce", EAudioGroup.Game, transform);
			}

			Vector3 gravityDirection = a_Arg.Source.GetGravityDirection();
			float gravityAmount = Mathf.Clamp01(Vector3.Dot(a_Arg.ImpactNormal, gravityDirection));
			Vector3 gravityToAdd = gravityDirection * (a_Arg.Source.GetGravityStrength() * gravityAmount * a_Arg.TimeUntilCollision);
			a_Arg.Source.AddVelocity(-(a_Arg.VelocityLostInCollision + gravityToAdd));
		}
	}
}

This code sample shows a portion of the UI Button class used in this project. The UI elements are setup in such a way that widgets and screens can easily be created via the use of the default Unity UI tools introduced in version 4.6, while also providing clean and simple access in the codebase.
namespace UserInterface.Elements
{
	[RequireComponent(typeof(EventHandler))]
	public class UIButton: UISelectable
	{
		private enum EButtonState
		{
			Normal,
			Highlighted,
			Pressed
		}

		public delegate void OnButtonPressedHandler();

		[SerializeField]
		private Graphic m_TargetGraphic = null;
		[SerializeField]
		private EPaletteType m_Palette = EPaletteType.Normal;
		[SerializeField]
		private EAudioPaletteType m_AudioPalette = EAudioPaletteType.Default;

		private EButtonState m_ButtonState;
		private OnButtonPressedHandler m_OnPressedHandler = null;

		protected override void Awake()
		{
			base.Awake();
			EventHandler.RegisterEventHandler<UIInputActionEventMessage>(OnInputAction);
		}

		private void OnInputAction(UIInputActionEventMessage a_Arg)
		{
			if (a_Arg.ActionType == InputSystem.EInputAction.UIPointerButton)
			{
				if (a_Arg.ActionData.ActionState == InputSystem.EActionState.Pressed)
				{
					OnPointerDown();
				}
				else if (a_Arg.ActionData.ActionState == InputSystem.EActionState.Released)
				{
					OnPointerUp();
				}
				a_Arg.IsHandled = true;
			}
		}

		public void SetSelectedHandler(OnButtonPressedHandler a_Handler)
		{
			m_OnPressedHandler = a_Handler;
        }

		public override void OnPointerEnter(UIPointerMoveMessage a_Message)
		{
			base.OnPointerEnter(a_Message);
			TransitionToState(EButtonState.Highlighted);
		}

		public override void OnPointerExit(UIPointerMoveMessage a_Message)
		{
			base.OnPointerExit(a_Message);
			TransitionToState(EButtonState.Normal);
		}

		[...]
	}
}



Back to Projects