The global.game_width not set before reading it - dialog

global variable name 'game_width' index (100009) not set before reading it.
at gml_Object_objTextbox_Create_0 (line 16) port_x = (global.game_width
- box_width - port_width) * 0.5
I created in Game global.game_height and width, but it doesn't work. What am I supposed to do?

Looks like the objtextbox object is created earlier than the game object.
And because the game object creates the variable, it cannot find the global.game_width before it's initialised.
Inside the Text Layer Properties on the left sidebar, you'll see all the objects that are loading inside the room. The game object is not shown there, so you've to place the game object inside the room (and change the order they're loaded first) to let it work.
I'm not sure if this still applies as you've already rewrote your code, but that's something to remember for the next time.

Related

get_node crashing game when node is deleted

First of all, I'm new to programming in general so I'm kind of assuming there's a simple answer to this question, I just couldn't seem to find it anywhere.
I'm making a simple platformer game with enemies that move toward the player. I used this code in the enemy's script underneath the physics process to get the player position:
player_position = get_parent().get_node("Player").get_position
However, upon the player being queue_freed when health reaches 0, the game crashes immediately and I get a null error due to there being no Player node. How can I work around this?
You could just set $Player.visibility to false instead of freeing, or you could check if the player exists first using get_parent().has_node("Player")
When you destroy the player, the physics process function is still trying to get the player node, even though it doesn't exist. So, as Lucas said, you could replace:
player_position = get_parent().get_node("Player").get_position
with something like...
if get_parent().has_node("Player"):
player_position = get_parent().get_node("Player").get_position
(Before setting player_position, it will check if the player node even exists)
I think you could use weakref (documentation here).
If you declare a weak reference:
var player_ref: WeakRef = null
and store that reference:
func store_player_node():
var player_ref = weakref(get_parent().get_node("Player"))
Then you can access that reference later:
if player_ref.get_ref():
player_position = player_ref.get_ref().get_position
Weakref has advantage over using get_parent().get_node("Player"). Let's imagine the following scenario:
Player dies and its node is removed from the parent node's children.
New node is created with name Player and added to the scene tree at the same place as the dead Player.
get_parent().get_node("Player") will return a node and the code will not crash. However, it will be a new Player node, not the old one, and I think this is usually undesired.
I hope this helps!

Godot, GDScript - Play Animation on Right Click

Any insight onto why this code doesn't work?
When I right click, the game crashes and gives the error: "Invalid call. Nonexistent function 'play' in base 'Array'".
func _ready():
anim_Play = get_tree().get_nodes_in_group("AnimationPlayer")
func_input(event):
if Input.is_action_pressed("aim"):
anim_Play.play("AimSights")
I guess from your code that you are trying to get a reference to your AnimationPlayer node, it fails and you get an Array instead.
It happens because you are using get_nodes_in_group (which returns an Array of nodes in a group), instead of get_node, which returns a node.
Invalid call. Nonexistent function 'play' in base 'Array
Means your are trying the call the play method (found in AnimationPlayer) from an Array object, that does not exist.
You would get AnimationPlayer like
var anim_Play = get_node("./path/to/your/AnimationPlayer")
Response to your question
get_nodes_in_group(group) returns an Array of nodes that are both in the SceneTree and in group group.
Let's say there is one AnimationPlayer node in the group "AnimationPlayer". We'll fetch it like:
var anim_player = get_tree().get_nodes_in_group("AnimationPlayer")[0]
Notice the [0]. That is called an accessor. We access the array at element 0. Now, we can call play:
anim_player.play("AimSights")
Do note: it is an error to access a non-existent element of an array.
Recommendation
This seems like an inappropriate use of groups. I recommend you use a node path, like svarog suggested, if the animation player is in the same scene as the script.
Additionally, it will help to read or google about some fundamental programming concepts: specifically Objects and Arrays.
Lastly, read over the scenes and nodes page from Godot's documentation: https://docs.godotengine.org/en/3.1/getting_started/step_by_step/scenes_and_nodes.html
The whole getting started guide on the Godot's documentation is an invaluable resource for learning Godot. It will help you greatly and it's not too long of a read.
Good luck!

NAudio - Does a new instance of OffsetSampleProvider have to be created for each playback

As explained here, OffsetSampleProvider can be used in order to play a specific portion of an audio file. Like this:
AudioFileReader AudioReader = new AudioFileReader("x.wav");
OffsetSampleProvider OffsetProvider = New OffsetSampleProvider(AudioReader);
OffsetProvider.SkipOver = TimeSpan.FromSeconds(5);
OffsetProvider.Take = TimeSpan.FromSeconds(8);
myWaveOut.Init(OffsetProvider);
myWaveOut.Play();
The above example will play an audio for 8 seconds, starting at second 5. However, if I want to play it again, it will not play, unless I set the Position property of the AudioFileReader to 0, and re-create a new instance of OffsetSampleProvider from it. So I would like to know if I'm missing something, or this is the way that OffsetSampleProvider should be used (and if it does, do I have to free any resources related to it).
You could copy the code for OffsetSampleProvider and add a Reset method to it. I'd also avoid using SkipOver for performance reasons and just set the CurrentTime of the AudioFileReader to 5 seconds directly before you play.

COMException^ on FilePicker PickSingleFileAsync() call

I'm trying to make a game (Universal DX11 application) and at some point I need access to image library to allow user to select avatar. But for some reason call of PickSingleFileAsync on picker rises an exception.
Windows::Storage::Pickers::FileOpenPicker^ openPicker = ref new Windows::Storage::Pickers::FileOpenPicker();
openPicker->SuggestedStartLocation = Windows::Storage::Pickers::PickerLocationId::PicturesLibrary;
openPicker->ViewMode = Windows::Storage::Pickers::PickerViewMode::Thumbnail;
// Filter to include a sample subset of file types.
auto filters = openPicker->FileTypeFilter;
filters->Clear();
filters->Append(".png");
openPicker->PickSingleFileAsync();// same exception with create_task(...);
Seems like the sample works only if I put it into UI thread. How can I use picker from my own thread?
UPD: HRESULT:0x80004005
Ok, I just decided to call dipatcher's RunAsync to execute this code. But I still have no idea why I cannot open picker inside non-UI thread.

How to update a MATLAB GUI in the background?

I have a MATLAB GUI and a separate application that writes data to a file.
I'd like my MATLAB GUI to check the file periodically, and update the GUI when it changes.
In Java, I'd use a SwingUtils.Timer(sp?) object to do something like this. Does MATLAB have timer functionality? I could write a java class and do it I suppose, but want something quick and dirty for a demo, preferably pure MATLAB.
You can create timer objects in MATLAB using the TIMER function. For example, this creates a timer object which should execute the function myFcn once every 10 seconds after the timer is started:
timerObject = timer('TimerFcn',#myFcn,'ExecutionMode','fixedRate',...
'Period',10.0);
Timers are started and stopped using the functions START and STOP. You should also always remember to delete them with DELETE when you're done using them. You can find more info on using timers in the MATLAB documentation.
It is worth noting, that if you are wanting to update axes object in a GUIDE GUI, there's an additional bit of "trickery" needed to make this work. You must either change the HandleVisibility property of the axes object in GUIDE, or you must explicitly acquire the handle. To do this, change the timerObject construction as follows (This is assuming the axes window in your GUIDE generated GUI is called axes1):
timerData.axes = handles.axes1;
timerData.n = 1; % some state needed for the plots.
timerObject = timer('TimerFcn',#myFcn,...
'ExecutionMode','fixedRate',...
'Period',10.0,...
'UserData', timerData);
then in myFcn, we need to reference the axes object. Specifically:
function [] = myFcn(timerObj, event)
timerData = get(timerObj, 'UserData');
plot(timerData.axes, (1:n)/n, sin(20*2*pi*(1:n)/n));
line( (1:n)/n, cos(20*2*pi*(1:n)/n, 'Parent', timerData.axes);
timerData.n = timerData.n + 1;
set(timerObj, 'UserData', timerData);
end

Resources