Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

[SOLVED] How to make an object rotate or move forever?
Started by elifares Jan 12 2019 01:58 PM

10 replies to this topic
object rotate move transition action

Best Answer roaminggamer , 12 January 2019 - 03:38 PM

Tip: Extending above example to make it self-cancelling (in case object is removed)

local transition1, transition2

--function transition1(self)
transition1 = function(self)
   self.onComplete = transition2
   transition.to( self, { time=1000, rotation=self.rotation+20, 
                  transition=easing.inOutBack, onComplete=self } )
end

--function transition2(self)
transition2 = function(self)
   self.onComplete = transition1
   transition.to( self, { time=1000, rotation=self.rotation-20, 
                  transition=easing.inOutBack, onComplete=self } )
end


transition1(object)

[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

elifares

[GLOBAL: userInfoPane.html]
elifares
  • Enthusiast

  • 86 posts
  • Corona SDK

Hi,

 

I have a player's head who I want to move up/down and rotate a bit to make it look like they're alive/breathing. What is the best way to go about that?

 

Here is my player (car_object + head_object) and I want to make his head "bob" back and forth.

Attached File  player.png   95.86KB   0 downloads

 

I've looked at the Corona APIs and Coronto Tutorials but I'm not exactly sure what the best way to achieve this is. Let's say I want to rotate the head 20 degrees clockwise over the span of 2 seconds and then rotate it back continuously. Do I use a timer.performWithDelay() call and make it move 1 degree every 100ms? Or is there a built-in transition that already does this?

 

Thanks in advance!



[TOPIC: post.html]
#2

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,588 posts
  • Corona SDK

There are many ways to do that.

 

1. Use a sprite.  You can make a sprite that plays this animation and if you want to modify the rate over time  you can also do that.

 

2. Use a timer as you suggested.

 

3. Use enterFrame listener() (Timer is actually using this under the hood).

 

4. transition.to() - I forgot this, but am adding this now.  Credit to @XeduR below.

Tip: If you use this method, make sure the onComplete objects are fields on the object and then the transition will be stopped automatically.

 

5. Make the head a physics object with low density, plus a little bit of angular damping,  and attach it to the rest of the image (also a body) with a pivot joint that has a limited rotation angle.  Then, motion of the second body will cause the head to bobble.

 

6. maybe... transition2 an external lib might... have a built-in feature for this too.  Maybe.



[TOPIC: post.html]
#3

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 892 posts
  • Corona SDK

If your game has physics (and some slopes), then I would definitely look into joints, like roaminggamer already suggested. It would probably result in the most dynamic effect.

If joints aren't your thing, then I would probably solve this by creating two functions that both contain transitions with onComplete for each other. Something along the lines of this pseudo-code:
 

local transition1, transition2

function transition1()
	transition.to( object, { time=1000, rotation=object.rotation+20, transition=easing.inOutBack, onComplete=transition2 } )
end

function transition2()
	transition.to( object, { time=1000, rotation=object.rotation-20, transition=easing.inOutBack, onComplete=transition1 } )
end

transition1()


[TOPIC: post.html]
#4

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,588 posts
  • Corona SDK

  Best Answer

Tip: Extending above example to make it self-cancelling (in case object is removed)

local transition1, transition2

--function transition1(self)
transition1 = function(self)
   self.onComplete = transition2
   transition.to( self, { time=1000, rotation=self.rotation+20, 
                  transition=easing.inOutBack, onComplete=self } )
end

--function transition2(self)
transition2 = function(self)
   self.onComplete = transition1
   transition.to( self, { time=1000, rotation=self.rotation-20, 
                  transition=easing.inOutBack, onComplete=self } )
end


transition1(object)

Edited by roaminggamer, 13 January 2019 - 11:07 AM.


[TOPIC: post.html]
#5

elifares

[GLOBAL: userInfoPane.html]
elifares
  • Enthusiast

  • 86 posts
  • Corona SDK

Thanks for the suggestions guys. I don't use physics in my game, I should have mentioned that in the post.

 

Xedur, I like your solution, it makes sense to me but I'm getting this error: Attempt to index field '?' (a nil value) when transition2 runs.



[TOPIC: post.html]
#6

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,588 posts
  • Corona SDK

See update to solution above.



[TOPIC: post.html]
#7

elifares

[GLOBAL: userInfoPane.html]
elifares
  • Enthusiast

  • 86 posts
  • Corona SDK

Thank you guys! I did not expect a response/solution this fast haha thanks again, really appreciate it!



[TOPIC: post.html]
#8

elifares

[GLOBAL: userInfoPane.html]
elifares
  • Enthusiast

  • 86 posts
  • Corona SDK

See update to solution above.

 

Roaminggamer, what's the point of putting self.onComplete = transition2 as opposed to just sticking transition2 into the transition.to() option parameters?

 

Ex:

transition.to( self, { time=1000, rotation=self.rotation+20,transition=easing.inOutBack, onComplete=transition2 } )



[TOPIC: post.html]
#9

elifares

[GLOBAL: userInfoPane.html]
elifares
  • Enthusiast

  • 86 posts
  • Corona SDK

In addition, I am trying to make players "breath" at different times. I display 4 players on the screen and each time I display a player, I begin the transitions on them. I don't always want all 4 players to be "breathing" the same way at the exact same time every time.

 

I am trying to do this:

M.normalBreathing = function(object)
 local transition1, transition2

 function transition1(self)
   self.onComplete = transition2
   transition.to( self, { time=1000, rotation=self.rotation+20, 
                  transition=easing.inOutBack, onComplete=self } )
 end

 function transition2(self)
   self.onComplete = transition1
   transition.to( self, { time=1000, rotation=self.rotation-20, 
                  transition=easing.inOutBack, onComplete=self } )
 end

 local function startTransitions()
  transition1(object)
 end
 timer.performWithDelay(math.random(0, 10) * 100, startTransitions);
end

And I get an Error: Attempt to index local 'self' (a nil value)



[TOPIC: post.html]
#10

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,588 posts
  • Corona SDK

1. I made a small mistake in my update to @XeduR's original code.  See my update above.

 

In the original versions, those functions  were global not local. i.e. The local statement at the top had no effect.

 

2. If that change doesn't fix the problem, try this and see what prints out:

local function startTransitions()
  print( "Object nil? ", object ) 

  if( object ) then
    print( "Actually a display object? ", object.displayRemove )
  end

  transition1(object)
end


[TOPIC: post.html]
#11

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,588 posts
  • Corona SDK

Roaminggamer, what's the point of putting self.onComplete = transition2 as opposed to just sticking transition2 into the transition.to() option parameters?

 

Ex:

transition.to( self, { time=1000, rotation=self.rotation+20,transition=easing.inOutBack, onComplete=transition2 } )

 

You pasted the wrong code above. I did originally typo it, but this is the final version I posted:

transition.to( self, { time=1000, rotation=self.rotation+20,
                       transition=easing.inOutBack, onComplete=self } )


What I've done is 'attached' the function directly to the object and then had the transition look at the object for an onComplete method.

 

Your code could well have worked fine, but it has been my practice for years to use local functions instead of global ones.  My technique above makes the function local (to the object).

 

Because there are effectively 'two' onComplete methods, I simply swap them on each call.




[topic_controls]
[/topic_controls]