GameMaker: How to freeze enemies temporarily? - game-maker

I tried to set the Enemy.path_speed=0 and then set an alarm[0]=5, when it gets to alarm[0] it simply set Enemy.path_speed=100(the default value) again. But it does not work. enemies are frozen forever. How else can I freeze the enemies temporarily when I hit the space?

path_speed = 0 and path_speed = 100 is not good idea. As example, objects can have different speed. I use speed factor, like speed = normal_speed * k where k is 1 for normal speed and 0 for full stop.
Enemy Create event:
spd = irandom_range(5, 10) // different speed, just as example
path_start(path0, spd, 1, true)
path_position = random(1)
k = 1
Enemy Step event:
path_speed = spd * k
Controller Space key pressed event:
with (o_enemy)
k = 0
alarm[0] = 3 * room_speed
Controller Alarm0 event:
with (o_enemy)
k = 1
And finished gm-project

You just set alarm. You never decrease it. so your statement is never true and hence the objects do not move.

Related

Handle previous state in continuous rotation

Hello i have the following lua code which functionality is to rotate a point creating a circle. The problem I'm having is with initial and/or last state. Since there is a clock running whenever i stop the rotation and start again, the point jumps around. I tried saving the last value after the lfo is turned off, and then use this value in each sin and cos functions but i cannot make it work well.
Thank you!
The Code:
local last = 0
local trigger = false
function update()
t = getMillis()
T = 3000
if trigger == true then
x = math.cos(2*math.pi*( (t - last) + t) /T)
y = math.sin(2*math.pi*( (t - last) + t) /T)
end
end
function onValueChanged(key)
if key == "x" and self.values.x == 1 then
if trigger == true then
last = t
end
trigger = not trigger
end
end

Callback function choosing problem in DifferentialEquations.jl

I have an object, when it reaches a threshold, it will enter a silence period, which I use a parameter (I call it ode_status) flipping between 1 and 0 to determine whether performing the ODE or not.
The threshold is implemented by ContinuousCallback.
fucntion condition(u, t, integrator)
u[1] - threshold
end
function affect!(integrator)
integrator.p[1] = 0 # integrator.p[1] represents ode_status
flip_back_time[1] = integrator.t + 5 # define silence period = 5s
end
ContinuousCallback(condition, affect!)
Next, I want to flip back ode_status after 5s, so I use DiscreteCallback.
function condition(u, t, integrator)
integrator.p[1] == 0 &&
integrator.t >= flip_back_time[1]
end
function affect!(integrator)
integrator.p[1] = 1
end
DiscreteCallback(condition, affect!)
However, the result is not what I think. The time that ode_status flips back is not exactly after 5s. It is at 5.107... or 5.879 in another trial.
I think I misuse these callback functions. Would anyone tell me how to solve this? Thanks in advance!
This is because the next step is not exactly at the 5 seconds later time. Remember, DiscreteCallback fires only at step times, so you need to insert a tstop to tell it to stop exactly 5 seconds in the future.
function affect!(integrator)
integrator.p[1] = 0 # integrator.p[1] represents ode_status
flip_back_time[1] = integrator.t + 5 # define silence period = 5s
add_tstop!(integrator,integrator.t + 5)
end

How to create an efficient for loop to resolve the rate limit issue with twitteR?

I am quite new to TwitteR and the concept of for loop. I have come across to this code to get the followers and profiles.
This code below works fine. Not entirely sure if retry on rate limit should be set for such a long time.
#This extracts all or most followers.
followers<-getUser("twitter_handle_here")$getFollowerIDs(retryOnRateLimit=9999999)
This code below is the for loop to get the profiles.
However, I think there should be a way to use length(followers) and getCurRateLimitInfo() to better contruct the loop.
My question is that if the length(followers) = 40000 and the ratelimit = 180, then how to construct the loop to sleep with the right amount of time and to get all 40000 twitter profiles?
Any help would be much appreciated.
#This is the for loop to sleep for 5 seconds.
#Problem with this is it simply sleeps for X seconds
for (follower in followers){
Sys.sleep(5)
followers_info<-lookupUsers(followers)
followers_full<-twListToDF(followers_info)
}
Here is some code I had written for a similar purpose, First you need to define this function stall_rate_limit:
stall_rate_limit <- function(limit) {
# Store the record of all the rate limits into rate
rate = getCurRateLimitInfo()
message("Checking Rate Limit")
if(any(as.numeric(rate[,3]) == 0)) {
# Get the locations of API Calls that are used up
index = which(as.numeric(rate[,3]) == 0)
# get the time till when rates limits Reset
wait = as.POSIXct(min(rate[index,4]), ## Reset times in the 4th col
origin = "1970-01-01", ## Origin of Unix Time
tz = "US/Mountain") ## Replace with your Timezone
message(paste("Waiting until", wait,"for Godot to reset rate limit"))
# Tell the computer to sleep until the rates reset
Sys.sleep(difftime(wait, Sys.time(), units = "secs"))
# Set J = to 0
J = 0
# Return J as a counter
return(J)
} else {
# Count was off, Try again
J = limit - 1
return(J)
}
}
Then you can run your code something like this:
callsMade = 0 ## This is your counter to count how many calls were made
limit = 180 ## the Limit of how many calls you can make
for(i in 1:length(followers)){
# Check to see if you have exceeded your limit
if(callsMade >= limit){
# If you have exceeded your limit, wait and set calls made to 0
callsMade = stall_rate_limit(limit)
}
### Execute your Code Here ... ###
callsMade = callsMade + 1 # or however many calls you have made
}

Is there a way to always start at 0 using math.sin() Lua

Edit: This question is about Roblox Lua.
I'm using math.sin(tick()) to get a variable number and would like for it to always start at 0. Is this possible using math.sin? Is there something else I can use other than tick() to make this work?
Example:
for i = 1, 10 do
local a = math.sin(tick())+1
print(a)
wait()
end
wait(1)
for i = 1, 10 do
local a = math.sin(tick())+1
print(a)
wait()
end
My goal is to have this number start at 0 every time and then increase from there. So, it would start at 0 then increase to 2 and then decrease back to zero and continue modulating between 0 and 2 for as long as I continue calling it. Using the example above the number starts at any arbitrary number between 0 and 2.
I took a different approach and came up with this. It does exactly what I wanted to do with math.sin(tick()). If anyone knows other ways to accomplish this I would like to know.
local n = 0
local m = 0
local Debounce = true
local function SmoothStep(num)
return num * num * (3 - 2 * num)
end
while Debounce do
for i = 1, 100 do
wait()
m = m+.01
n = SmoothStep(m)
print(n)
if not Debounce then break end
end
for i = 1, 100 do
wait()
m = m+.01
n = SmoothStep(m)
print(n)
if not Debounce then break end
end
end
To non-Roblox users: tick() returns the local UNIX time. wait(t) yields the current thread for t seconds, the smallest possible interval being roughly 1/30th of a second.
Given that math.sin(0) equals 0, what you have to do is subtract the tick() inside the loop with the time the loop began at. This should make the expression inside math.sin start at roughly 0 at the beginning of the loop.
local loopstart = tick()
for i = 1, 10 do
local a = math.sin(tick() - loopstart)+1
print(a)
wait()
end

Game Maker not recognizing variable

Attempting to set up a targeting array for a MMO-style game in GameMaker8 Pro, I have this code in the create event for the player's character, which is and has been running perfectly fine:
j = 0
i = 0
g = 0
for (i=100000; i<1000000; i+=1) if instance_exists(i) {if i.object_index = enemy {global.ttarget[j] = i j+=1} if i.object_index = rk or i.object_index = sage {global.etarget[g] = i g += 1}}
global.rmtargets = j
global.etargets = g
Then running this code in the step event for the player character:
h = 0
g = 0
i = 0
for (i=0; i<global.rmtargets; i+=1) global.target[i] = 0
global.target[0]=101139
for (h = 0; h<global.rmtargets; h+=1){hv = -1
for (g = 0; g<global.rmtargets; g+=1){if global.ttarget[g].range > hv {hv = global.ttarget[g].range}}
global.target[h] = hv
global.ttarget[h] = -1}
Returns this error message:
ERROR in
action number 1
of Step Event
for object rk:
Error in code at line 8: for (g = 0; g<global.rmtargets; g+=1){if global.ttarget[g].range > hv {hv = global.ttarget[g].range}}
at position 61: Unknown variable range
Even though I have this in the create event for the enemy:
range = 0
range = distance_to_object(rk)
And I've used this sort of syntax all over:
global.target[target].threat[s] += damage
Help? Any ideas why Game Maker won't recognize the variable?
My best guess is that one or more of the enemy instances have been destroyed between the player create event and the step event where the error happens. Maybe a better solution would be to iterate over all the enemies using the with() construct, that is faster and you can be sure that all the instances you are working with actually exist.
try putting brackets around the object variable. I have had trouble references from a reference extension before.
(global.ttarget[g]).range
or even save it to a new variable
for (g = 0; g<global.rmtargets; g+=1)
{
curr_target = global.ttarget[g]
curr_target.range
}
Instead of using global. before each instance of the variable in the code, you could also initialize it with the command:
globalvar (variable), (variable2);
Then you would be able to use the variable without global. in front of it :)
If object rk is not the enemy then there is no global range variable detectable by object rk. Variables initialized without var or globalvar only apply for the object it was defined in.
First of all, put round brackets in if conditions.
Second you should give more informations about your environment and programming logic and IMO stop using all these global variables.
Anyway, from what i understood of what you're doing, try to use the with keyword:
with(global.ttarget[g]) {
other.hv = range;
}

Resources