I've looked around for a few hours now and cant still find a helpful answer so I've decided to ask here- How am I supposed to code a button that deletes digits in a basic calculator one by one?
Heres my script so far!: https://pastebin.com/xLj2iCHU
func _on_BDeleteDigit_pressed():
var numberAdded
var numberBefore = $NumberStuffs.get_text()
numberAdded = numberAdded.length() - 1
numberAdded[numberBefore]=("")
$Outputlabel.set_text(str(numberAdded))
This is also the error when the delete button is pressed: https://i.stack.imgur.com/8OJTI.png
I was wondering how I may make this entire thing more optimized/shorter too but maybe that's for a different question altogether,,
CodePudding user response:
Explaining the error
I'll start with the error. It says
Nonexistent function 'length' in base 'Nil'
The error is telling you that you are trying call a function called length
on something that is Nil
, but Nil
does not have a function called length
.
The problem is that you are trying to call something on Nil
. What are you trying to call? length
. So where is that? That is here:
numberAdded = numberAdded.length() - 1
So, numberAdded
is Nil
. The next question is why. So, let us see where numberAdded
got its value…
So you declare it here:
var numberAdded
Then we have this line that has nothing to do with it:
var numberBefore = $NumberStuffs.get_text()
And then the line with the error:
numberAdded = numberAdded.length() - 1
What did you expect numberAdded.length()
to be, if numberAdded
does not have a value? Of course that is an error.
By the way, the code suggests that you expected numberAdded
to be, well, a number. Which makes me wonder what you expected from this:
numberAdded[numberBefore]=("")
Yes you can do the inverted indexing thing in C or C , because it is just adding pointers. But not GDScript, you don't.
I suspect that using types would help you. For example declare numberAdded
to be an integer like this: var numberAdded:int
. Yes, GDScript has types, use them.
How to delete the last character
Let me take as reference how you add a digit:
func _on_Button1_pressed():
var currentNumber = $NumberStuffs.get_text()
currentNumber = currentNumber "1"
$NumberStuffs.set_text(currentNumber)
Alright, we are storing a string on the text
property of the node $NumberStuffs
. And we add a digit by concatenating to it.
The above code should be is equivalent to this:
func _on_Button1_pressed():
$NumberStuffs.text = "1"
If get_text
and set_text
are custom functions in GDScript, you may want to look into setget
.
Thus, the question is how to remove the last character of a string. There are several ways!
One way would be using erase
:
func _on_BDeleteDigit_pressed():
var text := $NumberStuffs.text
var length := text.length()
text.erase(length - 1, 1)
$NumberStuffs.text = text
Note that erase
is modifying the string, but the string is a copy we got from reading $NumberStuffs.text
(or calling $NumberStuffs.get_text
), which is why we need to set to $NumberStuffs.text
(or call $NumberStuffs.set_text
) anyway.
Or if you prefer:
func _on_BDeleteDigit_pressed():
var text := $NumberStuffs.get_text()
var length := text.length()
text.erase(length - 1, 1)
$NumberStuffs.set_text(text)
Alternatively, we might get a string which is like the one we have except lacking the last character. We can do that with left
(which lets you get a portion of the string from the left, there is also a right
function that does the same but from the right):
func _on_BDeleteDigit_pressed():
var length := $NumberStuffs.text.length()
$NumberStuffs.text = $NumberStuffs.text.left(length - 1)
Or, if you prefer:
func _on_BDeleteDigit_pressed():
var text := $NumberStuffs.get_text()
var length := text.length()
$NumberStuffs.set_text(text.left(length - 1))
In general we can get a string containing a portion of another string with substr
:
func _on_BDeleteDigit_pressed():
var length := $NumberStuffs.text.length()
$NumberStuffs.text = $NumberStuffs.text.substr(0, length - 1)
Or, if you prefer:
func _on_BDeleteDigit_pressed():
var text := $NumberStuffs.get_text()
var length := text.length()
$NumberStuffs.set_text(text.substr(0, length - 1))
And yes, you can modify the string by indexing it, which I believe is what you were trying. For example:
$NumberStuffs.text[-1] = "a"
Which is equivalent to:
var length := $NumberStuffs.text.length()
$NumberStuffs.text[length - 1] = "a"
Which is equivalent to:
var text := $NumberStuffs.get_text()
var length := text.length()
text[length - 1] = "a"
$NumberStuffs.set_text(text)
Will replace the last character with an "a". And yes, you could remove by doing that. That would be:
$NumberStuffs.text[-1] = ""
Which is equivalent to:
var length := $NumberStuffs.text.length()
$NumberStuffs.text[length - 1] = ""
Which is equivalent to:
var text := $NumberStuffs.get_text()
var length := text.length()
text[length - 1] = ""
$NumberStuffs.set_text(text)
By the way, I have been using :=
when declaring the variables. That declares the variable of the type of whatever I'm using to initialize them.