Moving 8 directions Sprite

Hi,
I am new in Defold and I am creating a game right now. But i already tried all the ways but i can-t do my Player moves to all directions with his animations. Please if you can help me out

Did you check the Examples page? There’s an 8-way movement example. Bonus: I have an example of how to rotate and move a game object in a top-down game.

2 Likes

@britzl I checked that, but the player just move with the same animation and dont change

Ah, ok, so the animations aren’t changing but the movement is working? When you’re dealing with sprite flipbook animations (which I assume is looping) you can only trigger the animation once. If you send a play_animation message every frame the animation will get stuck on the first frame. You need to keep track of the current animation that is playing and play an animation if it differs from the current one. Like this: https://github.com/britzl/publicexamples/blob/master/examples/play_animation/play_animation/play_animation.script#L3-L9

1 Like

@britzl thank you very much for your help. The player is already moving to all directions with the sprites. But when i’m not pressing any key, the player don’t return to the idle animation i want and returns to the same idle animation always. And i think the player is not moving in all directions with the same speed, like when he moves Up and Down the speed is more higher than when he moves left and right.

The code is down there:

go.property("speed", 200)

local function play_animation(self, animation)
      if self.current_animation ~= animation then
        self.current_animation = animation
        msg.post("#sprite", "play_animation", { id = animation })
      end
end

function init(self)
    msg.post(".", "acquire_input_focus")
    self.direction = vmath.vector3(0,0,0)
    self.actions = {} 
    self.current_animation = nil
end

function final(self)
    msg.post(".", "release_input_focus")
end

function update(self, dt)
    if self.actions[hash("left")] then
            play_animation(self, hash("run_left"))
            self.direction.x = -self.speed
    elseif self.actions[hash("right")] then
            play_animation(self, hash("run_right"))
            self.direction.x = self.speed
    else
            self.direction.x = 0
end

    if self.actions[hash("up")] then
            play_animation(self, hash("run_up"))
            self.direction.y = self.speed
    elseif self.actions[hash("down")] then
            play_animation(self, hash("run_down"))
            self.direction.y = -self.speed 
    else
            self.direction.y = 0 
    end
    
    if self.direction.x == 0 and self.direction.y == 0 and self.actions[hash("up")] == false then
            play_animation(self, hash("idle_up"))
    elseif self.direction.x == 0 and self.direction.y == 0 and self.actions[hash("down")] == false then
            play_animation(self, hash("idle_down"))
    elseif self.direction.x == 0 and self.direction.y == 0 and self.actions[hash("left")] == false then
            play_animation(self, hash("idle_left")) 
    elseif self.direction.x == 0 and self.direction.y == 0 and self.actions[hash("right")] == false then
            play_animation(self, hash("idle_right"))                         
            
    end                

    go.set_position(go.get_position() + self.direction * dt)   
                           
    end       

function on_input(self, action_id, action)
    if action_id then
            if action.pressed then
                    self.actions[action_id] = true
            elseif action.released then
                    self.actions[action_id] = false
end 
end
end

The if elseif conditional where you are triggering the idle animation looks strange. It’s likely that it will only ever evaluate the first conditional. You need to rethink that one. I’m on a phone now so I’m reluctant to type a lot of code. Let me know if you’re able to solve it on your own or not.

I don-t know what should I do for solve my problem

To answer your last question, you should print out the values of your variables and observe how they change when you use the inputs and compare what you believe to be true and what is actually true in the state of your game. The questions you ask are pretty general for game development, so my recommendation is that you focus on learning how to solve your problems and debug your code. I don’t mean to sound hostile, but if you need someone to help you for every problem, it will take you a long time to get anywhere. It’s much faster in the long run to train your analysis and problem solving at this point.
To give you a good start I will of course answer the two other questions too… :slight_smile:
For the speed problem, you need to normalize the direction vector before applying it to the position. Apply the speed after normalizing it, and the player will move with the same speed in every direction.
For the idle anim problem, you need to think about state changes in movement and your idle animations. Right now there is nothing resetting the self.actions table, so after a key has been released self.actions[action_id] will be false every frame. And every frame you are checking for that and (re)starting the idle-animation. You will need to remember which direction the player had and decide which idle animation to play. One way of doing this is assuming you will go to an idle animation at the end of update(…), falsifying this in on_input(…) in the case of input, and at the start of update(…) trigger the fitting idle animation in case the assumption held true (i.e. no input). There are other ways to deal with this, you could look up “state machines” which is a popular way to deal with character states and animations. They might look complicated at wikipedia, but try to find a source which explains them in simpler terms, probably on stackoverflow.

2 Likes

I used the code y’all put here and It kinda worked after I made a new sprite to go with the player file so I have the idle animation for when he’s standing still but when I have him move both the moving animation and idle animation will play with the idle animation in front the moving animation

This sounds weird. Are you using two sprites? Can you share the code here and also show a screenshot of how the player game object looks?

I’m using a 8 directional sprites and while messing around with it some more I got some directional animations to work like the Up, left, right walking animation and the up idle animation


Here’s the code I’m using

go.property("speed", 5)

local function play_animation(self, animation)
	if self.current_animation ~= animation then
		self.current_animation = animation
		msg.post("#sprite", "play_animation", { id = animation })
	end
end

function init(self)
	msg.post(".", "acquire_input_focus")
	self.direction = vmath.vector3(0,0,0)
	self.actions = {} 
	self.current_animation = nil
end

function final(self)
	msg.post(".", "release_input_focus")
end

function update(self, dt)
	if self.actions[hash("Left")] then
		play_animation(self, hash("Player Left"))
		self.direction.x = -self.speed
	elseif self.actions[hash("Right")] then
		play_animation(self, hash("Player Right"))
		self.direction.x = self.speed
	else
		self.direction.x = 0
	end

	if self.actions[hash("Up")] then
		play_animation(self, hash("Player Up"))
		self.direction.y = self.speed
	elseif self.actions[hash("Down")] then
		play_animation(self, hash("Player Down"))
		self.direction.y = -self.speed 
	else
		self.direction.y = 0 
	end

	if self.direction.x == 0 and self.direction.y == 0 and self.actions[hash("Up")] == false then
		play_animation(self, hash("idle_up"))
	elseif self.direction.x == 0 and self.direction.y == 0 and self.actions[hash("Down")] == false then
		play_animation(self, hash("idle_down"))
	elseif self.direction.x == 0 and self.direction.y == 0 and self.actions[hash("Left")] == false then
		play_animation(self, hash("idle_left")) 
	elseif self.direction.x == 0 and self.direction.y == 0 and self.actions[hash("Right")] == false then
		play_animation(self, hash("idle_right"))                         

	end                

	go.set_position(go.get_position() + self.direction * dt)   

end       

function on_input(self, action_id, action)
	if action_id then
		if action.pressed then
			self.actions[action_id] = true
		elseif action.released then
			self.actions[action_id] = false
		end 
	end
end

Hmm, would you mind sharing the project with me (bjorn.ritzl@king.com) and I’ll take a look.

1 Like

There you go

The project is missing many of the things in your screenshots. Don’t forget to synchronize your changes!

What am I missing?
I super new at this but I’m still going to try.

Here’s the manual on synchronizing your project with the remote cloud storage: https://www.defold.com/manuals/workflow/#_synchronizing

Ok Thanks… This might take awhile before I can give you an update on the problem

Ok I tried to synchronized my game CaptureCapture1
Unlike to manual it doesn’t say any errors or corrupted files it’ll just say push or done
and obviously done will close the window and push I viewed the viewable files and say the comparison to their files and I saw nothing wrong


I think I might just be to arrogant in lua to realize what I’m doing wrong

  1. You must first select the files you want to synchronize.
  2. Then you “stage” them this action will select them for being synced.
  3. It is good praxis to write a message saying what you have done since the last commit.
  4. Pressing push will send them the server for other to synchronize down.

3 Likes

Ok did it. Thank you so much