ROBLOX: get a handler object in Touched function - roblox

I have a simple map with 2 gates (blue and red) and a ball.
I need a listener function for checking ball collisions with a gate.
I have created a server script:
function goal(hitter)
if hitter.Name == "ball" then
print(Instance.Parent)
print(hitter)
print("============")
end
end
game.Workspace.gate_blue.Touched:Connect(goal)
game.Workspace.gate_red.Touched:Connect(goal)
I need to detect in the function which gate has been hitted.
How can I get the gate name in the function?

One way you could reuse the goal functionality is to make a higher-order function :
function onGoalTouched(goalName)
return function(hitter)
if hitter.Name == "ball" then
print(Instance.Parent)
print(hitter, goalName)
print("============")
end
end
end
local blueGate = game.Workspace.gate_blue
local redGate = game.Workspace.gate_red
blueGate.Touched:Connect(onGoalTouched(blueGate))
redGate.Touched:Connect(onGoalTouched(redGate))

Related

Roblox Pathfinding Back and forth movement when reaching the destination requires jumping

For some reason when the destination target is placed somewhere where it requires jumping to get to my NPC is moving towards it while keep switching between moving back and forth.
Code:
local path = PathfindingService:CreatePath()
local waypoints
local currentWaypointIndex
local function followPath(destinationObject)
path:ComputeAsync(enemyNPC.HumanoidRootPart.Position, destinationObject.Position)
waypoints = {}
if path.Status == Enum.PathStatus.Success then
waypoints = path:GetWaypoints()
currentWaypointIndex = 1
humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
else
error("Path not really working")
end
end
local function onWaypointReached(reached)
if reached and currentWaypointIndex < #waypoints then
currentWaypointIndex += 1
if waypoints[currentWaypointIndex].Action == Enum.PathWaypointAction.Jump then
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
end
if reached and currentWaypointIndex >= #waypoints then
print("Target reached!")
animationTrack:Stop()
end
end
local function onPathBlocked(blockWaypointIndex)
if blockWaypointIndex > currentWaypointIndex then
followPath(destination)
end
end
path.Blocked:Connect(onPathBlocked)
humanoid.MoveToFinished:Connect(onWaypointReached)
followPath(destination)
(I delted the top part of the code with some local variables because it didn't let me post the whole thing without saying my post is mostly code)
Does anybody know what am I doing wrong?
You're looking for the action in the PathWaypoint, which is an PathWaypointAction Enum. You have to determine whether the PathWaypoint is a Walk or Jump action. Currently, you're doing MoveTo() regardless of whether it has to jump or not.
So, in your code:
if waypoints[currentWaypointIndex].Action == Enum.PathWaypointAction.Jump then
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
else
​humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
end

Roblox; making destroyed parts reappearing

I've made a game where you step on a specific tile this part gets destroyed. I want to make it that after a certain amount of time this destroyed block will reappear, now you might wonder why I just don't make the part invisible and make it lose it's player collision. I have not done this because I don't know how to make the Texture on top of the part transparency 1.
You could make a copy of the part, then do the destruction, and put the copy back into its place after a few seconds:
function onTouched(hit)
-- see if it was a player that touched the part
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
if (plr == nil) then return end
-- make backup of the part and its parent
local part = workspace.Part
local backup = part:Clone()
local backupParent = part.Parent
part:Destroy() -- do some cool effect for the destruction of it...
spawn(function()
wait(5)
-- put part back in place
backup.Parent = backupParent
backup.Touched:Connect(onTouched)
end)
end
workspace.Part.Touched:Connect(onTouched)
If you just want it to disappear you could also just remove it from the object tree temporarily by setting its Parent to nil:
function onTouched(hit)
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
if (plr == nil) then return end
local part = workspace.Part
local backupParent = part.Parent
part.Parent = nil
spawn(function()
wait(5)
part.Parent = backupParent
end)
end

Sprite Kit: Waiting to call a function until condition X is met

I'm working on a game (top-down shooter) and have run into a bit of a snag. Up to this point, I've spawned enemies with functions that just work with delays:
Wave One Function - Delay 3, spawn enemies //
Wave Two Function - Delay 6, spawn enemies
I do this because I haven't found a way to wait for all actions in a given function to complete before calling the next - as things stand, functionWaveOne calls functionWaveTwo, which calls functionWaveThree (etc).
This has worked until now. What's changed is I want two enemies to remain on-screen and until they're dead, I don't want the next wave to come. My initial solution to this was to have a running count of how many enemies died in wave four:
Detect collision -> Apply Damage -> Check if dead -> If yes, deadWaveFourEnemies++
Here's my problem: I have a primary weapon that's two parallel lasers, so they have potential to collide with an enemy at exactly the same time. This results in false positives, making the dead enemy count go higher than it should. I even tried adding an "am I alive" function to the enemy class, but to no avail.
Have any of you got a recommendation on how to either call functions in a better way or to get around these false positives? Thanks!
In case it helps:
if([enemySprite.name isEqual: #"shooter"]){
enemyShooter *enemyClass = (enemyShooter *)enemySprite;
itDied = [enemyClass doDamageWithAmount:secondaryWeaponDamage];
scoreIncrease = [enemyClass getScoreIncrease];
stillAlive = [enemyClass amIAlive];
}
[weaponSprite removeFromParent];
if(itDied){
[self increasePlayerScoreBy:scoreIncrease];
if(inWaveFour == 1 && stillAlive == 1){
waveFourKilled++;
NSLog(#"Seconday / Number killed: %i", waveFourKilled);
}
}

I am trying to make NPC that is randomly walking and attacks players

I am trying to make NPC that is randomly walking and attacks players. Can someone help me?
A good starting place for NPCs that walk around and attack players are zombies. I would recommend looking at the R15 Zombie with #### sounds model in the Toolbox. Once you drag it into the Workspace, there is a script in there called Script that is fairly straightforward in how it moves the zombie around to attack other humanoid characters.
Well, that is complex in itself, but if you are new to scripting, it might be best to just get the free-modeled zombie in the toolbox, and then change it's appearance through the explorer window. If you want to go the long route, it might be better to learn how to use the function :MoveTo. The Roblox Developer website provides good info on how to use these things. As for attacking people, just put a script in the arm that damages on touch. Here's something that might work, (put it in the same model as the humanoid):
local larm = script.Parent:FindFirstChild("Left Arm")
local rarm = script.Parent:FindFirstChild("Right Arm")
function findNearestTorso(pos)
local list = game.Players:GetPlayers()
local torso = nil
local dist = 10
local temp = nil
local human = nil
local temp2 = nil
for x = 1, #list do
temp2 = list[x]
if temp2.Character:IsA("Model") then
temp = temp2.Character:FindFirstChild("Torso")
human = temp2.Character:FindFirstChild("Humanoid")
if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
if (temp.Position - pos).magnitude < dist then
torso = temp
dist = (temp.Position - pos).magnitude
end
end
end
end
return torso
end
while true do
wait(0.1)
local target = findNearestTorso(script.Parent.Torso.Position)
if target ~= nil then
script.Parent.Humanoid:MoveTo(target.Position, target)
end
end
For the damage script, you can use this if you add it to one of the arms:
script.Parent.Touched:connect(function(part)
if part.Parent:FindFirstChild("Humanoid") then
part.Parent.Humanoid:TakeDamage(30)
end
end)

How can i move to right by dragging the scene to the left in Corona?

Well, i want to make levels to my game like in Angry Birds. So how can i move from left to right by dragging the scene? What should i use for this in Corona? Thanks.
Insert all the images on the screen you want to drag (presumably everything besides any GUI objects) into a group.
From there write a function with a touch listener assigned to the group itself. It would look something like this, supposing you're app is iPhone landscape mode.
local function constrainMap ()
if localGroup.x < -480 then
localGroup.x = -480
elseif localGroup.x > 0 then
localGroup.x = 0
end
end
Runtime:addEventListener("enterFrame", constrainMap)
local function moveMap (event)
if event.phase == "began" then
localX = localGroup.x
elseif event.phase == "moved" then
localGroup.x = localX + (event.x - event.xStart)
end
end
localGroup:addEventListener("touch", moveMap)
In the above case the localGroup contains all visual elements and the constrainMap function is used to prevent the user from scrolling the map off the screen.