Jump to content
A 2021 backup has been restored. Forums are closed and work in progress. Join our Discord server for more updates! ×
SoaH City Message Board

Emulating an Invincibility Trail


Recommended Posts

A fellow programmer and I have been hard at work on emulating the invincibility trail from Sonic 2. We've successfully been able to emulate the stars' rotation, and we can get the stars to trail behind Sonic as he moves, and they can move back to Sonic as he slows down. The only issues we've been experiencing are:

1) When Sonic is finished charging a spindash or peel-out, the stars immediately flare out instead of laggng behind from the place where Sonic was originally charging.

2) When Sonic is running through a loop, the trail of stars retains a horizontal trail instead of looping around with Sonic.

I'll post a picture of the events for you all to see:

invintrailevents-1.png

In Event 52, the sin and cos parts of each formula cause the stars to circle around Sonic, and the parts concerning his XSpeed and YSpeed allow each set of two circling stars to move a certain amount behind Sonic as he speeds up or slows down, hence the *6, *4, and *2 at the end of each formula. The greater that number is, the farther away the circling stars will move depending on Sonic's speed.

There must be a way to say "When Sonic is in a certain angle, move the stars' position about that angle" without messing with the stars' set rotation. As for getting the stars to lag when Sonic releases a spin dash or hits a spring, I don't know how to control that. We think that if we can say "When one set of two stars is a certain distance away from Sonic, start moving the other set away from Sonic," we can get it to work, but it's knowing that number that's got us puzzled.

Link to comment
Share on other sites

"2) When Sonic is running through a loop, the trail of stars retains a horizontal trail instead of looping around with Sonic"

You're probably basing the position off of the x and y speed. On slopes, the y speed of Sonic doesn't change, so to get the correct velocity, you need to use the Cosine of the X speed and the Sine of the Y speed multiplied by negative 1.

[ x = Cos(SpeedX); y = 0-Sin(SpeedX) ]

Link to comment
Share on other sites

Actually, the trailing effect is achieved by having a buffer of x,y positions for the centre of the rotating circle of stars. Each frame, the x and y position of the player is copied to the next buffer position.

Retro Sonic XG has the Sonic2/3 invincibility stars, I could post my script file for it, but you might have trouble reinterpreting it for mmf

Link to comment
Share on other sites

I think I understand what you mean. So, each set of stars records the last position of the player. That would actually make recalculating the positions easier instead of what we were doing with the positions to begin with.

Sure, you could post the script. It couldn't hurt to give it a shot, since programming languages have a couple things in common, anyway.

Link to comment
Share on other sites

That's cool and all, Streak, but that would work best for the Sonic 1 invincibility. Also, while your stars do follow positions well, they simply flash and fade away, while the ones I'm referring to trail behind Sonic the whole way and don't disappear until the invincibility is over. However, I thank you for helping out.

Link to comment
Share on other sites

Here's the script file for how it's done in Retro-Sonic XG... bear in mind it's using fixed point math instead of floats hence the bit shifting in areas. It might be a little complex though so sorry if it's no help :P



//---------Retro Sonic XG Invincibility Stars---------//
//----Scripted by Christian Whitehead "The Taxman"----//

//----Player Directions----//
#alias 1 : FACING_LEFT
#alias 0 : FACING_RIGHT

#alias Object.Value0 : Object.Angle1
#alias Object.Value1 : Object.Angle2

#alias Object.Value2 : Object.Stars1
#alias Object.Value3 : Object.Stars2
#alias Object.Value4 : Object.Stars3
#alias Object.Value5 : Object.Stars4

#alias Object.Value0 : StarPos0
#alias Object.Value1 : StarPos1
#alias Object.Value2 : StarPos2
#alias Object.Value3 : StarPos3
#alias Object.Value4 : StarPos4
#alias Object.Value5 : StarPos5
#alias Object.Value6 : StarPos6
#alias Object.Value7 : StarPos7

sub ObjectMain
if Object.State==0
//Set the Star Positions
ArrayPos0=1
StarPos7[+ArrayPos0]=Player.XPos
StarPos6[+ArrayPos0]=Player.XPos
StarPos5[+ArrayPos0]=Player.XPos
StarPos4[+ArrayPos0]=Player.XPos
StarPos3[+ArrayPos0]=Player.XPos
StarPos2[+ArrayPos0]=Player.XPos
StarPos1[+ArrayPos0]=Player.XPos
StarPos0[+ArrayPos0]=Player.XPos

ArrayPos0=2
StarPos7[+ArrayPos0]=Player.YPos
StarPos6[+ArrayPos0]=Player.YPos
StarPos5[+ArrayPos0]=Player.YPos
StarPos4[+ArrayPos0]=Player.YPos
StarPos3[+ArrayPos0]=Player.YPos
StarPos2[+ArrayPos0]=Player.YPos
StarPos1[+ArrayPos0]=Player.YPos
StarPos0[+ArrayPos0]=Player.YPos

Object.Angle1=180
Object.Angle2=0

Object.Stars4=20
Object.Stars3=0
Object.Stars2=32
Object.Stars1=44

Object.State=1
end if
end sub

sub ObjectDraw

//Update the Star Frames
Object.Stars4++
if Object.Stars4==26
Object.Stars4=20
end if

Object.Stars3++
if Object.Stars3==10
Object.Stars3=0
end if

Object.Stars2++
if Object.Stars2==38
Object.Stars2=32
end if

Object.Stars1++
if Object.Stars1==56
Object.Stars1=44
end if

//Update the Star Positions
ArrayPos0=1
StarPos7[+ArrayPos0]=StarPos6[+ArrayPos0]
StarPos6[+ArrayPos0]=StarPos5[+ArrayPos0]
StarPos5[+ArrayPos0]=StarPos4[+ArrayPos0]
StarPos4[+ArrayPos0]=StarPos3[+ArrayPos0]
StarPos3[+ArrayPos0]=StarPos2[+ArrayPos0]
StarPos2[+ArrayPos0]=StarPos1[+ArrayPos0]
StarPos1[+ArrayPos0]=StarPos0[+ArrayPos0]
StarPos0[+ArrayPos0]=Player.XPos

ArrayPos0=2
StarPos7[+ArrayPos0]=StarPos6[+ArrayPos0]
StarPos6[+ArrayPos0]=StarPos5[+ArrayPos0]
StarPos5[+ArrayPos0]=StarPos4[+ArrayPos0]
StarPos4[+ArrayPos0]=StarPos3[+ArrayPos0]
StarPos3[+ArrayPos0]=StarPos2[+ArrayPos0]
StarPos2[+ArrayPos0]=StarPos1[+ArrayPos0]
StarPos1[+ArrayPos0]=StarPos0[+ArrayPos0]
StarPos0[+ArrayPos0]=Player.YPos

if Player.Direction==FACING_RIGHT
Object.Angle1+=144
if Object.Angle1>511
Object.Angle1-=512
end if

Object.Angle2+=16
if Object.Angle2>511
Object.Angle2-=512
end if
else
Object.Angle1-=144
if Object.Angle1<0
Object.Angle1+=512
end if

Object.Angle2-=16
if Object.Angle2<0
Object.Angle2+=512
end if
end if

//Draw the 4th Pair of Stars
TempValue2=Object.Angle2
TempValue2+=116
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos7[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos7[+ArrayPos0]

DrawSpriteXY(Object.Stars4,TempValue0,TempValue1)

TempValue2=Object.Angle2
TempValue2+=372
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos7[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos7[+ArrayPos0]

TempValue2=Object.Stars4
TempValue2+=3
DrawSpriteXY(TempValue2,TempValue0,TempValue1)

//Draw the 3rd Pair of Stars
Cos(TempValue0,Object.Angle2)
Sin(TempValue1,Object.Angle2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos5[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos5[+ArrayPos0]

DrawSpriteXY(Object.Stars3,TempValue0,TempValue1)

TempValue2=Object.Angle2
TempValue2+=256
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos5[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos5[+ArrayPos0]

TempValue2=Object.Stars3
TempValue2+=5
DrawSpriteXY(TempValue2,TempValue0,TempValue1)

//Draw the 2nd Pair of Stars
TempValue2=Object.Angle2
TempValue2+=168
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos3[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos3[+ArrayPos0]

DrawSpriteXY(Object.Stars2,TempValue0,TempValue1)

TempValue2=Object.Angle2
TempValue2+=424
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos3[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos3[+ArrayPos0]

TempValue2=Object.Stars2
TempValue2+=3
DrawSpriteXY(TempValue2,TempValue0,TempValue1)

//Draw the 1st Pair of Stars
Cos(TempValue0,Object.Angle1)
Sin(TempValue1,Object.Angle1)
TempValue0<<=11
TempValue1<<=11

TempValue0+=Player.XPos
TempValue1+=Player.YPos

DrawSpriteXY(Object.Stars1,TempValue0,TempValue1)

TempValue2=Object.Angle1
TempValue2+=256
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

TempValue0+=Player.XPos
TempValue1+=Player.YPos

TempValue2=Object.Stars3
TempValue2+=5
DrawSpriteXY(Object.Stars1,TempValue0,TempValue1)

end sub

sub ObjectStartup

LoadSpriteSheet("Global/Items.gif")

//Invincibility Star Frames
SpriteFrame(0,0,1,1,118,304)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(0,0,1,1,118,304)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-1,-1,3,3,117,303)

//Frame 20
SpriteFrame(0,0,1,1,118,304)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(0,0,1,1,118,304)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-1,-1,3,3,117,303)

//Frame 32
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-7,-7,15,15,125,303)

//Frame 44
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)

end sub

sub RSDK
LoadSpriteSheet("Global/Items.gif")
SetEditorIcon(Icon0,SingleIcon,-15,-15,31,31,143,332)
end sub

[/CODE]

Link to comment
Share on other sites

Here's the script file for how it's done in Retro-Sonic XG... bear in mind it's using fixed point math instead of floats hence the bit shifting in areas. It might be a little complex though so sorry if it's no help :P



//---------Retro Sonic XG Invincibility Stars---------//
//----Scripted by Christian Whitehead "The Taxman"----//

//----Player Directions----//
#alias 1 : FACING_LEFT
#alias 0 : FACING_RIGHT

#alias Object.Value0 : Object.Angle1
#alias Object.Value1 : Object.Angle2

#alias Object.Value2 : Object.Stars1
#alias Object.Value3 : Object.Stars2
#alias Object.Value4 : Object.Stars3
#alias Object.Value5 : Object.Stars4

#alias Object.Value0 : StarPos0
#alias Object.Value1 : StarPos1
#alias Object.Value2 : StarPos2
#alias Object.Value3 : StarPos3
#alias Object.Value4 : StarPos4
#alias Object.Value5 : StarPos5
#alias Object.Value6 : StarPos6
#alias Object.Value7 : StarPos7

sub ObjectMain
if Object.State==0
//Set the Star Positions
ArrayPos0=1
StarPos7[+ArrayPos0]=Player.XPos
StarPos6[+ArrayPos0]=Player.XPos
StarPos5[+ArrayPos0]=Player.XPos
StarPos4[+ArrayPos0]=Player.XPos
StarPos3[+ArrayPos0]=Player.XPos
StarPos2[+ArrayPos0]=Player.XPos
StarPos1[+ArrayPos0]=Player.XPos
StarPos0[+ArrayPos0]=Player.XPos

ArrayPos0=2
StarPos7[+ArrayPos0]=Player.YPos
StarPos6[+ArrayPos0]=Player.YPos
StarPos5[+ArrayPos0]=Player.YPos
StarPos4[+ArrayPos0]=Player.YPos
StarPos3[+ArrayPos0]=Player.YPos
StarPos2[+ArrayPos0]=Player.YPos
StarPos1[+ArrayPos0]=Player.YPos
StarPos0[+ArrayPos0]=Player.YPos

Object.Angle1=180
Object.Angle2=0

Object.Stars4=20
Object.Stars3=0
Object.Stars2=32
Object.Stars1=44

Object.State=1
end if
end sub

sub ObjectDraw

//Update the Star Frames
Object.Stars4++
if Object.Stars4==26
Object.Stars4=20
end if

Object.Stars3++
if Object.Stars3==10
Object.Stars3=0
end if

Object.Stars2++
if Object.Stars2==38
Object.Stars2=32
end if

Object.Stars1++
if Object.Stars1==56
Object.Stars1=44
end if

//Update the Star Positions
ArrayPos0=1
StarPos7[+ArrayPos0]=StarPos6[+ArrayPos0]
StarPos6[+ArrayPos0]=StarPos5[+ArrayPos0]
StarPos5[+ArrayPos0]=StarPos4[+ArrayPos0]
StarPos4[+ArrayPos0]=StarPos3[+ArrayPos0]
StarPos3[+ArrayPos0]=StarPos2[+ArrayPos0]
StarPos2[+ArrayPos0]=StarPos1[+ArrayPos0]
StarPos1[+ArrayPos0]=StarPos0[+ArrayPos0]
StarPos0[+ArrayPos0]=Player.XPos

ArrayPos0=2
StarPos7[+ArrayPos0]=StarPos6[+ArrayPos0]
StarPos6[+ArrayPos0]=StarPos5[+ArrayPos0]
StarPos5[+ArrayPos0]=StarPos4[+ArrayPos0]
StarPos4[+ArrayPos0]=StarPos3[+ArrayPos0]
StarPos3[+ArrayPos0]=StarPos2[+ArrayPos0]
StarPos2[+ArrayPos0]=StarPos1[+ArrayPos0]
StarPos1[+ArrayPos0]=StarPos0[+ArrayPos0]
StarPos0[+ArrayPos0]=Player.YPos

if Player.Direction==FACING_RIGHT
Object.Angle1+=144
if Object.Angle1>511
Object.Angle1-=512
end if

Object.Angle2+=16
if Object.Angle2>511
Object.Angle2-=512
end if
else
Object.Angle1-=144
if Object.Angle1<0
Object.Angle1+=512
end if

Object.Angle2-=16
if Object.Angle2<0
Object.Angle2+=512
end if
end if

//Draw the 4th Pair of Stars
TempValue2=Object.Angle2
TempValue2+=116
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos7[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos7[+ArrayPos0]

DrawSpriteXY(Object.Stars4,TempValue0,TempValue1)

TempValue2=Object.Angle2
TempValue2+=372
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos7[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos7[+ArrayPos0]

TempValue2=Object.Stars4
TempValue2+=3
DrawSpriteXY(TempValue2,TempValue0,TempValue1)

//Draw the 3rd Pair of Stars
Cos(TempValue0,Object.Angle2)
Sin(TempValue1,Object.Angle2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos5[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos5[+ArrayPos0]

DrawSpriteXY(Object.Stars3,TempValue0,TempValue1)

TempValue2=Object.Angle2
TempValue2+=256
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos5[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos5[+ArrayPos0]

TempValue2=Object.Stars3
TempValue2+=5
DrawSpriteXY(TempValue2,TempValue0,TempValue1)

//Draw the 2nd Pair of Stars
TempValue2=Object.Angle2
TempValue2+=168
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos3[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos3[+ArrayPos0]

DrawSpriteXY(Object.Stars2,TempValue0,TempValue1)

TempValue2=Object.Angle2
TempValue2+=424
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos3[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos3[+ArrayPos0]

TempValue2=Object.Stars2
TempValue2+=3
DrawSpriteXY(TempValue2,TempValue0,TempValue1)

//Draw the 1st Pair of Stars
Cos(TempValue0,Object.Angle1)
Sin(TempValue1,Object.Angle1)
TempValue0<<=11
TempValue1<<=11

TempValue0+=Player.XPos
TempValue1+=Player.YPos

DrawSpriteXY(Object.Stars1,TempValue0,TempValue1)

TempValue2=Object.Angle1
TempValue2+=256
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

TempValue0+=Player.XPos
TempValue1+=Player.YPos

TempValue2=Object.Stars3
TempValue2+=5
DrawSpriteXY(Object.Stars1,TempValue0,TempValue1)

end sub

sub ObjectStartup

LoadSpriteSheet("Global/Items.gif")

//Invincibility Star Frames
SpriteFrame(0,0,1,1,118,304)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(0,0,1,1,118,304)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-1,-1,3,3,117,303)

//Frame 20
SpriteFrame(0,0,1,1,118,304)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(0,0,1,1,118,304)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-1,-1,3,3,117,303)

//Frame 32
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-7,-7,15,15,125,303)

//Frame 44
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)

end sub

sub RSDK
LoadSpriteSheet("Global/Items.gif")
SetEditorIcon(Icon0,SingleIcon,-15,-15,31,31,143,332)
end sub

[/CODE]

All I can say is, unless that code works in mmf2's lua object, I doubt it will help much. far too much bulk here.

Link to comment
Share on other sites

All I can say is, unless that code works in mmf2's lua object, I doubt it will help much. far too much bulk here.

Bulky? This one was a fairly basic sized script XD

No you wouldn't be able to port that code directly, apart from the fact the script syntax is my own, the Retro Engine works very differently to the object system of MMF. For example, MMF would need each star twinkle to be a separate active object, where as using the manual drawing methods in the Retro Engine, the stars are drawn with one script.

It should still be possible to duplicate the algorithm though. It's just not laid out in an obvious manner, so yeah sorry. I just can't be bothered going into mmf and dealing with it XD

Link to comment
Share on other sites

I think I was able to understand some of this.



//---------Retro Sonic XG Invincibility Stars---------//
//----Scripted by Christian Whitehead "The Taxman"----//

//----Player Directions----//
#alias 1 : FACING_LEFT
#alias 0 : FACING_RIGHT

#alias Object.Value0 : Object.Angle1
#alias Object.Value1 : Object.Angle2

#alias Object.Value2 : Object.Stars1
#alias Object.Value3 : Object.Stars2
#alias Object.Value4 : Object.Stars3
#alias Object.Value5 : Object.Stars4

#alias Object.Value0 : StarPos0
#alias Object.Value1 : StarPos1
#alias Object.Value2 : StarPos2
#alias Object.Value3 : StarPos3
#alias Object.Value4 : StarPos4
#alias Object.Value5 : StarPos5
#alias Object.Value6 : StarPos6
#alias Object.Value7 : StarPos7

sub ObjectMain
if Object.State==0
//Set the Star Positions
ArrayPos0=1
StarPos7[+ArrayPos0]=Player.XPos
StarPos6[+ArrayPos0]=Player.XPos
StarPos5[+ArrayPos0]=Player.XPos
StarPos4[+ArrayPos0]=Player.XPos
StarPos3[+ArrayPos0]=Player.XPos
StarPos2[+ArrayPos0]=Player.XPos
StarPos1[+ArrayPos0]=Player.XPos
StarPos0[+ArrayPos0]=Player.XPos

ArrayPos0=2
StarPos7[+ArrayPos0]=Player.YPos
StarPos6[+ArrayPos0]=Player.YPos
StarPos5[+ArrayPos0]=Player.YPos
StarPos4[+ArrayPos0]=Player.YPos
StarPos3[+ArrayPos0]=Player.YPos
StarPos2[+ArrayPos0]=Player.YPos
StarPos1[+ArrayPos0]=Player.YPos
StarPos0[+ArrayPos0]=Player.YPos

Object.Angle1=180
Object.Angle2=0

Object.Stars4=20
Object.Stars3=0
Object.Stars2=32
Object.Stars1=44

Object.State=1
end if
end sub
[/CODE]

Basically, I'd be able to do all this by editing the active object properties of each star.

[CODE]
sub ObjectDraw

//Update the Star Frames
Object.Stars4++
if Object.Stars4==26
Object.Stars4=20
end if

Object.Stars3++
if Object.Stars3==10
Object.Stars3=0
end if

Object.Stars2++
if Object.Stars2==38
Object.Stars2=32
end if

Object.Stars1++
if Object.Stars1==56
Object.Stars1=44
end if
[/CODE]

This causes the stars to animate.

[CODE]
//Update the Star Positions
ArrayPos0=1
StarPos7[+ArrayPos0]=StarPos6[+ArrayPos0]
StarPos6[+ArrayPos0]=StarPos5[+ArrayPos0]
StarPos5[+ArrayPos0]=StarPos4[+ArrayPos0]
StarPos4[+ArrayPos0]=StarPos3[+ArrayPos0]
StarPos3[+ArrayPos0]=StarPos2[+ArrayPos0]
StarPos2[+ArrayPos0]=StarPos1[+ArrayPos0]
StarPos1[+ArrayPos0]=StarPos0[+ArrayPos0]
StarPos0[+ArrayPos0]=Player.XPos

ArrayPos0=2
StarPos7[+ArrayPos0]=StarPos6[+ArrayPos0]
StarPos6[+ArrayPos0]=StarPos5[+ArrayPos0]
StarPos5[+ArrayPos0]=StarPos4[+ArrayPos0]
StarPos4[+ArrayPos0]=StarPos3[+ArrayPos0]
StarPos3[+ArrayPos0]=StarPos2[+ArrayPos0]
StarPos2[+ArrayPos0]=StarPos1[+ArrayPos0]
StarPos1[+ArrayPos0]=StarPos0[+ArrayPos0]
StarPos0[+ArrayPos0]=Player.YPos

if Player.Direction==FACING_RIGHT
Object.Angle1+=144
if Object.Angle1>511
Object.Angle1-=512
end if

Object.Angle2+=16
if Object.Angle2>511
Object.Angle2-=512
end if
else
Object.Angle1-=144
if Object.Angle1<0
Object.Angle1+=512
end if

Object.Angle2-=16
if Object.Angle2<0
Object.Angle2+=512
end if
end if

//Draw the 4th Pair of Stars
TempValue2=Object.Angle2
TempValue2+=116
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos7[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos7[+ArrayPos0]

DrawSpriteXY(Object.Stars4,TempValue0,TempValue1)

TempValue2=Object.Angle2
TempValue2+=372
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos7[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos7[+ArrayPos0]

TempValue2=Object.Stars4
TempValue2+=3
DrawSpriteXY(TempValue2,TempValue0,TempValue1)

//Draw the 3rd Pair of Stars
Cos(TempValue0,Object.Angle2)
Sin(TempValue1,Object.Angle2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos5[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos5[+ArrayPos0]

DrawSpriteXY(Object.Stars3,TempValue0,TempValue1)

TempValue2=Object.Angle2
TempValue2+=256
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos5[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos5[+ArrayPos0]

TempValue2=Object.Stars3
TempValue2+=5
DrawSpriteXY(TempValue2,TempValue0,TempValue1)

//Draw the 2nd Pair of Stars
TempValue2=Object.Angle2
TempValue2+=168
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos3[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos3[+ArrayPos0]

DrawSpriteXY(Object.Stars2,TempValue0,TempValue1)

TempValue2=Object.Angle2
TempValue2+=424
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos3[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos3[+ArrayPos0]

TempValue2=Object.Stars2
TempValue2+=3
DrawSpriteXY(TempValue2,TempValue0,TempValue1)

//Draw the 1st Pair of Stars
Cos(TempValue0,Object.Angle1)
Sin(TempValue1,Object.Angle1)
TempValue0<<=11
TempValue1<<=11

TempValue0+=Player.XPos
TempValue1+=Player.YPos

DrawSpriteXY(Object.Stars1,TempValue0,TempValue1)

TempValue2=Object.Angle1
TempValue2+=256
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

TempValue0+=Player.XPos
TempValue1+=Player.YPos

TempValue2=Object.Stars3
TempValue2+=5
DrawSpriteXY(Object.Stars1,TempValue0,TempValue1)

end sub
[/CODE]

This must be the physics of the stars.

[CODE]
sub ObjectStartup

LoadSpriteSheet("Global/Items.gif")

//Invincibility Star Frames
SpriteFrame(0,0,1,1,118,304)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(0,0,1,1,118,304)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-1,-1,3,3,117,303)

//Frame 20
SpriteFrame(0,0,1,1,118,304)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(0,0,1,1,118,304)
SpriteFrame(-1,-1,3,3,117,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-1,-1,3,3,117,303)

//Frame 32
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-10,-10,21,21,117,319)
SpriteFrame(-7,-7,15,15,125,303)

//Frame 44
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-15,-15,31,31,143,332)
SpriteFrame(-3,-3,7,7,117,307)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-7,-7,15,15,125,303)
SpriteFrame(-3,-3,7,7,117,307)

end sub

sub RSDK
LoadSpriteSheet("Global/Items.gif")
SetEditorIcon(Icon0,SingleIcon,-15,-15,31,31,143,332)
end sub

[/CODE]

Must be the animation frames. Does this mean your rotating stars rotate in your animation frames? I see 12 frames for most of these. Well, I was using only 6 frames. Maybe if I stretched it out to 12, the animation might look better.

Thank you for the code, Taxman. It gave me some valuable info. I'll get back to work on the invincibility later today.

Link to comment
Share on other sites

Does this mean your rotating stars rotate in your animation frames? I see 12 frames for most of these. Well, I was using only 6 frames. Maybe if I stretched it out to 12, the animation might look better.

Thank you for the code, Taxman. It gave me some valuable info. I'll get back to work on the invincibility later today.

Nah, the rotation is handled with sin and cos functions:



//Draw the 4th Pair of Stars
TempValue2=Object.Angle2
TempValue2+=116
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos7[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos7[+ArrayPos0]

DrawSpriteXY(Object.Stars4,TempValue0,TempValue1)

TempValue2=Object.Angle2
TempValue2+=372
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos7[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos7[+ArrayPos0]

TempValue2=Object.Stars4
TempValue2+=3
DrawSpriteXY(TempValue2,TempValue0,TempValue1)

//Draw the 3rd Pair of Stars
Cos(TempValue0,Object.Angle2)
Sin(TempValue1,Object.Angle2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos5[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos5[+ArrayPos0]

DrawSpriteXY(Object.Stars3,TempValue0,TempValue1)

TempValue2=Object.Angle2
TempValue2+=256
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos5[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos5[+ArrayPos0]

TempValue2=Object.Stars3
TempValue2+=5
DrawSpriteXY(TempValue2,TempValue0,TempValue1)

//Draw the 2nd Pair of Stars
TempValue2=Object.Angle2
TempValue2+=168
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos3[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos3[+ArrayPos0]

DrawSpriteXY(Object.Stars2,TempValue0,TempValue1)

TempValue2=Object.Angle2
TempValue2+=424
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

ArrayPos0=1
TempValue0+=StarPos3[+ArrayPos0]
ArrayPos0=2
TempValue1+=StarPos3[+ArrayPos0]

TempValue2=Object.Stars2
TempValue2+=3
DrawSpriteXY(TempValue2,TempValue0,TempValue1)

//Draw the 1st Pair of Stars
Cos(TempValue0,Object.Angle1)
Sin(TempValue1,Object.Angle1)
TempValue0<<=11
TempValue1<<=11

TempValue0+=Player.XPos
TempValue1+=Player.YPos

DrawSpriteXY(Object.Stars1,TempValue0,TempValue1)

TempValue2=Object.Angle1
TempValue2+=256
Cos(TempValue0,TempValue2)
Sin(TempValue1,TempValue2)
TempValue0<<=11
TempValue1<<=11

TempValue0+=Player.XPos
TempValue1+=Player.YPos

TempValue2=Object.Stars3
TempValue2+=5
DrawSpriteXY(Object.Stars1,TempValue0,TempValue1)


[/CODE]

The radius of the rotation stars is 16 pixels so in mmf it'd look more like this

Star_XPosition = Star_CentreX + ( cos(RotationAngle) * 16 )

Star_YPosition = Star_CentreY + ( sin(RotationAngle) *16 )

Star_CentreX and Star_CentreY are the buffered positions of PlayerX and PlayerY. The older the buffer data, the more delayed the star trailing effect is

Link to comment
Share on other sites

Sorry, but that code didn't help me at all. :( Should the stars being created from the sparkles be in the same Group? This is another thing that's been puzzling me. I'm just totally lost right now. No matter what, the stars I create keep on following the active object. How can I get them to simply stay put? There must be some kind of event that stops the created stars from following the active object.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...