User Tag List

Results 1 to 2 of 2

Thread: Orbit Diver (Movement pattern for boss)

  1. #1
    Wizrobe C-Dawg's Avatar
    Join Date
    Jan 2002
    Posts
    4,205
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    vBActivity - Stats
    Points
    6,611
    Level
    24
    vBActivity - Bars
    Lv. Percent
    99.9%

    Orbit Diver (Movement pattern for boss)

    Here's a slightly more complicated movement pattern. In practice, the enemy seems to jump around in a quasi-random way. What it's really doing is following an ideal (x,y) in orbit around the player, dodging away from player attacks, and swiping in for an attack periodically.

    Shout goes out to Jman who debugged this one. I changed his resulting script a little bit, based on the following observation:

    You need to guard against your custom boss movement scripts going off the edge of the screen. If they go off to far, the FFC will dissapear. It turns out to be easier to keep things on the screen if you only modify velocity, not actual position. Where I can't do that here, I've tried to guard against going off the screen anyway.

    NOTE: This code is not written with this_ffc, but with this->. So wherever you stick it, it will currently affect the first ffc.

    Code:
    // ========================================
    // orbit_diver - This FFC script makes the FFC behave as an
    // orbit diver.  At rest, the FFC will orbit the player at a certain
    // distance.  If the player attacks, the FFC distance of the
    // orbit will double for a short period of time, then it will 
    // immediately counterattck.  At regular
    // intervals, the FFC will dive towards the player and then return
    // to it's circular path.
    //
    // D0 - Speed of the orbit diver's normal behavior.  Must be
    // between 0 and about 6.28 for proper behavior.
    // D1 - Speed of the orbit diver's attack
    // D2 - Radius of the orbit diver's normal behavior
    // D3 - Delay between orbit diver's diving attack.  Make it longer
    // than 30, because that's how long the attack will last.
    // D4 - The time the orbit diver spends in a larger orbit after an attack
    // =======================================
    
    ffc script orbit_diver{
    
    	void run(int orbit_speed, int diving_speed, int radius, int delay, int dodge_time) {
    
    		int state = 0;	// 0 = At rest, not dodging
    				// 1 = Dodging away from player attack
    				// 2 = Diving towards player
    
    		int i = 0;	// Used to keep track of the
    		int orbit_x;	// orbit of the ffc.
    		int orbit_y;
    		int orig_radius = radius;
    
    		int delay_counter = delay;		// Countdown to attack
    
    		int dodge_counter = dodge_time;		// Countdown to dodging
    
    		int dive_counter = 30;			// Duration of attack
    		
    		bool ontrack = true;
    
    		// We need to scale 
    
    		while(true) {
    
    			// First, calculate the idea orbit of this ffc and put it into orbit_x, orbit_y
    
    			orbit_x = ((Sin(i)*radius) + Link->X+8)-(this->EffectWidth/2);
    			orbit_y = ((Cos(i)*radius) + Link->Y+8)-(this->EffectWidth/2);
    			
    			// Next, increase the value of i for the next loop.
    
    			i  = i + orbit_speed;
    
    			// ============= State 0 Behavior ==============
    
    			if (state == 0) {
    			
    				// The FFC should get close to the ideal orbit (kept track of
    				// by orbit_x, orbit_y) if it is not already.
    		
    				if(!ontrack)
    				{
    				 	if (  ((this->X - orbit_x) > diving_speed) || ((this->X - orbit_x) < -diving_speed) ||
    					((this->Y - orbit_y) > diving_speed) || ((this->Y - orbit_y) < -diving_speed)  )
    					{
    
    						if (this->X >= orbit_x) 
    						{ 
    							this->Vx = -diving_speed; 
    						}
    						else 
    						{ 
    							this->Vx = diving_speed; 
    						}
    	
    						if (this->Y >= orbit_y) 
    						{ 
    							this->Vy = -diving_speed; 
    						}
    						else 
    						{ 
    							this->Vy = diving_speed; 
    						}
    					}
    					else
    					{
    						ontrack=true;
    					}
    				}
    
    				// If the FFC is already close to the ideal orbit, just follow it around.
    	
    				else{
    
    					if(orbit_x > 248) { this->X = 248; }
    					else{
    						if(orbit_x < 0) { this->X = 0; }
    						else {this->X = orbit_x;}
    					}
    
    					if(orbit_y > 168) { this->Y = 168; }
    					else{
    						if(orbit_y < 0) { this->Y = 0; }
    						else {this->Y = orbit_y;}
    					}
    				}
    
    				// Countdown to diving attack
    
    				if (delay_counter <= 0){
    
    					state = 2;
    					dive_counter = 30;
    					delay_counter = delay;
    				}
    				else{
    					delay_counter--;
    				}
    
    				// Detect whether the player is attacking or using an item
    				if ( (Link->InputB) || (Link->InputA)){
    			
    					state = 1;	
    				}
    
    			} // end of state 0
    
    			// ============= State 1 Behavior ==============
    			if ( state == 1 ) {
    
    				// Increase the radius incrementally until it reaches double the radius;
    				if(radius >= orig_radius*2) { radius = orig_radius*2; }
    				else { radius += 1; }
    
    				// The FFC should get close to the ideal orbit (kept track of
    				// by orbit_x2, orbit_y2) if it is not already.
    				
    				if(!ontrack)
    				{
    					if (  ((this->X - orbit_x) > orbit_speed) || ((this->X - orbit_x) < -orbit_speed) ||
    					((this->Y - orbit_y) > orbit_speed) || ((this->Y - orbit_y) < -orbit_speed)  ){
    
    						if (this->X >= orbit_x) { this->X -= diving_speed; }
    						else { this->X += diving_speed; }
    	
    						if (this->Y >= orbit_y) { this->Y -= diving_speed; }
    						else { this->Y += diving_speed; }
    					} 
    					else
    					{
    						ontrack=true;
    					}
    				}
    
    				// If the FFC is already close to the ideal orbit, just follow it around.
    				else{
    
    					this->X = orbit_x;
    					this->Y = orbit_y;
    				}
    
    				// Countdown to diving attack
    				if (delay_counter <= 0){
    
    					state = 2;
    					dive_counter = 30;
    					delay_counter = delay;
    				}
    				else{
    					delay_counter--;
    				}
    
    				// Countdown to counterattack
    				if (dodge_counter <= 0){
    					state = 2;
    					dive_counter = 30;
    					dodge_counter = dodge_time;
    				}
    				else{
    					dodge_counter--;
    				}
    			} // end of state 1
    
    			// ============= State 2 Behavior ==============
    			if (state == 2) {
    
    				if (this->X <= Link->X){
    					this->Vx = this->Vx + (diving_speed/10);
    					if ( this->Vx > diving_speed ) { this->Vx = diving_speed; }
    				}
    				else{
    					this->Vx = this->Vx - (diving_speed/10);
    					if ( this->Vx < -diving_speed ) { this->Vx = -diving_speed; }
    				}
    
    				if (this->Y <= Link->Y){
    					this->Vy = this->Vy + (diving_speed/10);
    					if ( this->Vy > diving_speed ) { this->Vy = diving_speed; }
    				}
    				else{
    					this->Vy = this->Vy - (diving_speed/10);
    					if ( this->Vy < -diving_speed ) { this->Vy = -diving_speed; }
    				}
    
    				// Duration of attack
    				if (dive_counter <= 0){
    					state = 0;
    					this->Vx = 0;
    					this->Vy = 0;
    					ontrack = false;
    					delay_counter = delay;
    					dodge_counter = dodge_time;
    					radius = orig_radius;
    				}
    				else{
    					dive_counter--;
    				}
    
    			} //end of state 2 
    
    			// Edgeguard function
    
    			if(this->X > 248) { this->Vx = -1; }
    			if(this->X < 0) { this->Vx = 1; }
    
    			if(this->Y > 168) { this->Vy = -1; }
    			if(this->Y < 0) { this->Vy = 1; }
    
    
    			Waitframe();
    		} // end of while loop
    	} // end of void run
    } // end of ffc script

  2. #2
    The Time-Loop Continues ZC Developer
    Gleeok's Avatar
    Join Date
    Apr 2007
    Posts
    4,826
    Mentioned
    259 Post(s)
    Tagged
    10 Thread(s)
    vBActivity - Stats
    Points
    12,959
    Level
    33
    vBActivity - Bars
    Lv. Percent
    26.21%

    Re: Orbit Diver (Movement pattern for boss)

    First reply...that's hard to believe. Anyway, I would like to register a bug. While playing Zodiac, the orbit diver will zip off screen if the player "lures it" to the edge. Also messing with the speed variables causes it to instantly fly off screen, while lowering them a tad, messes up the orbit or general movement....I could of erred somehow though... Sweet script otherwise.
    This post contains the official Gleeok seal of approval. Look for these and other posts in an area near you.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
About us
Armageddon Games is a game development group founded in 1997. We are extremely passionate about our work and our inspirations are mostly drawn from games of the 8-bit and 16-bit era.
Social