~eda-qa/dhlib/main

« back to all changes in this revision

Viewing changes to app-squix/squix/PlayerCursor.hx

  • Committer: edA-qa mort-ora-y
  • Date: 2010-02-16 05:36:32 UTC
  • Revision ID: eda-qa@disemia.com-20100216053632-60lt7fndfi3fgblw
first

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* <license>
 
2
 * This file is part of the dis-Emi-A HaXe Library. Copyright (c) edA-qa mort-ora-y
 
3
 * For full copyright and license information please refer to doc/license.txt.
 
4
 * </license> 
 
5
 */
 
6
package squix;
 
7
 
 
8
import mathx.Point2;
 
9
import squix.CursorActor;
 
10
 
 
11
class PlayerCursor extends CorePanelObject
 
12
{
 
13
        var speed : Float;
 
14
        var speedFactor : Float;
 
15
        var speedTime : Float;
 
16
        
 
17
        public function new( game : Game )
 
18
        {       
 
19
                super( 
 
20
                        game, 
 
21
                        new CursorActor( { marqueeSpeed: 2 } ), 
 
22
                        game.global.cursorSize 
 
23
                        );
 
24
                game.cursor = this;
 
25
                
 
26
                place( Point2.at( game.surface.width /2, game.surface.height ) );
 
27
                if( game.cursorStartOnEdge )
 
28
                        place( game.surface.findNearestEdge( sAt.roundDemote() ).promoteF() );
 
29
                alive = false;
 
30
                actor.actorSetSequence( CursorActor.seq.Create, ui.Action.bind( setAlive ) );
 
31
                                
 
32
                speed = game.global.cursorSpeed;
 
33
                speedFactor = 1;
 
34
                
 
35
                game.addEventListener( GameEvent.CursorDie, onCursorDie );
 
36
                game.addEventListener( GameEvent.BonusCollected, onBonusCollected );
 
37
        }
 
38
        
 
39
        /**
 
40
         * Determines whether this cursor is in a "usable" state, that is, it
 
41
         * is alive and can be regarded as a true cursor.  Introduced so that
 
42
         * the TraceSelector would not use a cursor which is being created
 
43
         * or dying.
 
44
         */
 
45
        public function isUsable() : Bool
 
46
        {
 
47
                return alive;
 
48
        }
 
49
        
 
50
        public function getSpeed() : Float
 
51
        {
 
52
                return speed * speedFactor;
 
53
        }
 
54
        
 
55
        override function onBonusCollected( ge : GameEvent )
 
56
        {
 
57
                switch( ge.bonus )
 
58
                {
 
59
                        case CursorSpeedUp:
 
60
                                speedFactor = game.global.cursorSpeedUpFactor;
 
61
                                speedTime = game.global.cursorSpeedRecoverTime;
 
62
                                actor.actorSetTrait1( CursorActor.trait.Marquee.Speed, 4 );
 
63
                        case CursorSpeedDown:
 
64
                                speedFactor = game.global.cursorSpeedDownFactor;
 
65
                                speedTime = game.global.cursorSpeedRecoverTime;
 
66
                                actor.actorSetTrait1( CursorActor.trait.Marquee.Speed, 0.5);
 
67
                        case MonsterFreeze:
 
68
                                //not for us
 
69
                }
 
70
        }
 
71
        
 
72
        var invincibleTime : Float;
 
73
        function setAlive() 
 
74
        {
 
75
                alive = true;
 
76
                
 
77
                //check if near enemies...
 
78
                if( game.isCursorNearEdgeKiller() )
 
79
                {
 
80
                        invincibleTime = game.global.cursorInvincibleTime;
 
81
                        actor.actorSetTrait( CursorActor.trait.Invincible.On );
 
82
                }
 
83
                else
 
84
                        invincibleTime = 0;
 
85
        }
 
86
        
 
87
        override function _stepTime( elapsed : Float )
 
88
        {
 
89
                //only move in normal sequence mode
 
90
                if( !alive )
 
91
                        return;
 
92
                        
 
93
                //check for end of speedFactor
 
94
                if( speedTime > 0 ) 
 
95
                {
 
96
                        speedTime -= elapsed;
 
97
                        if( speedTime <= 0 )
 
98
                        {
 
99
                                speedFactor = 1;
 
100
                                actor.actorSetTrait1( CursorActor.trait.Marquee.Speed, 2 );
 
101
                        }
 
102
                }
 
103
                
 
104
                //check for turning off invincible
 
105
                if( invincibleTime > 0)
 
106
                {
 
107
                        invincibleTime -= elapsed;
 
108
                        if( invincibleTime <= 0 )
 
109
                                actor.actorSetTrait( CursorActor.trait.Invincible.Off );
 
110
                }
 
111
                
 
112
                if( game.cursorPhase == CursorPhase.Edge )
 
113
                        actor.actorSetTrait( CursorActor.trait.Mode.Edge );
 
114
                else if( game.cursorPhase == CursorPhase.Select )
 
115
                        actor.actorSetTrait( CursorActor.trait.Mode.Select );
 
116
                        
 
117
                if( game.cursorPhase != CursorPhase.Fill
 
118
                        && (!game.lockCursorOnSelector  || game.cursorPhase == CursorPhase.Edge ) )
 
119
                        moveCursor( elapsed );
 
120
        }
 
121
        
 
122
        function moveCursor( elapsed : Float )
 
123
        {                       
 
124
                //Same basic structure as in TraceSelector
 
125
                var pos = targetCursorPos();
 
126
                var dirs = game.surface.getCursorDirections( sAt );
 
127
                var cdir = GridUtil.pointClosest( pos, dirs, game.allowCursorJitter ? null : sAt );
 
128
                
 
129
                //if none then we'll just drift to where we need to be
 
130
                var cnext;
 
131
                if( cdir == null )
 
132
                {
 
133
                        //TODO: if dirs.length != 0, then check one more step to see which direction would lead us
 
134
                        //closed to the cursor (less sticky movement then (one-blocks don't halt the cursor then)
 
135
                        
 
136
                        if( dirs.length !=0 )   //only if there was really *no* choice (as there might be two options, neither of which are closer to the mouse)
 
137
                                return;
 
138
                        if( game.surface.isCovered( sAt.floorDemote() ) )       //only while in open area, should be locked when not... (shouldn't happen)
 
139
                        {
 
140
                                //snap to nearest intersection (to keep valid state)
 
141
                                place( sAt.round() ); //TODO: snap to x or y bound only!
 
142
                                return;
 
143
                        }
 
144
                                
 
145
                        //otherwise move towards destination (TODO: max move into new cell, use div 2 now to come close...)
 
146
                        //TODO: max the actual distance to mouse as well, otherwise jitters
 
147
                        cnext = sAt.unitVectorTo( pos ).div(2).add( sAt );
 
148
                }
 
149
                else
 
150
                        cnext = cdir.mp;
 
151
                
 
152
                var step = GridUtil.excessStep( sAt, cnext, elapsed * getSpeed() );
 
153
                //prevent off-surface wandering (Due here to actually have some elapsed movement -- see plan defect)
 
154
                var next = step.next.constrain( Point2.at( 0, 0 ), Point2.at( game.surface.width, game.surface.height ) );
 
155
                place( next );
 
156
                if( step.excess > 0 )   //perhaps should use !isZero
 
157
                {
 
158
                        moveCursor( step.excess / getSpeed() );
 
159
                        return;
 
160
                }
 
161
        }
 
162
        
 
163
        override public function moveObject( smp : Point2 )
 
164
        {
 
165
                //assume location is valid.
 
166
                place( smp );
 
167
        }       
 
168
        
 
169
        function onCursorDie( ge : GameEvent )
 
170
        {
 
171
                alive = false;
 
172
                actor.actorSetSequence( CursorActor.seq.Destroy, ui.Action.bind( destroy ) );
 
173
                flashx.SoundManager.playSound( "playerDies" ); 
 
174
        }
 
175
        
 
176
        override function destroy()
 
177
        {
 
178
                super.destroy();
 
179
                
 
180
                game.cursor = null;
 
181
                game.removeEventListener( GameEvent.CursorDie, onCursorDie );
 
182
        }       
 
183
        
 
184
        override function onLevelOver( ge : GameEvent )
 
185
        {
 
186
                game.numLives++;        //we're returning to the player's lives remaining
 
187
                super.onLevelOver( ge );
 
188
        }       
 
189
        
 
190
        override public function getCorePanelCollisionObject( ) : flash.display.DisplayObject
 
191
        {
 
192
                if( !alive || invincibleTime > 0 )
 
193
                        return null;
 
194
                        
 
195
                return actor.getNative();
 
196
        }       
 
197
}