I need a script that can do an animation when you are standing on a brick. I just don't know how to do the animation. I can't find a free model with the animation I am looking for. Here is a preview of how I want the hands up. PREVIEW OF THE ANIMATION
The brick you are standing on is
script.Parent
There are two main ways of animation; The newer Animations and the older Joints.
The guide should be able to help you to getting started with animations. It even got a video.
If you want to use a old style Joint animation, something like this might work:
local Block = script.Parent
local function MakeFakeShoulder(Character, Side)
local Controller = { ["Stop"] = function() end }
local Torso = Character:findFirstChild("Torso")
local Arm = Character:findFirstChild(Side .. " Arm")
if not Torso or not Arm then return Controller end
local Shoulder = Torso:findFirstChild(Side .. " Shoulder")
if Shoulder then
local FakeShoulder = Instance.new("ManualWeld")
FakeShoulder.Name = "Fake " .. Side .. " Shoulder"
FakeShoulder.C0 = CFrame.new(1.5 * (Side == "Right" and 1 or -1),0.5,0)
FakeShoulder.C1 = CFrame.new(0,0.5,0) * CFrame.fromAxisAngle(Vector3.FromAxis(Enum.Axis.Z), math.rad(-180))
FakeShoulder.Part0 = Torso
FakeShoulder.Part1 = Arm
FakeShoulder.Parent = Torso
Shoulder.Parent = nil
function Controller:Stop()
Shoulder.Parent = Torso
FakeShoulder:Destroy()
end
end
return Controller
end
local function MakeFakeShoulders(Character)
local Controller = { }
local Right = MakeFakeShoulder(Character, "Right")
local Left = MakeFakeShoulder(Character, "Left")
function Controller:Stop()
Right:Stop()
Left:Stop()
end
return Controller
end
local function GetHumanoid(Part)
if Part.Parent == nil then return nil end
return Part.Parent:findFirstChild("Humanoid")
end
local CurrentlyTouching = { }
Block.Touched:connect(function(Part)
local Humanoid = GetHumanoid(Part)
if not Humanoid then return end
CurrentlyTouching[Humanoid] = CurrentlyTouching[Humanoid] or 0
CurrentlyTouching[Humanoid] = CurrentlyTouching[Humanoid] + 1
if CurrentlyTouching[Humanoid] > 1 then return end
local Controller = MakeFakeShoulders(Part.Parent)
while CurrentlyTouching[Humanoid] > 0 do
if GetHumanoid(Block.TouchEnded:wait()) == Humanoid then
CurrentlyTouching[Humanoid] = CurrentlyTouching[Humanoid] - 1
end
end
Controller:Stop()
end)
Note that if the ending touch do not register good enough, make a invisible CanCollide = false bounding part that is bigger than the visual part and put the script in that one instead,
Related
new to Lua and love. I'm trying to animate a character for my platform game. I know my key binds and all work but I have never animated before, so I don't even know if I'm going in the right direction or not. I've tried looking up guides so I can compare my code to someone else's but it seems that most of them are outdated. Originally my player was just a white rectangle but now im trying to actually give it a sprite.
Here's my main.lua
local STI = require("sti")
local anim8 = require('anim8')
require("MC")
function love.load()
map1 = STI("map/map1.lua", {"box2d"})
Physics = love.physics.newWorld(0,0)
Physics:setCallbacks(beginContact, endContact)
map1:box2d_init(Physics)
map1.layers.Solid.visible = false
background = love.graphics.newImage("assets/Base pack/bg.png")
mc:load()
end
function love.update(dt)
Physics:update(dt)
mc:update(dt)
end
function love.draw()
love.graphics.push()
love.graphics.scale(5,3)
love.graphics.draw(background)
love.graphics.pop()
map1:draw(0, 0, 2, 2)
love.graphics.push()
love.graphics.scale(2,2)
mc:draw()
love.graphics.pop()
end
function love.keypressed(key)
mc:jump(key)
if keypressed == "escape" then
love.event.quit(0)
end
end
function beginContact(a, b, collision)
mc:beginContact(a, b, collision)
end
function endContact(a, b, collision)
mc:endContact(a, b, collision)
end
I don't believe that there is anything wrong with my main but i think it's necessary to recreate the problem (sorry if it makes this too long). Now my mc.lua is where I'm having the problem since im trying to animate the player themselves by giving them a jump idle and walk animation, I think i will give them a damaged and death animation later.
local anim8 = require('anim8')
mc = {}
spr_mc_walk = love.graphics.newImage("assets/mc sprites/1 Pink_Monster/Pink_Monster_Walk_6.png")
local w = anim8.newGrid(32, 32, spr_mc_walk:getWidth(), spr_mc_walk:getHeight())
walk = anim8.newAnimation(w('1-6', 1), 0.1)
spr_mc_idle = love.graphics.newImage("assets/mc sprites/1 Pink_Monster/Pink_Monster_Idle_4.png")
local i = anim8.newGrid(32, 32, spr_mc_idle:getWidth(), spr_mc_idle:getHeight())
idle = anim8.newAnimation(i('1-4', 1), 0.1)
spr_mc_jump = love.graphics.newImage("assets/mc sprites/1 Pink_Monster/Pink_Monster_Jump_8.png")
local j = anim8.newGrid(32, 32, spr_mc_jump:getWidth(), spr_mc_jump:getHeight())
jump = anim8.newAnimation(j('1-8', 1), 0.1)
obj_mc = walk
function mc:load()
self.x = 100
self.y = 0
self.width = 20
self.height = 60
self.xvel = 0
self.yvel = 0
self.maxspeed = 200
self.acceleration = 4000 -- max speed
self.friction = 3900 -- how long it takes them to reach max speed
self.gravity = 1000
self.jumpAmount = -500
self.grounded = false
self.physics = {}
self.physics.body = love.physics.newBody(Physics, self.x, self.y, "dynamic")
self.physics.body:setFixedRotation(true)
self.physics.shape = love.physics.newRectangleShape(self.width, self.height)
self.physics.fixture = love.physics.newFixture(self.physics.body, self.physics.shape)
end
function mc:draw()
love.graphics.draw(obj_mc, self.x, self.y)
end
This is most of my mc or player function, except for movement and such but this has all the code that I'm confused with. I'm pretty sure I wrote the code right I'm just confused on how to actually implement it now that I have it written down. I thought just doing the draw function would actually draw the idle version of the character but then there's where I get the error. If you need anymore code or anymore details just let me know.
The error that this is happening at is
Error
MC.lua:41: bad argument #1 to 'draw' (Drawable expected, got table)
Traceback
[C]: in function 'draw'
MC.lua:41: in function 'draw'
main.lua:30: in function 'draw'
[C]: in function 'xpcall'
I haven't done any of that for a while, but I believe obj_mc, in this case, is a table of the frames. You need to loop through them during update.
local anim8timer = 0
local anim8index = 1
local anim8rate = 0.2 -- pick an animation rate that looks good for your game
function mc:update( dt )
anim8timer = anim8timer +dt -- add delta time
if anim8timer >= anim8rate then
anim8timer = anim8timer -anim8rate -- reset timer
anim8index = anim8index +1 -- next frame
if anim8index > #obj_mc then anim8index = 1 end -- loop frames
end
end
function mc:draw()
love.graphics.draw( obj_mc[ anim8index ], self.x, self.y )
end
They may have a built-in function that accomplishes some of that, so look for anything that resembles this in the Love2D forum.
I am making an Os module that lets you create remote Operating systems but when the background frame loads in a new window just an random window loads in but it just basically gets "overwritten" by the background frame.
I have a post on scriptinghelpers: https://scriptinghelpers.org/questions/116285/instancenew-but-not-working-as-expected-module
but it seems that no one wants no one on the website knows how to do it
my code for the main Os module:
local module = {}
function module.__Version__()
local ROS = '1.00'
local ROS = tostring(ROS)
print('Version: '..ROS)
end
function module.create_environment(master)
local main = Instance.new('ScreenGui',master)
main.Name = ("ROS")
return(main)
end
function module.create_background(env)
local Frame = Instance.new('Frame',env)
Frame.Name = ('Background')
Frame.Size = UDim2.new(2,0,2,0)
Frame.Position = UDim2.new(0, 0,-0.5, 0)
Frame.BackgroundColor3 = Color3.new(0.337255, 0.290196, 1)
return(Frame)
end
function module.create_taskbar(env)
local main = Instance.new("Frame",env)
main.BackgroundColor3 = Color3.new(0, 0, 0)
main.Size = UDim2.new(2, 0,0, 45)
main.Position = UDim2.new(-0.5, 0,1, -45)
return(main)
end
function module.create_app_button(icon,env,X,Y)
local Btn = Instance.new('ImageButton',env)
Btn.Image = (tostring(icon))
Btn.Size = UDim2.new(0, 49,0, 49)
Btn.Position = UDim2.new(0, tonumber(X), 0, tonumber(Y))
return(Btn)
end
function module.create_clone_env(env)
local coloned_env = env:Clone()
coloned_env.Parent = env.Parent
end
function module.create_time_gui(env)
local main = Instance.new('TextLabel',env)
main.Size = UDim2.new(0, 115,0, 41)
main.Position = UDim2.new(1, -145,1, -44)
main.TextColor3 = Color3.new(1, 1, 1)
main.BackgroundTransparency = 1
main.TextScaled = true
main.Font = Enum.Font.Ubuntu
local assetId = 5990705305
local InsertService = game:GetService("InsertService")
local model = InsertService:LoadAsset(assetId)
model.Time_Manager.Parent = main
return(main)
end
function module.create_start_button(env)
local main_button = Instance.new('TextButton',env)
main_button.Size = UDim2.new(0, 146,0, 45)
main_button.Position = UDim2.new(0, 0,1, -44)
main_button.TextColor3 = Color3.new(0, 0, 0)
main_button.Text = "Start"
main_button.TextSize = 25
main_button.Font = Enum.Font.Arial
main_button.BorderSizePixel = 0
return(main_button)
end
function module.create_app(env)
local frame = Instance.new('Frame',env)
local round = Instance.new("UICorner",frame)
local top_frame = Instance.new('Frame',frame)
local exit_button = Instance.new('TextButton',top_frame)
local assetId = 5995055509
local InsertService = game:GetService("InsertService")
local model = InsertService:LoadAsset(assetId)
round.CornerRadius = UDim.new(0,20)
frame.Size = UDim2.new(0, 1084,0, 673)
frame.Position = UDim2.new(0.5, -542,0.5, -336)
frame.BackgroundColor3 = Color3.new(1, 1, 1)
top_frame.Size = UDim2.new(1, 0,0.003, 28)
top_frame.Position = UDim2.new(0, 0,0, 0)
top_frame.BackgroundColor3 = Color3.new(0.611765, 0.611765, 0.611765)
top_frame.BorderSizePixel = 0
exit_button.Size = UDim2.new(0, 74,0, 30)
exit_button.Position = UDim2.new(1, -74,0.5, -15)
exit_button.Text = ("X")
exit_button.BorderSizePixel = 0
exit_button.TextColor3 = Color3.new(1, 1, 1)
exit_button.BackgroundColor3 = Color3.new(1, 0, 0)
exit_button.TextStrokeTransparency = 0
exit_button.TextSize = 17
model.LocalScript.Parent = exit_button
model:Destroy()
return(frame)
end
return module
Everything works; create_taskbar(),create_time_gui(),create_start_button()
But its just the create_app()
This is what my Os-module made:
This is the OS my Os-module made:
As i said the background overwrites my create_app() is there a way to prevent this?
If maintaining the element hierarchy is important, try adjusting the ZIndex of the background frame and the app so that the two aren't fighting for which one appears on top. Elements with smaller numbers for their ZIndex will render first, meaning they will appear behind elements with larger ones.
function module.create_background(env)
local Frame = Instance.new('Frame',env)
Frame.ZIndex = 1
-- <a bunch of other code>
return Frame
end
And then make the app's ZIndex higher.
function module.create_app(env)
local frame = Instance.new('Frame', env)
frame.ZIndex = 2
-- <a bunch of other code>
return frame
end
But you should be careful. Messing with ZIndices can get really messy really quick. A better alternative would be to just set the app Frame's parent to the background Frame.
I'm trying to add a function that randomly selects objects from the table targets. I read somewhere that you can use targets[math.random(#targets)], but when I do that, it doesn't just reset one of the targets regardless of resetTarget() call, and it doesn't actually make the next target random.
local targets -- an array of target objects
local bomb = display.newImage("bomb.png")
local asteroid = display.newImage("asteroid.png")
local balloon = display.newImage("balloon.png")
targets = { bomb, asteroid, balloon }
function createTarget()
for i = 1, #targets do
local t = targets[i]
t.x = WIDTH + 50 -- start slightly off screen to the right
t.y = math.random(100, HEIGHT - 100) -- at random altitude
end
end
function resetTarget(obj)
createTarget()
end
function detectHits()
-- Do hit detection for ball against each target
local HIT_SLOP = BIRD_RADIUS * 2 -- Adjust this to adjust game difficulty
for i = 1, #targets do
local t = targets[i]
if math.abs(t.x - bird.x) <= HIT_SLOP
and math.abs(t.y - bird.y) <= HIT_SLOP then
-- Hit
isBomb(t)
isAsteroid(t)
isBalloon(t)
resetTarget(t)
updateScore()
end
end
end
This will work but you will need a forward reference to currentTarget.
What is your function to target the random target?
local newTarget = function()
local rand = math.random(1,#targets)
currentTarget = target[rand]
doSomething()
end
I am trying to use this in a project, but I cannot figure out how to place a touch event listener to each of the icons/objects in the carousel, If someone could provide a quick answer of how to do that I'd appreciate it.
local NUM_ITEMS=20;
local radiusX= 200;
local radiusY= 40;
local centerX = 240;
local centerY = 160;
local speed = 0.05;
local perspective = 3;
local carousel = display.newGroup()
local icons = {}
local function zSort(myTable, myGroup)
table.sort(myTable,
function(a, b)
return a.depth < b.depth -- depth is your custom field
end
)
for i = 1, #myTable do
myGroup:insert(myTable[i].img)
end
end
function Icon(i)
local this = {}
local icon = display.newImage(carousel, "images/icon"..i..".png")
this.angle = (i-1) * math.rad(360/NUM_ITEMS);
this.img = icon
return this
end
function update(event)
local icon
local sin = math.sin
local cos = math.cos
for i=1, NUM_ITEMS, 1 do
icon = icons[i]
local img = icon.img
img.x = cos(icon.angle) * radiusX + centerX
img.y = sin(icon.angle) * radiusY + centerY
local s = (img.y - perspective) / (centerX + radiusY - perspective)
img.xScale = s*0.25
img.yScale = s*0.25
icon.angle = (icon.angle + speed) --%math.rad(360)
icon.depth = s
end
zSort(icons, carousel)
end
for i=1, NUM_ITEMS, 1 do
local icon = Icon(i)
icons[i] = icon
end
function onTouch(event)
if(event.phase=="moved") then
speed = (event.x - centerX) / 2000;
end
end
Runtime:addEventListener("enterFrame",update)
Runtime:addEventListener("touch", onTouch)
I can't exactly understood what you really need. But if you want to add individual touch to all same icons in a localGroup, then you can add the icons as an icon array and give specific tag to each and can give individual touch, as follows:
local icons = {}
for i=1,10 do
icons[i] = display.newImage(i..".png")
icons[i].tag = i
end
local function touchIt(e)
print(e.target.tag)
--[[ icons[e.target.tag] can be used to identify
and set properties to the touched icon --]]
end
for i=1,10 do
icons[i]:addEventListener("touch",touchIt)
end
OR
if you want to identify all group elements as the same and give touch, then you can use same tag/ give userdata to all icons and can give same touch action to all group elements(as follows).
local icons = {}
for i=1,10 do
icons[i] = display.newImage(i..".png")
icons[i].tag = 1 --[[ you can also use icons[i].userdata = "icons"
(or any string)--]]
end
local function touchIt(e)
print(e.target.tag) -- It willo be 1 for all icons
--[[ icons[e.target.tag] can be used to identify
whether if it is under 'icons' --]]
--[[ or use userdata as follows --]]
print(e.target.userdata)--[[ out put is a string
identifying the group/element--]]
end
for i=1,10 do
icons[i]:addEventListener("touch",touchIt)
end
This seemed simple to do but I do not know how to monitor for continued touching. I want to touch the display or an image and as long as the user has not lifted his finger continue to rotate an Image. Here is a snip the code I have:
local rotate = function(event)
if event.phase == "began" then
image1.rotation = image1.rotation + 1
end
return true
end
Runtime:addEventListener("touch", rotate)
I want the rotation to occur until the finger is lifted from the screen.
Thanks for any advice.
How about this?
local crate = ...
local handle
local function rotate(event)
if event.phase == "began" and handle == nil then
function doRotate()
handle=transition.to(crate,
{delta=true, time=1000, rotation=360, onComplete=doRotate})
end
doRotate()
elseif event.phase == "ended" and handle then
transition.cancel(handle)
handle = nil
end
end
Runtime:addEventListener("touch", rotate)
This allows for better control of the rate of rotation. Relying on enterFrame might be problematic if you start dropping frames for some reason.
Also, the checks for handle and not handle are to accomodate multi touch. There are other ways (and better ways) to handle this but it's expedient (and shouldn't matter at all if you aren't using multitouch.)
I ended up doing this. Please post your answer if you have a better method !!
local direction = 0
function scene:move()
crate.rotation = crate.rotation + direction
end
Runtime:addEventListener("enterFrame", scene.move)
local function onButtonEvent( event )
if event.phase == "press" then
direction = 1 -- ( -1 to reverse direction )
elseif event.phase == "moved" then
elseif event.phase == "release" then
direction = 0
end
return true
end
local button = widget.newButton{
id = "rotate_button",
label = "Rotate",
font = "HelveticaNeue-Bold",
fontSize = 16,
yOffset = -2,
labelColor = { default={ 65 }, over={ 0 } },
emboss = true,
onEvent = onButtonEvent
}