Swinging Rope help

BlitzPlus Forums/BlitzPlus Programming/Swinging Rope help

Anyone out there got any suggestions for making a rope swing realistically.

I thought of making it up from very small image sections.

However, if there is a formula to calculate this effect i would be very happy(maybe)

Now this depends on how realistic you want it...

What's it for? A pitfall type rope?

If so you probably don't want it that realistic.

An easy way to make something that 'looks about right' is:

Draw a bunch of arcs from the pivot point for your segments.


Now as you move to the lower segments you move along the arc faster than the higher ones, this will give the impression of the end flailing. You'd move them using a sine wave so they slow at the ends and reach full speed in the middle.

This is not accurate at all, this is not realistic at all, but it looks about right for a game.

Could that swings be done using 1 bezier-curve while changing the end point and the end-control-point btw?

Not a bad idea CS_TBL, you could use the following spline code using two points and modify it so that the end point moves back and forth...

http://www.blitzmax.com/codearcs/codearcs.php?code=1100

Might be a bit overcomplicated for a rope but it's worth trying.

What's it for? A pitfall type rope?



yup

thanks some great ideas there, sine - yuck

guess ill start working on it, thanks again

If you're looking for a pitfall type rope then this code will be of interest to you as well :)

Pitfall II remake source by WolRon...

http://www.blitzmax.com/codearcs/codearcs.php?code=1224

Out of boredom I made a few rope-functions, bankbased, but no user should be bothered with that.. (I think) it's also based on those circles btw..

The example app says it all .. The rope-swing could be a bit better.. the upper-part of the ropes ain't swinging at all. Ahwell, someone who wants to improve it, within the current structure? :)

app=CreateWindow("rope - CS_TBL",0,0,640,480)

canvas=CreateCanvas(0,0,640,480,app)

timer=CreateTimer(25)

; make a bunch o' ropes ...  schoolgym-trauma :(  *sigh*

Dim MyRope(15)
For t=0 To 15
	MyRope(t)=CreateRope(48,3,128-Rnd(80),4+Rnd(8)) ; CreateRope(segments, segmentlength, swingamplitude, swingspeed)
Next

Repeat
	WaitEvent()
	If EventID()=$4001

		SetBuffer CanvasBuffer(canvas)
			Cls

			For ropes=0 To 15 ; all ropes
				UpdateRope(MyRope(ropes)) ; update the phases
				
				; readout the x/y coords for each segment, for each rope
				For t=0 To RopeMaxsegments(MyRope(ropes))-1
					x=RopeX(t,MyRope(ropes))
					y=RopeY(t,MyRope(ropes))
					Plot 64+(ropes*32)+x,128+y
				Next
			Next
		FlipCanvas canvas
	EndIf
	If EventID()=$803 quit=True
Until quit
End

Function CreateRope(segments,segmentlength,swing,speed)
	bank=CreateBank(1+1+1+1 + 2) ; functionarguments + 1 (swingphase)

	If speed>360 speed=360

	PokeByte bank,0,segments
	PokeByte bank,1,segmentlength
	PokeByte bank,2,swing
	PokeByte bank,3,speed

	PokeShort bank,4,0
	Return bank
End Function

Function UpdateRope(bank)
	If Not bank End

	speed=PeekByte(bank,3)
	phase=PeekShort(bank,4)
	phase=(phase+speed) Mod 360
	PokeShort bank,4,phase
	
End Function

Function RopeX(segment,bank)
	If Not bank End

	maxsegments=PeekByte(bank,0)
	If segment>=maxsegments End

	phase=PeekShort(bank,4)
	swing=PeekByte(bank,2)
	segmentlength=PeekByte(bank,1)

	angle=Sin(phase)*swing*segment/128
	angle=angle*segment/maxsegments

	x=Sin(angle)*segment*segmentlength
	Return x
End Function

Function RopeY(segment,bank)
	If Not bank End

	maxsegments=PeekByte(bank,0)
	If segment>=maxsegments End

	phase=PeekShort(bank,4)
	swing=PeekByte(bank,2)
	segmentlength=PeekByte(bank,1)

	angle=Sin(phase)*swing*segment/128
	angle=angle*segment/maxsegments

	y=Cos(angle)*segment*segmentlength
	Return y
End Function

Function RopeMaxsegments(bank)
	If Not bank End
	Return PeekByte(bank,0)
End Function


ps. no doubt it isn't fool-proof ^_^

here you go


Const EVENT_None		= $0		; No event (eg. a WaitEvent timeout)
Const EVENT_KeyDown		= $101		; Key pressed
Const EVENT_KeyUp		= $102		; Key released
Const EVENT_ASCII		= $103		; ASCII key pressed
Const EVENT_MouseDown	= $201		; Mouse button pressed
Const EVENT_MouseUp		= $202		; Mouse button released
Const EVENT_MouseMove	= $203		; Mouse moved
Const EVENT_Gadget		= $401		; Gadget clicked
Const EVENT_Move		= $801		; Window moved
Const EVENT_Size		= $802		; Window resized
Const EVENT_Close		= $803		; Window closed
Const EVENT_Front		= $804		; Window brought to front
Const EVENT_Menu		= $1001		; Menu item selected
Const EVENT_LostFocus	= $2001		; App lost focus
Const EVENT_GotFocus	= $2002		; App got focus
Const EVENT_Timer		= $4001		; Timer event occurred


vecchiotempo=0
cycles=0
r=10

raggiofalso=r

numballs=40

iteraz=50

g#=0.3

Dim angle#(numballs)
Dim rv# (numballs)
Dim x# (numballs)
Dim y# (numballs)
Dim z# (numballs)
Dim xv#(numballs)
Dim yv#(numballs)
Dim oldx# (numballs)
Dim oldy#(numballs)
Dim yspeed#(numballs)
Dim xspeed#(numballs)
Dim unicol(3)
Dim col(numballs,3)
Dim adder(3)


Dim forzax1#(numballs)
Dim forzay1#(numballs)
Dim forzax0#(numballs)
Dim forzay0#(numballs)

Dim dist#(numballs)

Dim m#(numballs)




;m(10)=100

;m(20)=100

For i=1 To 3
adder(i)=1
Next

For i=1To numballs

x(i)=i

For j=1 To 3
col(i,j)=Rnd(255)

Next
Next

grabbed=0
grabx#=0
graby#=0

x(1)=400
y(1)=300

xwin=1000
ywin=700

window = CreateWindow ("Game Window (use cursors)...", 0, 0, xwin, ywin+80,0,15)



canvas = CreateCanvas (0, 0, ClientWidth (window), ClientHeight (window), window)
SetGadgetLayout canvas , 1, 1, 1, 1 ; Use zero to leave an edge 'unpinned'...

SetBuffer CanvasBuffer (canvas)

fps = CreateTimer (280)

Repeat

Repeat
	
		e = WaitEvent (1)
		
		If e= EVENT_Close Then End
		


Until e = EVENT_Timer

Cls

For i=1 To numballs
oldx(i)=x(i)
oldy(i)=y(i)
Next 




If Not  MouseDown(1)

grabbed=0
End If

If grabbed=0 And MouseDown(1)

For i=1 To numballs

 If MouseX(canvas)>x(i) And MouseX(canvas)<x(i)+2*r  And MouseY(canvas)>y(i) And MouseY(canvas)<y(i)+2*r Then
grabbed=i

grabx=MouseX(canvas)-x(i)
graby=MouseY(canvas)-y(i)


End If

Next

End If

;grabbed=1


For i=1To numballs

m(i)=1
Next

;m(numballs)=10

;m(1)=10


If grabbed>0

m(grabbed)=1000000000


x(grabbed)=MouseX(canvas)-grabx
y(grabbed)=-graby+MouseY(canvas)
xv(grabbed)=0
yv(grabbed)=0
End If





;applica le forze alla velocita' vecchia



For i=1 To numballs


yv(i)=yv(i)+g

x(i)=x(i)+xv(i)
y(i)=y(i)+yv(i)





Next



For l=1 To iteraz;!!!!!

For i=2 To numballs



dist(i)=((x(i)-x(i-1))^2+(y(i)-y(i-1))^2)^0.5-2*r

If (1=2)
angle(i)=ATan2(-y(i)+y(i-1),x(i)-x(i-1))
forzax1(i-1)=dist(i)/(1+m(i-1)/m(i))*Cos(angle(i))
forzay1(i-1)=-dist(i)/(1+m(i-1)/m(i))*Sin(angle(i))


forzax0(i)=-dist(i)/(1+m(i)/m(i-1))*Cos(angle(i))
forzay0(i)=dist(i)/(1+m(i)/m(i-1))*Sin(angle(i))
End If

If (1=1)
forzax1(i-1)=dist(i)/(1+m(i-1)/m(i))* ( (x(i)-x(i-1) )/ ( dist(i)+2*r ) )

forzay1(i-1)=dist(i)/(1+m(i-1)/m(i))*( (y(i)-y(i-1) )/ ( dist(i)+2*r ) )


forzax0(i)=-dist(i)/(1+m(i)/m(i-1))*( (x(i)-x(i-1) )/ ( dist(i)+2*r ) )
forzay0(i)=-dist(i)/(1+m(i)/m(i-1))*( (y(i)-y(i-1) )/ ( dist(i)+2*r ) )
End If

Next


For i=1 To numballs

x(i)=x(i)+forzax0(i)+forzax1(i)
y(i)=y(i)+forzay0(i)+forzay1(i)

Next

Next



For i=1 To numballs




xv(i)=x(i)-oldx(i)
yv(i)=y(i)-oldy(i)

If x(i)>xwin -2*r
x(i)=xwin-2*r
xv(i)=-xv(i)
End If
If x(i)<0 
x(i)=0
xv(i)=-xv(i)
End If
If y(i)>ywin-2*r 
y(i)=ywin-2*r
yv(i)=-yv(i)
xv(i)=0.9*xv(i)
End If
If y(i)<0 
y(i)=0
yv(i)=-yv(i)
End If


Next





For i=1 To 3
If Rnd(0,1000)>990 Then
adder(i)=-adder(i)
End If

unicol(i)=unicol(i)+adder(i)
If unicol(i)>254 Then adder(i)=-1
If unicol(i)<1 Then adder(i)=1

Next

If (1=1)

For i=1 To numballs

Color unicol(1),unicol(2),unicol(3)

;Color col(i,1),col(i,2),col(i,3)

Oval x(i),y(i),2*raggiofalso,2*raggiofalso
Next

End If

If (1=2)
For i=1 To numballs-1

Color  unicol(1),unicol(2),unicol(3)

;Color col(i,1),col(i,2),col(i,3)

Line x(i),y(i),x(i+1),y(i+1)
Next
End If

	Text  20, 40,fps

cycles=cycles+1
If MilliSecs()-vecchiotempo>1000
vecchiotempo=MilliSecs()
fps=cycles
cycles=0
End If

	FlipCanvas canvas
	
	Until (KeyHit (1))
	
End



The effect looks great! But the source looks a bit painful to read, for me :\ doesn't look much stand-alone, or self-contained.. it's simply 'the routine', everywhere.

Would it be possible to
- get rid of *all* globals and dims
- make stand-alone selfcontained 'blackbox' functions
?

ok, I'll explain you the algorithm in words: at each frame you move the balls as there was no link between them. Then, every frame, you try to get the balls back linked: to do this you (*) use an algorithm that for every couple of linked balls, shifts them closer by an amount proportional to their distance. You need to calculate all the shifts for all couples before you apply them. Moreover, all this must be repeated for 30-40 times every frame(i.e.goto *). then you update the speed of of each ball according to the movement it did in the last frame

sorry I'm not good at modular design, try to see if you can get it a "black box"

hey, I remember I clallenged people here to do it, and botbuilder came up with a solution that is probably coded much better than mine: check it out!

http://blitzmax.com/Community/posts.php?topic=43242&hl=chain

Thanks again for all the input.

Working on rope atm:)