How to create a walking animation in LOVE 2D - animation

So I was wondering how to change an image of character I've created depending on the key I've pressed/am pressing?
My ultimate going to to have a walking animation occuring when "d" (or any of the wasd keys) is pressed but then he stands still when the "d" key has just been pressed etc. All images have been created already.
I've tried this but it didn't work out:
function love.load()
if love.keyboard.isDown("a") then
hero = love.graphics.newImage("/hero/11.png")
elseif love.keyboard.isDown("d") then
hero = love.graphics.newImage("/hero/5.png")
elseif love.keyboard.isDown("s") then
hero = love.graphics.newImage("/hero/fstand.png")
elseif love.keyboard.isDown("w") then
hero = love.graphics.newImage("/hero/1.png")
end
function love.draw()
love.graphics.draw(background)
love.graphics.draw(hero, x, y)
end

You must understand how LÖVE works. It (very basically) does this:
love.load() -- invoke love.load just once, at the beginning
while true do -- loop that repeats the following "forever" (until game ends)
love.update(dt) -- call love.update()
love.draw() -- call love.draw()
end
This schema is so frequent that the loop itself has a name - it's called The Game Loop.
Your code does't work because you are using love.load() as if it was part of the game loop, but it isn't. It's called at the beginning, during the first millisecond or so of your program, and never again.
You want to use love.load do load the images, and love.update to change them:
function love.load()
heroLeft = love.graphics.newImage("/hero/11.png")
heroRight = love.graphics.newImage("/hero/5.png")
heroDown = love.graphics.newImage("/hero/fstand.png")
heroUp = love.graphics.newImage("/hero/1.png")
hero = heroLeft -- the player starts looking to the left
end
function love.update(dt)
if love.keyboard.isDown("a") then
hero = heroLeft
elseif love.keyboard.isDown("d") then
hero = heroRight
elseif love.keyboard.isDown("s") then
hero = heroDown
elseif love.keyboard.isDown("w") then
hero = heroUp
end
end
function love.draw()
love.graphics.draw(background)
love.graphics.draw(hero, x, y)
end
The code above has certain repetitiveness that can be factored out using tables, but I've left it simple on purpose.
You will also notice that I have included the dt parameter in the love.update function. This is important, since you will need it to make sure that animations work the same in all computers (the speed at which love.update is called depends on each computer, and dt allows you to cope with that)
Nevertheless, if you want to do animations, you will probably want to use this Animation Lib or my own.

Related

How do I make a script affect all its children in Roblox LUA?

I'm new to programming in LUA, although I've learned similar languages like JS. It's frustrating if I have to alter the same script in many parts in a group by replacing each script, and I don't know of an elegant way to do it. Instead, I decided to nest all the parts inside of the script. I've seen some examples and I've tried to adapt some of them, but they don't exactly apply to what I want to do and I can't get them to work.
In essence, what I'm trying to do is monitor all the bricks for a player to contact them. I took the original disappearing brick script that was nested inside each brick and modified it. If a part (brick) is touched, that should call the onTouch function, which will make the brick's transparency decrease over time until the in pairs loop is done, after which the brick disappears and CanCollide is turned off. After 2 seconds, it then returns back to normal. I think the problem is with the coding I used to monitor the parts as I don't really understand the right way to monitor multiple objects. Can someone please help? Thanks!
File structure:
function onTouched(brick)
local delay = .1 -- the delay between each increase in transparency (affects speed of disappearance)
local RestoreDelay = 2 -- delay before the brick reappears
local inc = .1 -- how much the brick disappears each time
-- All characters have a Humanoid object
-- if the model has one, it is a character
local h = script.Child:findFirstChild("Humanoid") -- Find Humanoids in whatever touched this
if (h ~=nil) then -- If there is a Humanoid then
h.Health = h.MaxHealth -- Set the health to maximum (full healing)
for x=0,1, inc do
script.Child.Transparency = x+inc
script.Child.CanCollide = true
wait(delay)
end
wait(delay)
script.Child.Transparency = 1
script.Child.CanCollide = false
wait(RestoreDelay)
script.Child.Transparency = 0
script.Child.CanCollide = true
else
end
end
while true do
local bricks=script:GetChildren():IsA("basic.part")
for x=1,brick in pairs(bricks) do
brick.Touched:connect(onTouched(brick)) -- Make it call onTouched when touched
end
end
end
For the most part, you've gotten it right, but you've got a few syntax errors where there are different conventions between JavaScript and Lua.
In JS, you would fetch an array of objects and then bee able to filter it immediately, but in Lua, there is limited support for that. So a JavaScript line like :
var bricks = script.GetChildren().filter(function(item) {
return item === "basic.part"
})
cannot be done all in one line in Lua without assistance from some library. So you'll need to move the check into the loop as you iterate over the objects.
Other than that, the only other thing to change is the onTouched handler's function signature. The BasePart.Touched event tells you which object has touched the brick, not the brick itself. But by creating a higher order function, it's easy to get access to the brick, and the thing that touched it.
-- create a helper function to access the brick and the thing that touched it
function createOnTouched(brick)
-- keep track whether the animation is running
local isFading = false
return function(otherPart)
-- do not do the animation again if it has already started
if isFading then
return
end
local delay = .1 -- the delay between each increase in transparency (affects speed of disappearance)
local restoreDelay = 2 -- delay before the brick reappears
local inc = .1 -- how much the brick disappears each time
-- All characters have a Humanoid object, check for one
local h = otherPart.Parent:FindFirstChild("Humanoid")
if h then
-- heal the player
h.Health = h.MaxHealth
-- start fading the brick
isFading = true
brick.CanCollide = true
for i = 0, 1, inc do
brick.Transparency = i
wait(delay)
end
-- turn off collision for the brick
wait(delay)
brick.Transparency = 1
brick.Anchored = true
brick.CanCollide = false
-- turn the part back on
wait(restoreDelay)
brick.Transparency = 0
brick.CanCollide = true
-- reset the animation flag
isFading = false
end
end
end
-- loop over the children and connect touch events
local bricks = script:GetChildren()
for i, brick in ipairs(bricks) do
if brick:IsA("BasePart") then
local onTouchedFunc = createOnTouched(brick)
brick.Touched:Connect(onTouchedFunc)
end
end

How can i change the character image non Ruby Gosu

im building a basic game in the style of the original pokemon games using the ruby gosu library. Ive managed to figure out how to move the originally loaded sprite about but i cant figure out how to clear that sprite and draw the new sprite e.g. back view in its place.
Ive been looking throught the documentation and came across the "insert" method, although im not sure if this is what i want. Any help?
im creating the var in the initialize method then drawing it later on like so:
def initialize
#character_image = Gosu::Image.new("media/images/char.png", :tileable => false)
end
def draw
#character_image.draw(#character_location_X, #character_location_Y, 1)
end
You need to make a class for your character, which needs an update and draw function. In the update function, when input such as WASD is received you can switch the image of the sprite. If you don't have a sprite sheet, you'll have to load multiple images and switch between them.
Here's some ruby pseudocode to help you:
#back_image = Gosu::Image.new("media/images/back.png")
#front_image = Gosu::Image.new("media/images/front.png")
#left_image = Gosu::Image.new("media/images/left.png")
#right_image = Gosu::Image.new("media/images/right.png")
current_image = front_image
This goes in your update function:
if up
current_image = back_image
elsif down
current_image = front_image
elsif right
current_image = right_image
elsif left
current_image = left_image
end
Then in your draw function all you need to do is
def draw
#current_image.draw(#character_location_X, #character_location_Y, 1)
end
This is a pretty basic way, but if you use a sprite sheet, you can create your own animation class that Gosu can use that allows you to select between certain ranges of frames of your character spritesheet.

Want to move a slider and all the others update in Matlab?

I have GUI in Matlab that I have made using the Programmatic approach. It has 6 sliders and I want to be able to move one of them and have the others update as if i clicked them again but to stay in the same place. I am guessing I will need to use the set() function. Is there some function to do this in matlab already? I have been looking around. Any suggestions or something to point me in the right direction?
If you are using guide, you can access the other sliders from the handles variable that is available in each callback.
Set the Value property for them.
function Slider1_CallBack(hObj,evt,handles)
set(handles.Slider1,'Value',10);
set(handles.Slider2,'Value',10);
% etc..
end
In case you are using it programmaticaly, you can store the handles manually.
function main
handles.Figure1 = figure(..);
handles.Slider1 = uicontrol(...);
handles.Slider2 = uicontrol(...);
guidata(handles.Figure1,handles);
end
And your slider callback should be:
function Slider1_CallBack(hObj,evt)
handles = guidata(hObj);
set(handles.Slider1,'Value',10);
set(handles.Slider2,'Value',10);
% etc..
end
Edit A good practice in writing UI is separating the GUI logic from the actual data. You always change the data, and call updateGUI routine.
Therefore, you can write your program like this:
function main
handles.gui.Figure1 = figure(..);
handles.gui.Slider1 = uicontrol(...);
handles.gui.Slider2 = uicontrol(...);
handles.data.x = 1;
guidata(handles.Figure1,handles);
end
function UpdateGui(handles)
%Based on the data, update the GUI
set(handles.Slider1,'Value',handles.data.x);
set(handles.Slider2,'Value',handles.data.x+1);
end
And the callback should look like:
function Slider1_CallBack(hObj,evt)
handles = guidata(hObj);
handles.data.x = handles.data.x + 1;
UpdateGui(handles);
guidata(hObj,handles);
% etc..
end

Is there a better way of linking transitions in Corona Lua?

I'm currently animating a trash can when something gets dragged and dropped onto it with this code:
local trashUp
local trashDown
trashUp = function()
transition.to(
trash, {time=100, xScale=1.2, yScale=1.2, onComplete=trashDown })
end
trashDown = function()
transition.to(
trash, {time=100, xScale=1, yScale=1})
end
and then calling trashUp() when I want to start the animation.
The code works fine, but I can't help feel it could be coded better. Two functions to animate an object!
Is there any way I can do this more efficiently?
Well you could do it in a single function by setting the second transition with delay; refer to this code example: http://developer.anscamobile.com/reference/index/transitionto
Depending on your situation however that's not necessarily less complicated, because now you have to keep track of two transitions simultaneously instead of just one transition at a time. In the code you posted you aren't keeping track of the transitions, but you probably should be in case you need to cancel them before the transition is complete (eg. the player switches scenes in the middle of the transition).
You can do it by coding the onComplete function inline with the first transition call:
animateTrash = function()
transition.to(
trash,
{ time=100, xScale=1.2, yScale=1.2, onComplete=
function()
transition.to(
trash,
{time=100, xScale=1, yScale=1})
end
})
end
This won't be any more efficient, but it does keep everything to do with animating the trashcan in one place. I think this approach could get quickly out of hand, though, especially if you were doing anything other than the transitions when animating the trashcan, e.g., updating your program's state, or creating/destroying other objects, etc.
Echoing jhocking's answer, this approach doesn't support canceling either.
This question is pretty old, but since I was trying to do the same thing, I figured I should share what I came up with. This sequentially executes transitions that are passed in as variable args. If onComplete is supplied, it is called as its transition completes.
local function transitionSequence(target, step, ...)
local remaining_steps = {...}
if #remaining_steps > 0 then
local originalOnComplete = step.onComplete
step.onComplete = function(target)
if originalOnComplete then
originalOnComplete(target)
end
transitionSequence(target, unpack(remaining_steps))
end
transition.to(target, step)
else
transition.to(target, step)
end
end
Example:
transitionSequence(myImage,
{xScale=0.5, onComplete=function(t) print("squeeze") end},
{xScale=1, onComplete=function(t) print("relax") end},
{yScale=2, onComplete=function(t) print("stretch") end},
{yScale=1, onComplete=function(t) print("relax again") end})
transition.to( trash, {time=t, delta=true, xScale=1.5, transition=easing.continousLoop} )
Also very useful for purposes like that:
easing.sin = function( f, a )
return function(t, tmax, start, d)
return start + delta + a*math.sin( (t/tmax) *f * math.pi*2 )
end
end
easing.sinDampened = function( f, a, damp )
return function(t, tmax, start, d)
return start + delta + a*math.sin( damp^(t/tmax) *f * math.pi*2 )
end
end
...etc

Smooth transition (optical effect) between uitabpanels in Matlab

I have designed a group of three uitabpanels objects.
htab = uitabgroup('v0');
th1 = uitab('v0',htab,'title','Panel 1','ButtonDownFcn',...
#th1_ButtonDownFcn);
th2 = uitab('v0',htab,'title','Panel 2','ButtonDownFcn',...
#th2_ButtonDownFcn);
th3 = uitab('v0',htab,'title','Panel 3','ButtonDownFcn',...
#th3_ButtonDownFcn);
My intention is having a smooth transition between them when I change the selected uipanel through the mouse click. I pretend to achieve it changing the 'Visible' property of the elements contained inside them using the ButtonDownFcn function ( I got this idea based on the description section of this page).
set(handles.th2,'Visible','off');
set(handles.th3,'Visible','off');
...
function th1_ButtonDownFcn(hObject, eventdata)
handles = guidata(fh);
set(handles.th1,'Visible','on');
set(handles.th2,'Visible','off');
set(handles.th3,'Visible','off');
guidata(fh,handles);
end
function th2_ButtonDownFcn(hObject, eventdata)
handles = guidata(fh);
set(handles.th1,'Visible','off');
set(handles.th2,'Visible','on');
set(handles.th3,'Visible','off');
guidata(fh,handles);
end
function th3_ButtonDownFcn(hObject, eventdata)
handles = guidata(fh);
set(handles.th1,'Visible','off');
set(handles.th2,'Visible','off');
set(handles.th3,'Visible','on');
guidata(fh,handles);
end
where
fh: handle of the figure where they are contained the uitabpanels.
handles.th1, handles.th2, handles.th3: handles of the elements contained into each uitabpanel respectively.
However, it has not worked (I click on each one of uitabpanel's tabs and the visibility of them do not change) and I do not understand why.
In conclusion, the ButtonDownFcn and SelectionChangeFcn functions of an UITAB are already active when you click in the tab´s label. So it is not possible to achieve the desired target (smooth optical transition) because the obtained result (modifying the mentioned functions) is the same that doing nothing.

Resources