/// <summary> /// Spawn a new group at a random location. /// </summary> public GroupCrystallonEntity spawn(AbstractCrystallonEntity[] pMembers) { var _screenWidth = Director.Instance.GL.Context.GetViewport().Width; var _screenHeight = Director.Instance.GL.Context.GetViewport().Height; return spawn( 50f + 0.75f * _screenWidth * GameScene.Random.NextFloat(), 50f + 0.75f * _screenHeight * GameScene.Random.NextFloat(), pMembers); }
/// <summary> /// Spawn a new group the specified pX and pY. /// </summary> /// <param name='pX'> /// X coordinate /// </param> /// <param name='pY'> /// Y coordinate /// </param> public GroupCrystallonEntity spawn( float pX, float pY, AbstractCrystallonEntity[] pMembers, bool pComplete = false ) { GroupCrystallonEntity g; if (pComplete) { g = new CubeCrystallonEntity(_scene, _physics, null); } else { g = new GroupCrystallonEntity(_scene, _physics, null, SelectionGroup.MAX_CAPACITY, pComplete); } foreach (AbstractCrystallonEntity e in pMembers) { g.Add(e); } g.id = NextId; NextId += 1; g.setPosition( pX, pY ); g.BeReleased(g.getPosition()); EventHandler handler = GroupSpawned; if (handler != null) { handler( this, null ); } return g; // g.addToScene(); // return Add(g); }
/// <summary> /// Called we're only releasing a single entity. /// </summary> /// <returns> /// The CardCrystallonEntity /// </returns> protected virtual AbstractCrystallonEntity ReleaseSingle( AbstractCrystallonEntity pEntity ) { Remove( pEntity ); return pEntity.BeReleased( this.getPosition() ); }
/// <summary> /// If an entity has a fixed orientation, this tells us what it is. If not, it just tells us what orientation to use. /// </summary> /// <returns> /// <c>int</c> The orientation index. /// </returns> /// <param name='pEntity'> /// <see cref="Crystallography.AbstractCrystallonEntity"/> /// </param> private int GetOrientationIndex( AbstractCrystallonEntity pEntity ) { if (!AppMain.ORIENTATION_MATTERS) { return population; } if ( pEntity is GroupCrystallonEntity ) { if ( (pEntity as GroupCrystallonEntity).complete) { return population; } } int orientation = ( pEntity as SpriteTileCrystallonEntity ).getOrientation(); int attachPosition = -1; attachPosition = orientation; return attachPosition; }
public override void PostAttach( AbstractCrystallonEntity pEntity ) { pEntity.BeSelected( InputManager.MAX_PRESS_DURATION ); EaseOut(); selectionDelay = MAX_SELECTION_DELAY; }
/// <summary> /// Release an entity from the Group. /// </summary> public virtual AbstractCrystallonEntity Release( AbstractCrystallonEntity e, bool pForceBreak = false) { if ( e is SpriteTileCrystallonEntity ) { return ReleaseSingle (e as SpriteTileCrystallonEntity ); } else if ( e is CubeCrystallonEntity ) { return ReleaseSingle( e as CubeCrystallonEntity ); } else { return null; } }
/// <summary> /// Actually reparent a single entity to this group. /// </summary> /// <param name='pEntity'> /// <see cref="Crystallography.AbstractCrystallonEntity"/> /// </param> public void Attach( AbstractCrystallonEntity pEntity ) { IncreaseSlots( 1 ); members[GetFreeSlot()] = pEntity; //create a child-node, give it a positional offset, make pEntity a child of child-node int index = GetOrientationIndex( pEntity ); if ( _pucks[index] == null ) { AddPuck(index); } Node puck = _pucks[index]; pEntity.attachTo(puck); pEntity.getNode().Position *= 0; if ( !AppMain.ORIENTATION_MATTERS ) { if ((pEntity is CubeCrystallonEntity) == false ) { QualityManager.Instance.SetQuality( pEntity, "QOrientation", index ); } } _numMembers++; }
// METHODS --------------------------------------------------------------------------------------------------- /// <summary> /// Add an entity to <c>qualityDict</c> /// </summary> /// <param name='pEntity'> /// <see cref="Crystallography.AbstractCrystallonEntity"/> /// </param> /// <param name='pQualityName'> /// <c>string</c> Class name for this quality. /// </param> /// <param name='pVariant'> /// <c>int</c> Index of the variant. Probs 0, 1, or 2. /// </param> private void Add( AbstractCrystallonEntity pEntity, string pQualityName, int pVariant ) { if (qualityDict[pQualityName][pVariant] == null) { qualityDict[pQualityName][pVariant] = new List<int>(); } qualityDict[pQualityName][pVariant].Add( pEntity.id ); }
/// <summary> /// Handles <c>InputManager.TouchDownDetected</c>. /// </summary> /// <param name='sender'> /// InputManager instance /// </param> /// <param name='e'> /// <see cref="Crystallography.InputManager.BaseTouchEventArgs"/> /// </param> void HandleInputManagerInstanceTouchDownDetected(object sender, SustainedTouchEventArgs e) { // NO TOUCHING PIECES WHEN GAME IS PAUSED if ( GameScene.paused ) return; // NO TOUCHING PIECES WHEN LEVEL IS OVER if ( GameScene.Hud.MetGoalTime != 0.0f) return; setPosition( e.touchPosition ); if (velocity < MAXIMUM_PICKUP_VELOCITY) { if ( InputManager.dragging ) { // ----------------------------------- LOOK FOR ENTITIES THE PLAYER MIGHT BE TRYING TO TOUCH // TEST FINGER POSITION var entity = GetEntityAtPosition( e.touchPosition ); if (justDownPositionEntity != null) { // ------------------------ EDGE CASE: PLAYER TOUCHED DOWN ON A PIECE, BUT DRAGGED OFF OF IT if (justDownPositionEntity != entity ) { // ----------------- BEFORE WE ADDED IT TO THE SELECTION GROUP. if (entity == null) { entity = justDownPositionEntity; // ----------------- COMMON: PLAYER IS TOUCHING EMPTY SPACE; RESOLVE IT BELOW } } justDownPositionEntity = null; } if ( entity == null && velocity < 100.0f && population != 0) { // TRY THE PICK UP POSITIONS FOR THE PIECE THE PLAYER ALREADY HAS if (_pucks[(int)POSITIONS.TOP].Children.Count != 0) { entity = GetEntityAtPosition( getNode().LocalToWorld(UP_LEFT_SELECTION_POINT), POSITIONS.LEFT); if (entity == null) { entity = GetEntityAtPosition( getNode().LocalToWorld(UP_RIGHT_SELECTION_POINT), POSITIONS.RIGHT); } } if ( entity == null && _pucks[(int)POSITIONS.LEFT].Children.Count != 0) { entity = GetEntityAtPosition( getNode().LocalToWorld(LEFT_UP_SELECTION_POINT), POSITIONS.TOP); } if ( entity == null && _pucks[(int)POSITIONS.RIGHT].Children.Count != 0){ entity = GetEntityAtPosition( getNode().LocalToWorld(RIGHT_UP_SELECTION_POINT), POSITIONS.TOP); } } if (entity != null) { if ( selectionDelay == 0.0f) { Add (entity); } } lastEntityTouched = entity; } } }
/// <summary> /// Handles <c>InputManager.TouchJustDownDetected</c>. /// </summary> /// <param name='sender'> /// Input Manager instance /// </param> /// <param name='e'> /// <see cref="Crystallography.InputManager.BaseTouchEventArgs"/> /// </param> void HandleInputManagerInstanceTouchJustDownDetected(object sender, BaseTouchEventArgs e) { if ( GameScene.paused ) return; if ( GameScene.Hud.MetGoalTime != 0.0f) return; setPosition( e.touchPosition ); lastEntityTouched = justDownPositionEntity = GetEntityAtPosition( e.touchPosition ) as AbstractCrystallonEntity; AddParticle(0.0f); Scheduler.Instance.Schedule(this.getNode(), AddParticle, 0.1f, false, 1); if ( lastEntityTouched is CardCrystallonEntity ) { Add ( lastEntityTouched ); justDownPositionEntity = null; } }
/// <summary> /// Reset the SelectionGroup /// </summary> /// <param name='pScene'> /// Instance of the scene to be a part of after resetting. /// </param> public void Reset( Scene pScene ) { RemoveAll(); MemberType = null; if (lastPosition != null) { lastPosition.Clear(); } else { lastPosition = new List<Vector2>(); } if (selectionPoints != null) { selectionPoints.Clear(); } else { selectionPoints = new List<Vector2>(); } lastPosition.Add( getPosition() ); heading = Vector2.Zero; lastEntityReleased = null; lastEntityTouched = null; justDownPositionEntity = null; _scene = pScene; easeState = EaseState.IN; selectionDelay = 0.0f; // NEED TO RESET THESE IN CASE PLAYER ADJUSTED EASE DISTANCE IN OPTIONS MENU UP_OFFSET = new Vector2(0.5f, 30.0f+EASE_DISTANCE); LEFT_OFFSET = new Vector2(-EASE_DISTANCE-35.0f, 17.5f); RIGHT_OFFSET = new Vector2(EASE_DISTANCE+35.0f, 17.5f); UP_LEFT_SELECTION_POINT = new Vector2(-39.5f, 10.0f+EASE_DISTANCE); UP_RIGHT_SELECTION_POINT = new Vector2(40.5f, 10.0f+EASE_DISTANCE); LEFT_UP_SELECTION_POINT = new Vector2(-EASE_DISTANCE-20, 55.5f); RIGHT_UP_SELECTION_POINT = new Vector2(EASE_DISTANCE+20, 55.5f); }
/// <summary> /// Release the currently selected ICrystallonEntity from the SelectionGroup. /// </summary> // public ICrystallonEntity Release () { public override AbstractCrystallonEntity Release( AbstractCrystallonEntity e, bool pForceBreak = false ) { AbstractCrystallonEntity entity = e; if (pForceBreak) { lastEntityReleased = null; if (entity is GroupCrystallonEntity) { this.Break (); return entity; } return ReleaseSingle ( entity ); } else if (population == 1) { entity = members[0]; return lastEntityReleased = ReleaseSingle ( entity ); } bool isComplete = false; if ( !pForceBreak ) { // --------------------------- don't bother testing completeness if Break forced if ( population == MAX_CAPACITY ) { // -------------------------------------------------------- EVALUATE CUBES! if (QualityManager.Instance.CheckForMatch( this, true ) ) { GroupComplete(); isComplete = true; } else { GroupFailed(); return null; } } } if ( entity is NodeCrystallonEntity ) { return lastEntityReleased = ReleaseGroup ( isComplete, pForceBreak ); } return lastEntityReleased = null; }
public void Pull(AbstractCrystallonEntity pEntity) { var dir = getPosition() - pEntity.getPosition(); pEntity.addImpulse(0.03f * dir.Normalize() * GamePhysics.PtoM ); }
/// <summary> /// Removes an entity from all qualities in <c>qualityDict</c> /// </summary> /// <param name='pEntity'> /// The Entity /// </param> public void RemoveAll( AbstractCrystallonEntity pEntity ) { var allQualities = qualityDict.Keys.ToList(); foreach( var quality in allQualities ) { Remove (pEntity, quality); } }
public bool CheckMemberTypeCompatability( AbstractCrystallonEntity pEntity ) { // NO CURRENT MEMBER TYPE if (MemberType == null) { if ( typeof(GroupCrystallonEntity).IsAssignableFrom(pEntity.GetType()) ) { // ------- HANDLE GROUP-TYPE OBJECTS MemberType = (pEntity as GroupCrystallonEntity).MemberType; } else if ( typeof(CardCrystallonEntity).IsAssignableFrom(pEntity.GetType()) ) { // - HANDLE CARD-TYPE OBJECTS MemberType = typeof(CardCrystallonEntity); } } else { Type t = null; if ( typeof(GroupCrystallonEntity).IsAssignableFrom(pEntity.GetType()) ) { // ------- HANDLE GROUP-TYPE OBJECTS t = (pEntity as GroupCrystallonEntity).MemberType; } else if ( typeof(CardCrystallonEntity).IsAssignableFrom(pEntity.GetType()) ) { // - HANDLE CARD-TYPE OBJECTS t = typeof(CardCrystallonEntity); } return this.MemberType.IsAssignableFrom(t); } return true; }
/// <summary> /// Apply a particular variant of a particular quality to an entity. Also removes a previous variant of that quality, if it exists. /// </summary> /// <param name='pEntity'> /// <see cref="Crystallography.AbstractCrystallonEntity"/> /// </param> /// <param name='pQualityName'> /// <c>string</c> Class name for this quality. Must start with a capitol Q. /// </param> /// <param name='pVariant'> /// <c>int</c> Index of the variant. Probs 0, 1, or 2. /// </param> public void SetQuality( AbstractCrystallonEntity pEntity, string pQualityName, int pVariant ) { var type = Type.GetType( "Crystallography." + pQualityName ); var quality = (IQuality)type.GetProperty("Instance").GetValue(null, null); Remove( pEntity, pQualityName ); Add( pEntity, pQualityName, pVariant ); quality.Apply( pEntity, pVariant ); }
/// <summary> /// This is primarily used for positioning the group's pucks /// </summary> /// <param name='pEntity'> /// P entity. /// </param> public virtual void PostAttach( AbstractCrystallonEntity pEntity ) { if ( population > 1 ) { foreach( AbstractCrystallonEntity e in members ) { if( e != null) { int puckIndex = Array.IndexOf(_pucks, e.getNode().Parent); _pucks[puckIndex].Position = e.getAttachOffset( puckIndex ); } } } else { // JUST CENTER THE OBJECT IF THERE'S ONLY ONE. foreach (var puck in _pucks) { puck.Position *= 0; } } }
/// <summary> /// Remove an entity from <c>qualityDict</c> /// </summary> /// <param name='pEntity'> /// <see cref="Crystallography.AbstractCrystallonEntity"/> /// </param> /// <param name='pQualityName'> /// <c>string</c> Class name for this quality. /// </param> private void Remove( AbstractCrystallonEntity pEntity, string pQualityName ) { foreach ( List<int> list in qualityDict[pQualityName] ) { if ( list == null ) { continue; } if( list.Remove(pEntity.id) ) { return; } } }
public void Destroy() { InputManager.Instance.DoubleTapDetected -= HandleInputManagerInstanceDoubleTapDetected; InputManager.Instance.TouchJustDownDetected -= HandleInputManagerInstanceTouchJustDownDetected; InputManager.Instance.TouchJustUpDetected -= HandleInputManagerInstanceTouchJustUpDetected; InputManager.Instance.TouchDownDetected -= HandleInputManagerInstanceTouchDownDetected; InputManager.Instance.DragDetected -= HandleInputManagerInstanceDragDetected; InputManager.Instance.TapDetected -= HandleInputManagerInstanceTapDetected; RemoveAll(); this.removeFromScene(true); _instance = null; lastPosition.Clear(); lastPosition = null; _scene = null; lastEntityReleased = null; lastEntityTouched = null; justDownPositionEntity = null; }