Jump to content

Photo

Making Things Move Around a Circle


  • Please log in to reply
3 replies to this topic

#1 C-Dawg

C-Dawg

    Magus

  • Members

Posted 24 June 2014 - 11:58 PM

So, I've been wrestling with this code all night.  I give up.  I have no idea what's going wrong.  The code is below.  The part that's driving me bonkers is that the bubbles, which are supposed to orbit in a neat line.. dont.  I want a gap the size of a quarter of the circle in the rotating shield of bubbles that cover the rest of a circle around the boss.  What actually happens is that all of the bubbles bunch up as if x = Cos(0) and y = Sin(0) all the time.  I have no idea why they're doing that.  They don't move, they don't get drawn spaced out... it just makes no... damn... sense!

// ==================================
// Fungal Orb - This code creates the Fungual Orb
// boss.  The Orb protects itself with rotating sheilds
// And sprays patterns of spores.  
// Orbits around the perimeter of the screen, so 
// sometimes it is below the player.
// D0 - The health of the boss, plus 100
// =================================
 
ffc script fungual_orb{
 
void run(int hit_points){
 
// setup
 
int wobble;
 
eweapon current_eweapon;
 
bool did_we_kill_bullets_yet = false;
 
npc ghosted_enemy = Screen->CreateNPC(85);
ghosted_enemy->HP = hit_points;
 
int state = 0;
int state_counter = 0;
int action_counter = 0;
 
this->Vx = -0.5;
 
ffc weapon_check;
 
// --------------------------
// Enemy Projectile Setup
// --------------------------
// We don't have arrays.  We only have 32 FFCs.  So to make 50+ projectiles,
// we make a bunch of enemies!
 
int first_projectile_enemy_number = Screen->NumNPCs() + 1;
int i;
npc current_enemy;
item end_boss;
int shot_pattern;
float bullet_loop = 0;
int attack_radius = 48;
 
float step = PI/8;
float current = 0;
 
for(i = first_projectile_enemy_number; i < first_projectile_enemy_number + 12; i++){
 
current_enemy = Screen->CreateNPC(51);
current_enemy->X = -16; // Hide ze enemy off the screen during setup
current_enemy->Y = -16;
 
}
 
// So now there are 12 baddies off the screen waiting patiently.
 
// Activity while alive
 
int starfield_scroll1 = 0;
int starfield_scroll2 = -176;
int current_background1 = 26260;
int current_background2 = 26260;
 
while(ghosted_enemy->HP>=100){
 
// -------------------------
// Scroll the starfield
// ------------------------
 
Screen->DrawTile(
1, // Layer
0, // X coordinate
starfield_scroll1, // Y coordinate
current_background1, // Tile 
16, // block of 16 tile wide
12, // block of one tile height
3, // CSet
-1, // XScale = 1
-1, // YScale = 1
0, // no rotation
0,  // no rotation
0, // no rotation angle
0, // no flip
true, // respect the transparent regions
128 // opaque
);
 
if(starfield_scroll1>=176){
starfield_scroll1=-176;
}
 
Screen->DrawTile(
1, // Layer
0, // X coordinate
starfield_scroll2, // Y coordinate
current_background2, // Tile 
16, // block of one tile wide
12, // block of one tile height
3, // CSet
-1, // XScale = 1
-1, // YScale = 1
0, // no rotation
0,  // no rotation
0, // no rotation angle
1, // no flip
true, // respect the transparent regions
128 // opaque
);
 
if(starfield_scroll2>=176){
starfield_scroll2=-176;
}
 
starfield_scroll1++;
starfield_scroll2++;
 
// --------------------------
// DRAW ENEMY LIFE BAR
// --------------------------
if(ghosted_enemy->HP > 100) {Life_Bar(ghosted_enemy);}
 
// --------------------------
// DRAW ENEMY 
// --------------------------
 
ghosted_enemy->X = this->X;
ghosted_enemy->Y = this->Y;
 
 
Screen->DrawTile(
2, // Layer
this->X-40, // X coordinate
this->Y-48, // Y coordinate
28600, // Tile 
6, // block of 16 tile wide
6, // block of 12 tile height
7, // CSet
-1, // XScale = 1
-1, // YScale = 1
0, // no rotation
0,  // no rotation
0, // no rotation angle
0, // no flip
true, // respect the transparent regions
128 // opaque
);
 
// -----------------------
// ENEMY BEHAVIOR
// -----------------------
 
 
// Shield enemies rotate during all phases
 
// We want the 12 dudes arranged around a circle with radius attack_radius, but with
// a gap.  So, divide the circle into 16 sections.  Move the starting point, bullet_loop,
// ahead by 0.2 each frame.  Then, starting at bullet loop, draw the 12 enemies each 
// spaced by PI/8, or 1/16, of total radians around the circle. 
 
current = 0;
 
for(i = first_projectile_enemy_number; i < first_projectile_enemy_number + 12; i++){
 
current_enemy = Screen->LoadNPC(i);
current_enemy->X = this->X + attack_radius*Sin( (current) + bullet_loop );
current_enemy->Y = this->Y + attack_radius*Cos( (current) + bullet_loop );
current_enemy->HP = 99999;
current = current + step;
 
} 
 
bullet_loop = bullet_loop + 0.02;
if(bullet_loop >= 2*PI) { bullet_loop = 0;}
 
 
// Wandering back and forth spraying bullets while sheild rotates.
if (state == 0){
 
if(this->X >= 212){this->Vx = -0.5;}
if(this->X <= 48){this->Vx = 0.5;}
 
this->Vy = Sin(wobble)/4;
wobble++;
 
if (this->Y <= 30){this->Y = 30;}
 
state_counter++;
 
if ( (state_counter == 40) ||
(state_counter == 80) ||
(state_counter == 120) ||
(state_counter == 160) ||
(state_counter == 200)
){
 
for(i = 0; i<=PI; i = i + PI/8){
current_eweapon = Screen->CreateEWeapon(129);
current_eweapon->X = this->X;
current_eweapon->Y = this->Y+16;
current_eweapon->OriginalTile = 26542;
current_eweapon->CSet = 7;
current_eweapon->NumFrames = 4;
current_eweapon->ASpeed = 4;
current_eweapon->Damage = 25;
current_eweapon->Angular = true;
current_eweapon->Angle = i;
current_eweapon->DeadState = -1; 
current_eweapon->Step = 200;
}
}
 
if ( state_counter >= 260){
 
state_counter = 0;
state = 1;
}
 
} // end of state 0
 
// Enemy shield expanding, wave pattern more severe.
if ( state == 1 ){
 
if(this->X >= 212){this->Vx = -0.5;}
if(this->X <= 48){this->Vx = 0.5;}
 
this->Vy = Sin(wobble)/2;
wobble++;
 
if (this->Y <= 30){this->Y = 30;}
 
if( state_counter <= 200 ){
attack_radius = attack_radius + state_counter/20;
}
if( (state_counter > 200) && (state_counter <= 400) ){
attack_radius = attack_radius - state_counter/20;
}
 
state_counter++;
 
if (state_counter >= 420){
state = 2;
state_counter = 0;
}
 
} // end of state 1
 
// Thick spray of bullets.
if (state == 2){
 
if(this->X >= 212){this->Vx = -0.5;}
if(this->X <= 48){this->Vx = 0.5;}
 
this->Vy = Sin(wobble)/4;
wobble++;
 
if (this->Y <= 30){this->Y = 30;}
 
state_counter++;
 
if ( (state_counter == 10) ||
(state_counter == 20)||
(state_counter == 30)||
(state_counter == 40)||
(state_counter == 50)||
(state_counter == 60)||
(state_counter == 70)||
(state_counter == 80)||
(state_counter == 90)||
(state_counter == 100)||
(state_counter == 110)||
(state_counter == 120)||
(state_counter == 130)||
(state_counter == 140)||
(state_counter == 150)
){
 
for(i = 0; i<=PI; i = i + PI/16){
current_eweapon = Screen->CreateEWeapon(129);
current_eweapon->X = this->X;
current_eweapon->Y = this->Y+16;
current_eweapon->OriginalTile = 26542;
current_eweapon->CSet = 7;
current_eweapon->NumFrames = 4;
current_eweapon->ASpeed = 4;
current_eweapon->Damage = 25;
current_eweapon->Angular = true;
current_eweapon->Angle = i;
current_eweapon->DeadState = -1; 
current_eweapon->Step = 100;
}
}
 
if ( state_counter >= 200){
 
state_counter = 0;
state = 0;
}
 
} // end of state 2
 
Waitframe();
 
} // end of alive loop
 
// Activity when defeated
 
while(ghosted_enemy->HP<100){
 
// -------------------------
// Scroll the starfield
// ------------------------
 
Screen->DrawTile(
1, // Layer
0, // X coordinate
starfield_scroll1, // Y coordinate
current_background1, // Tile 
16, // block of 16 tile wide
12, // block of one tile height
3, // CSet
-1, // XScale = 1
-1, // YScale = 1
0, // no rotation
0,  // no rotation
0, // no rotation angle
0, // no flip
true, // respect the transparent regions
128 // opaque
);
 
if(starfield_scroll1>=176){
starfield_scroll1=-176;
}
 
Screen->DrawTile(
1, // Layer
0, // X coordinate
starfield_scroll2, // Y coordinate
current_background2, // Tile 
16, // block of one tile wide
12, // block of one tile height
3, // CSet
-1, // XScale = 1
-1, // YScale = 1
0, // no rotation
0,  // no rotation
0, // no rotation angle
1, // no flip
true, // respect the transparent regions
128 // opaque
);
 
if(starfield_scroll2>=176){
starfield_scroll2=-176;
}
 
starfield_scroll1++;
starfield_scroll2++;
 
if(!did_we_kill_bullets_yet){
 
for(i = first_projectile_enemy_number; i <= first_projectile_enemy_number + 12; i++){
 
current_enemy = Screen->LoadNPC(i);
current_enemy->HP = 0;
}
 
did_we_kill_bullets_yet = true;
}
 
state = 20;
ghosted_enemy->X = -16;
ghosted_enemy->Y = -16;
ghosted_enemy->HP--;
wobble++;
 
Screen->Circle(3,this->X,this->Y,2*wobble,109,1,0,0,0,true,128);
Screen->Circle(3,this->X,this->Y,(64*Cos(wobble)),109,1,0,0,0,true,128);
 
Screen->Circle(3,this->X + Rand(48) - 24,this->Y + Rand(48) - 24,
8 + Rand(8),109,1,0,0,0,true,128);
 
if(ghosted_enemy->HP == 50) {Game->PlaySound(84);}
 
if((this->Data != 0) && (this->Data != 562) && (this->Data != 563)){
 
Game->PlaySound(84);
this->Data = 562;
this->Data = 562;
}
 
if (ghosted_enemy->HP < 2){  
 
Screen->TriggerSecrets(); 
}
 
Waitframe();
 
} // end of dead loop
 
} // end of void run
 
} //end of FFC script

Edited by C-Dawg, 25 June 2014 - 12:00 AM.


#2 Saffith

Saffith

    IPv7 user

  • Members

Posted 25 June 2014 - 12:38 AM

Sin and Cos take their arguments in degrees. You want RadianSin and RadianCos.

#3 C-Dawg

C-Dawg

    Magus

  • Members

Posted 25 June 2014 - 12:51 AM

Degrees?  I didn't even realize that was an option -- I'm used to Sin and Cos being strictly defined by their graphs, which have periods of 2 pi.  However -- let me implement this suggestion...

 

.. success!  Thank you, Saffith!


Edited by C-Dawg, 25 June 2014 - 12:54 AM.


#4 Saffith

Saffith

    IPv7 user

  • Members

Posted 25 June 2014 - 12:58 AM

ZScript's pretty arbitrary about that, unfortunately. weapon->Angle is in radians, and ArcTan, ArcSin, and ArcCos return radian values. Aside from those, I think everything that doesn't have "Radian" in its name uses degrees.


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users