Discord
Login
Community
DARK THEME

what is wrong in this code?

(my english is bad sorry :/ )

checkmovement = function(x,y)

if keyboard.LEFT or keyboard.a then x -= 1 end

if keyboard.RIGHT or keyboard.d then x += 1 end

if keyboard.UP or keyboard.w then y += 1 end

if keyboard.DOWN or keyboard.s then y -= 1 end

end

is not working, but:

checkmovement = function()

if keyboard.LEFT or keyboard.a then player.x -= 1 end

if keyboard.RIGHT or keyboard.d then player.x += 1 end

if keyboard.UP or keyboard.w then player.y += 1 end

if keyboard.DOWN or keyboard.s then player.y -= 1 end

end

is working, why? What did I do wrong explain pls <3

I'm not entirely sure how to explain this, but basically, the checkmovement(x, y) function in the first result is given the player's x and y location. However, changing the values that were passed into the function doesn't change the variables that they were originally associated with. There are a few exceptions to this however. If an object or list is passed into the function, changes to parameters in the object/list will reflect on the original object/list. For example you could do:

checkMovement = function(obj)
  if keyboard.LEFT or keyboard.a then obj.x -= 1 end
  if keyboard.RIGHT or keyboard.d then obj.x += 1 end
  if keyboard.UP or keyboard.w then obj.y += 1 end
  if keyboard.DOWN or keyboard.s then obj.y -= 1 end
end

and then call checkMovement(player) to move the player.

but if you call checkmovement(player.x, player.y) with your origional code, then it will be given the numbers that are the player's coordinates, but they're just numbers. They have no connection to their original values.

In your first example, x and y are the arguments of the function. They are thus just like local variables, existing only in the course of your function and potentially masking global variables that would have the same name. As soon as the function exits, the local variables are discarded. Global variables x and y haven't been affected in the process.

Short answer don't use parameters/argument variables in microscript. warning this could make your code messy. Instead of

checkmovement = function(x,y)
end

do

checkmovement = function()
end

or use objects as arguments to functions as Abr00 said.

Very long answer... that is mostly correct (very simplified for explanation).
When you call a function, your function gets added to a stack (in this particular case). What is a stack? Well it's like a record of which function has been called in memory with all the data that is associated with that function. So when you call a function you grow this stack (we also say push the stack) that is somewhere in memory being organized for you by... "the computer" (without getting too complicated). To be efficient with memory, once a function is done doing what it's doing "the computer" reuses the memory for other functions (we call this poping from the stack). This means that behind the scenes the computer erases the memory of the unused function and allows the reassignment of the memory by other functions.

Let's say you have a main function on the stack with two variables (1 and x) and an object player. It might look something like this in memory.

|==============|     
|  variable 1  |  
|  variable x  |  
|  obj player  |  
|=====main=====|  

Now if we call checkmouvement(x, y), the computer will push this function with it's local variables to the stack. This is how it could look like in memory.

|===============|  
|   variable x  |  
|   variable y  |  
|=checkmovement=|     
|   variable 1  |  
|   variable x  |  
|   obj player  |  
|======main=====| 

Notice that even though there are two x variables (one in main and one in checkmovement), they are entirely different variables. When you are in checkmovement the closest variable is used in your case that would be the parameters/arguments (x, y). This is what we call a local variable (local to checkmovement). When you are talking about the x variable in checkmovement it only refers to the x variable in checkmovement and not the one in main (this is also called masking a global variable since they both have the same name). So when you are in checkmovement you can't use or change the x variable in main which is a completely different variable. Once checkmouvement is done doing it's if statements it just throws away the variables. The computer then shrinks the stack so that the memory can be used for other stuff. So we get back this:

|==============|     
|  variable 1  |  
|  variable x  |  
|  obj player  |  
|=====main=====|  

This is pretty much what happened in your first checkmovement version. You did calculations and then told the computer to do nothing with the local variables. So the computer just deleted them and went back to the calling function (in my example here that would be main).

To explicitly tell the computer you want to keep the values of the local variables you have to do one of three things. The first way would be to return the information with a "return statement". That would look something like this:

checkMovement = function(x, y)
  if keyboard.LEFT or keyboard.a then x -= 1 end
  if keyboard.RIGHT or keyboard.d then x += 1 end
  if keyboard.UP or keyboard.w then y += 1 end
  if keyboard.DOWN or keyboard.s then y -= 1 end
  return [x, y]
end

We have to use a list for the return statement because you can only really return one single thing from a function. Now in main you can save this returned value with a variable.

main = function()
  coords = checkMovement(5, 10)
end

Another way of telling the computer you want to keep data is to use variables that are outside the scope of the function. You can do this by simply using the desired variables that are in lower functions in the stack and not naming the variables the same or not using parameters/arguments. So instead of having this.

|===============|  
|   variable x  |  
|   variable y  |  
|=checkmovement=|     
|   variable 1  |  
|   variable x  |  
|   obj player  |  
|======main=====| 

You would change your code so that instead of using x twice in checkmovement and main you would just call the variables that are in the main function.

|===============|    
|   variable y  |  
|=checkmovement=|     
|   variable 1  |  
|   variable x  |  
|   obj player  |  
|======main=====| 

Here if your code does change the x variable in checkmovement, microStudio will know that you are talking about the variable in main which is in a "higher" global scope (it is visible since main was called first and is hence in memory). This is why your second example works. microStudio knows that the player object exists and has access to it because it is visible in the stack or in the global scope.

Finally, you can use arguments to send objects or lists to functions. Why this works is a bit complicated and weird and you need to understand a particular concept that is pointers or references. But that is not supper important for microStudio. In general, when you send an object or a list to a function the function just knows where that variable is because it knows where in memory it lives. You aren't sending a copy of the variable, but the variable itself with it's home address. So when you change it in checkmovement it changes the value for all other functions. This can be lumped in the category of just trust me it works for now, but if you want to learn more go ahead.

For more information check this absolutely great book that is completely free on the author's site: [Dive into Systems] (https://diveintosystems.org/book/C1-C_intro/functions.html#_the_stack)

Post a reply

Progress

Status

Preview
Cancel
Post
Validate your e-mail address to participate in the community