How do I drag sprites during execution in Scratch?
This is covered on the Scratch Wiki.
boisvert's answer is technically correct, however, his script will always drag the sprite from it's center. Using a slightly more advanced script will drag from the spot it was picked up, more like the padlock:
when green flag clicked
forever
if <<mouse down?> and <touching [mouse-pointer v]?>>
repeat until <not <mouse down?>>
set [offset x v] to ((x position) - (mouse x))
set [offset y v] to ((y position) - (mouse y))
go to x: ((mouse x) + (offset x)) y: ((mouse y) + (offset y))
end
else
wait until <not <mouse down?>>
end
(The wiki link above has this is visual blocks format.)
Click the padlock next to the sprite name. It will look open; then the sprite becomes draggable in the executable version.
Alternatively, you could program its dragged behaviour with a script:
if <mouse down>
set x to (mouse x)
set y to (mouse y)
it can be made more clever, to follow the mouse at an offset position, with a delay, snap to a position when dropped, highlight something as it passes over it... If you use a script your choices are limitless.
For a quick and simple route, all you have to do is click the info button of the sprite: Click here for image 1.
After that you should find the box that says: can drag in player and click that: Click here for image 2.
This is actually it. Now whenever somebody plays your game they can drag the sprite. You just have to let them know that it is possible since most project don't allow it.
If you would not mind if the sprite is still draggable when the script is not running then you press the i button at the top-right corner when the sprite is selected. Then, you press Can drag in player. However, this does not work for Scratch 3.0 and so you would need to use my other method, scripting.
when green flag clicked
forever
if <<mouse down?> and <touching [mouse-pointer]>>
go to [mouse-pointer]
You can use the <mouse down?> boolean, the touching [mouse pointer]? and the variables(mouse x) and (mouse y) to get the mouse's coordinates and to detect if the mouse is down. Here is how you can do it:
when green flag clicked //when the green flag is clicked,
forever //do this forever,
if touching [mouse pointer]? AND mouse down? //touching the mouse pointer? The mouse down?
set x to (mouse x) //set my x position to the mouse's x position.
set y to (mouse y) //set my y position to the mouse's y position.
end if loop //if everything above is not true, don't go to mouse
end forever loop //repeat this process forever!
If you need more help with other things, you ca follow me if you want to #endermite334.
Sprites are by default draggable in Scratch 3.0. You can change that by using set drag mode [not draggable]
Related
I'm trying to implement this in Physica, my Scratch-based physics engine. I tried adding it and the ball glitched out (couldn't move on the x axis at all). Does anyone know how to do this?
If it's a physics engine, then every object should have added variables for speed, and then you manipulate the speed:
To change the speed:
When ... (whenever your drag release is)
set Vx to 10
this example has a drag function:
https://en.scratch-wiki.info/wiki/Draggable_Sprite_Feature
In the physics engine, speed constantly moves your object:
When green flag
forever
add Vx to x
add Vy to y
#boisvert pretty much answered your question. But if you want to sense drag releasing, use this code:
when green flag
set drag mode to draggable
forever
wait until touching mouse pointer and mouse down
wait until not mouse down
point toward mouse pointer
set V to distance to mouse pointer * 2
along with this:
when green flag
forever
set V to V*0.9
move V steps
if on edge, bounce
It's not the most perfect code, but it will work
Example: https://scratch.mit.edu/projects/558479500/
I would like to detect the exact location of the mouse click within the 3x3 grid displayed on the screen. How can this be done in MIT scratch? Any suggestions?
There are two ways to do this.
You could create 9 sprites, hide, and use the When this sprite clicked event...
...but it would be a whole lot of unnecessary sprites.
Or you can do the following:
As #PullJosh said, you can use the mouse x and y blocks. Just do some math:
You know that the stage goes from X: -240 to 240, Y: -180 to 180.
Just put that into some code to detect ranges, below is a link to a project that is an example of this:
This project
(Note: This assumes the grid boxes are the same size.)
when greenFlag pressed
forever
if <mouse down?> then
set (lastMouseClickX) to (mouse x)
set (lastMouseClickY) to (mouse y)
end
wait until <not<mouse down?>>
end```
This is pretty simple if you want to involve 2 variables in this:
All you really need to do is to set the mousex position to a variable and the mousey position to a variable after the sprite detects a click on it. Here is an example:
I want to remap mouse wheel down to Ctrl+Alt+E but only when the mouse touches the right edge of the screen. I know how to remap the mouse wheel scroll but i don't know how to make it work only when the mouse touch the edge of the screen:
WheelDown::^!e
I hope someone can help me with the rest of the script.
Consider this, if you mean touching the right edge, it means that the X coordinate of the mouse is equal the maximum usually, the screen's width (±1 pixel).
#If can be used to create context-sensitive hotkeys. See #If
A_ScreenWidth can be used to get the screen's width. See A_ScreenWidth
CoordMode can set coordinates mode to be relative to the whole screen. See CoordMode
MouseGetPos gets the current mouse coordinates. See MouseGetPos
Please take the time to analyse this example.
Example script
#If MouseIsTouchScreenRight()
WheelDown::^!e
#If
MouseIsTouchScreenRight() {
CoordMode, Mouse, Screen ;set coordinates mode to be relative to the whole screen
MouseGetPos, mX ;store the X coordinate of the mouse in `mX`
if ( abs(A_ScreenWidth-mX) <= 2 ) ;if the "absolute" difference is within 2 pixels
return true
return false
}
How can I smooth out animations in Scratch? Mainly, I want it such that when you press and hold the right arrow, it goes right without any noticeable jittering. Plus, scratch makes you wait a second to repeat when you hold an arrow. How can I smooth this stuff out?
I know it's an old question. But in case somebody is looking for a solution, check out this scratch project: http://scratch.mit.edu/projects/276298/
Just add forever loop and inside this loop check if arrow key is pressed. If it is - move.
This way you won't be dependent on keyboard repeat rate.
With Scratch, you can get very smooth motion using Glide with long distances or intervals. However, the disadvantage of this method is that the Glide operation must finish before the sprite can do any sensing, such as edge or collision detection. This is often undesirable.
The small delay that you are talking about when you press a key, is actually directly tied to the repeat rate of your keyboard. When you press a key on your keyboard, that key event is sent, but then there is a small delay before the repeat kicks in. If you can find a way to change your system keyboard repeat rate, this would carry over into Scratch.
There is a limit to how much optimizing you can do in Scratch. It is, after all, a very basic(but very fun), entry-level programming environment. :)
You could do until "arrow not pressed"
when arrow pressed
repeat
move (or glide)
until not arrow pressed
then it will not check key pressing at set intervals, making the move smoother.
You can do this:
When flag pressed
forever
if (right arrow pressed?) then
change xs by 1
xs = xs * 0.8
change x by (xs)
That checks everytime if the right arrow is pressed, and if yes, it changes the variable xs by one. Later, it multiplies xs by 0.8, so the value sightly decays.
Then it changes the sprite's x by the var xs.
This is an oldie but a goodie, and as others have suggested you need to keep checking that the key is still pressed and repeat whatever action you need until it's not pressed any more. Like so:
This is because when you hold down a key the computer will wait a short pause before accepting that you really do want the the key press to be repeated.
This is a combination of concepts called debouncing (or throttling) an input and is useful on all kinds of electronics and computing). If it didn't do that allll ooofff yoourr ttyping wwoould look likke thhhis.
One way you can do that is use variables and custom blocks to make arguments to smooth out motion. Add a variable called speed x and use a forever change X by speed X. I don't have any snapshots or examples, but you can use scripts in the custom block to smoothly glide it.
You could do this for smooth x move:
forever
change x by (([amount] - (x position)) / [divide])
Which 'amount' is how much that you want to move and 'divide' is how smooth is that.
(Do the same with smoothing y)
Or you can also smooth x and y move:
forever
go to x: (([amount] - (x position)) / [divide]) y: (([amount] - (x position)) / [divide])
Also, you can make the sprite glide smoothly to the mouse:
forever
go to x: (((mouse x) - (x position)) / [divide]) y: (((mouse y) - (x position)) / [divide])
I am trying to drag some shapes in HTML canvas but I am encountering a problem with respect to determining the change in mouse coordinates [dx,dy]
First of all, there is no problem in the coordinates themselves, stored in mousePos as the rollover effects work flawlessly. What I am doing is, upon first entering the shape, saving the mouse coordinates.
pos = {x : mousePos[0] , y : mousePos[1]};
Then, onMotion updates the coordinates everytime the mouse moves as well as recording the current position
dx=mousePos[0]-pos.x;
dy=mousePos[1]-pos.y;
pos = {x : mousePos[0] , y : mousePos[1]};
Then I add the dx and dy values to the shapes coordinates (lets take a simple rectangle as an example)
ctx.fillRect(0+this.dx,0+this.dy,100+this.dx,100+this.dy);
as long as the mouse doesn't move too fast, it works relatively well (not perfect though). If I move the mouse very quickly, without going out of the window, the rectangle does not catch up with the mouse. I can understand if there is a delay catching up to the mouse, but how can the delta values be off? Clearly we know where we started, and even if dozens/hundreds of pixels are skipped in the process, eventually the mouse should stop and the correct delta values should be calculated.
Any help would be greatly appreciated as I have hit a conceptual wall here.
You might try to get e.layerX-Y when the onMotion is fired to get the real position instead of the delta. This way it can't be "off".
To use this, place your shape into a div with style="padding:0px;margin=0px;" , because the position is relative to the parent block.