(PsychoPy) Cannot assign fixed (independent of RT) duration to rating scale component - psychopy

For my fMRI experiment, I would like to have a rating window of a fixed 4s duration, i.e.
1) if a response is given in this window, the component stays active (marker is displayed) for the remaining time, i.e. 4-rt
2) if no response is given in this window, the component ends and the script moves on to the next trial
I've set the duration property of my rating scale component to 4s, but the scale still awaits a response indefinitely. The maxTime property is of no help, as that just deactivates the component rather than end it.
On the other hand, if a response is given, the component ends right then, making the rating window effectively of variable duration, which I do not want.
I've defined a blank text component to stay on the screen for 4-ratingScale.rt and thus act as a "buffer" that makes the total duration fixed. But I get the error "AttributeError: 'RatingScale' object has no attribute 'rt'". If instead of .rt I use .getRT(), I do get a value, however it does not seem to correspond to the time passed between the scale being displayed and a response being given.
Thanks for any thoughts!

Related

Godot - Input.is_action_just_pressed() runs twice

So I have my Q and E set to control a Camera that is fixed in 8 directions. The problem is when I call Input.is_action_just_pressed() it sets true two times, so it does its content twice.
This is what it does with the counter:
0 0 0 0 1 1 2 2 2 2
How can I fix thix?
if Input.is_action_just_pressed("camera_right", true):
if cardinal_count < cardinal_index.size() - 1:
cardinal_count += 1
else:
cardinal_count = 0
emit_signal("cardinal_count_changed", cardinal_count)
On _process or _physics_process
Your code should work correctly - without reporting twice - if it is running in _process or _physics_process.
This is because is_action_just_pressed will return if the action was pressed in the current frame. By default that means graphics frame, but the method actually detect if it is being called in the physics frame or graphic frame, as you can see in its source code. And by design you only get one call of _process per graphics frame, and one call of _physics_process per physics frame.
On _input
However, if you are running the code in _input, remember you will get a call of _input for every input event. And there can be multiple in a single frame. Thus, there can be multiple calls of _input where is_action_just_pressed. That is because they are in the same frame (graphics frame, which is the default).
Now, let us look at the proposed solution (from comments):
if event is InputEventKey:
if Input.is_action_just_pressed("camera_right", true) and not event.is_echo():
# whatever
pass
It is testing if the "camera_right" action was pressed in the current graphics frame. But it could be a different input event that one being currently processed (event).
Thus, you can fool this code. Press the key configured to "camera_right" and something else at the same time (or fast enough to be in the same frame), and the execution will enter there twice. Which is what we are trying to avoid.
To avoid it correctly, you need to check that the current event is the action you are interested in. Which you can do with event.is_action("camera_right"). Now, you have a choice. You can do this:
if event.is_action("camera_right") and event.is_pressed() and not event.is_echo():
# whatever
pass
Which is what I would suggest. It checks that it is the correct action, that it is a press (not a release) event, and it is not an echo (which are form keyboard repetition).
Or you could do this:
if event.is_action("camera_right") and Input.is_action_just_pressed("camera_right", true) and not event.is_echo():
# whatever
pass
Which I'm not suggesting because: first, it is longer; and second, is_action_just_pressed is really not meant to be used in _input. Since is_action_just_pressed is tied to the concept of a frame. The design of is_action_just_pressed is intended to work with _process or _physics_process, NOT _input.
So, apparently theres a built in method for echo detection:
is_echo()
Im closing this.
I've encountered the same issue and in my case it was down to the fact that my scene (the one containing the Input.is_action_just_pressed check) was placed in the scene tree, and was also autoloaded, which meant that the input was picked up from both locations and executed twice.
I took it out as an autoload and Input.is_action_just_pressed is now triggered once per input.

Player doesn't spawn correctly in procedural generated map

I've followed "Procedural Generation in Godot: Dungeon Generation" by KidsCanCode #https://www.youtube.com/watch?v=o3fwlk1NI-w and find myself unable to debug the current problem.
This specific commit has the code, but I'll try to explain in more detail bellow.
My main scene has a Camera2D node, a generic Node2D calles Rooms and a TileMap, everything is empty.
When the script starts, it runs a
func make_room(_pos, _size):
position = _pos
size = _size
var s = RectangleShape2D.new()
s.custom_solver_bias = 0.5
s.extents = size
$CollisionShape2D.shape = s
A few times and it fills $Rooms using .add_child(r) where r is a instance of the node that has the make_room() function. It will then iterate over $Rooms.get_children() a few times to create a AStar node to link all the rooms:
The magic comes when make_map() is called after afterwards, it fills the map with non-walkable blocks and then it carves the empty spaces, which works fine too:
There is a find_start_room() that is called to find the initial room, it also sets a global variable to the Main script start_room, which is used to write 'Start' on the map using draw_string(font, start_room.position - Vector2(125,0),"start",Color(3,4,8))
When I hit 'esc' it runs this simple code to instance the player:
player = Player.instance()
add_child(player)
player.position = start_room.position + Vector2(start_room.size.x/2, start_room.size.y/2)
play_mode = true
The problem comes when spawning the player. I tried doing some 'blind' fixing, such as adding or subtracting a Vector2(start_room.size.x/2, start_room.size.y/2) to player.position to see if I could make it fall within the room, to no avail.
Turning to the debugger didn't help, as the positions expressed by the variable inspectors don't seem to mean anything.
I tried implementing a simple 'mouse click print location':
print("Mouse Click/Unclick at: ", event.position)
print("Node thing",get_node("/root/Main/TileMap").world_to_map(event.position))
And also a 'start_room' print location:
print(get_node("/root/Main/TileMap").world_to_map(start_room.position))
And a when player moves print location, written directly into the Character script:
print(get_node("/root/Main/TileMap").world_to_map(self.position))
Getting results like the ones bellow:
Mouse Click/Unclick at: (518, 293)
Node thing(16, 9)
(-142, 0)
(-147, -3)
So, the player doesn't spawn on the same position as the start_room and the mouse position information is not the same as anything else.
Why is the player now spawning correctly? How can I debug this situation?
EDIT1: User Theraot mentioned about how the RigidBody2D is doing some weird collisions, and from what I understood, changing their collision behavior should fix the whole thing.
There's a section on the code that -after generating the random rooms- it removes some of the rooms like this:
for room in $Rooms.get_children():
if randf() < cull:
room.queue_free()
else:
room.mode = RigidBody2D.MODE_STATIC
room_positions.append(Vector3(room.position.x, room.position.y, 0))
From what I understand, if the room is randomly selected it will be deleted using queue_free() OR it will be appended to a room_positions for further processing. This means if I shift all the rooms to a different collision layer, the player/character instance would be alone with the TileMap on the same collision layer.
So I just added a simple room.collision_layer = 3 changing this section of the code to
for room in $Rooms.get_children():
if randf() < cull:
room.queue_free()
else:
room.mode = RigidBody2D.MODE_STATIC
room.collision_layer = 3
room_positions.append(Vector3(room.position.x, room.position.y, 0))
It doesn't seem to have changed anything, the player still spawns outside the room.
Do you see the rooms spread outwards?
You didn't write code to move the rooms. Sure, the code gives them a random position. But even if you set their position to Vector2.ZERO they move outwards, avoiding overlaps.
Why? Because these rooms are RigidBody2D, and they do push other physics objects. Such as other rooms or the player character.
That's the problem: These rooms are RigidBody2D, and you put your KinematicBody2D player character on top of one of them. The RigidBody2D pushes it out.
The tutorial you followed is exploiting this behavior of RigidBody2Ds to spread the rooms. However you don't need these RigidBody2D after you are done populating your TileMap.
Instead, you can store the start position in a variable for later placing the player character (you don't need offsets - by the way - the position of the room is the center of the room), and then remove the RigidBody2Ds. If you want to keep the code that writes the text, you would also have to modify it, so it does not fail when the room no longer exists.
Alternatively, you can edit their collision layer and mask so they don't collide with the player character (or anything for that matter, but why would you want these RigidBody2Ds that collide with nothing?).
Addendum post edit: Collision layers and mask don't work as you expect.
First of all, the collision layer and mask are flags. The values of the layers are powers of two (1, 2, 4, 8...). So, when you set it to 3, it is the layer 1 plus the layer 2. So it still collides with a collision mask of 1.
And second, even if you changed the collision layer of the rooms to 2 (so it does not match the collision mask of 1 that the player character has). The player character still has a layer 1 which match the collision mask of the rooms.
See also the proposal Make physics layers and masks logic simple and consistent.
Thus, you would need to change the layer and mask. Both. in such way that they don't collide. For example, you can set layer and mask to 0 (which disable all collisions). The algorithm that populates the TileMap does not use the layer and mask.

MediaControllerCompat returning wrong state

In my app, I am instantiating a MediaControllerCompat with a valid Token and here is the issue that I am encountering:
The value that I am getting from mController.getPlaybackState().getPosition() is the length of my audio instead of its position, and last time I update the state on the MediaSession object I did set it with the correct playback position.
It is probably something in my code, but just wondering if there is anything in the instantiation process of MediaControllerCompat that can make this happen.

Variable is changing without the program running

On the website I am writing, there is an object called person which holds a variable called balance. At one point I call the set method and change balance's value to 100 from 0.
I noticed there was a problem when the at the end running my program the value of balance was back to 0. Placing a break point where it changes balance with the code
User.person.balance = Date.Parse(txtBal_Updated.Text)
it goes through the setter and changes the value from 0 to 100. I stop the program right after this change and use the tracer to look at the value of balance and it say 100. But if I look at person and through person to balance it shows that it is 0. Then when I look back at balance it has suddenly changed back to 0 without me stepping through the program at all. I am very confused how an objects value can change without the program running.
What is the thing that you call “your program” ? Is it some JavaScript in a Web page ? How do you run it ?
What is “the tracer” ? With what tool(s) you inspect the variables ?
Your problem makes me think strongly of variable scope. You may experience some garbage-collecting too.
You focus on the variables themselves. In your situation, I suspect first the instrumentation.

Cancelling a setInterval delay while it is running in AS2

Is this possible?
I have a file in which a movie clip is launched when the user roles over another element. To make the user experience more pleasant this happens after a 3 second delay using setInterval. Is there a way of stopping and resetting this time if the user rolls off the element before the 3 seconds is up?
var xTimer = setInterval(wait, 3000);
function wait(){
show('all');
play('all');
clearInterval(xTimer);
}
Above is the code I have used to set the delay, and below is the code I had assumed would interrupt and reset the timer.
invisBtn.onRollOut = function(){
rollover_mc.gotoAndStop(1);
stop();
clearInterval(xTimer());
trace('off');
}
Any help on this would be massively appreciated.
First, the setInterval & clearInterval functions use a Number variable to work.
setInterval() returns a Number variable, and clearInterval() takes that Number in parameter to remove the previous started interval. Here you seem to keep the interval ID inside a function variable instead of a Number one.
Thus, clearInterval(xTimer()); should in reality be clearInterval(xTimer); (without the parenthesis after xTimer).
And secondly, so you can use it in the invisBtn.onRollOut function, just be sure that the xTimer variable is scoped correctly (not inside a function where the invisBtn.onRollOut isn't also), and not on different keyframes of the timeline (timeline keyframes in Flash tends to forget the code you've written on it as soon as the reading head passes onto a new keyframe of the layer which has the code on it).
Feel free to ask more details if you need !