Logitech LUA Script: MoveMouseRelative not working as expected - lua

I am trying to write a script which will spin my character 180 degrees in game while holding lctrl and right clicking. This script works, but takes forever to spin around because of the sleep timer:
EnablePrimaryMouseButtonEvents(true)
function OnEvent(event, arg)
if (event == "MOUSE_BUTTON_PRESSED" and arg == 2 and IsModifierPressed("lctrl")) then
for i = 0, 96 do
MoveMouseRelative (125,0)
Sleep (1)
end
end
end
If I increase MouseMoveRelative beyond 125, it starts to move the mouse in the wrong direction. No matter what value I use (I've tried lots of values between 100 and 12,000), it always moves the mouse a very small distance either left or right.
If I eliminate the Sleep function, the results are inconsistent. It usually rotates my character between 80-140 degrees. I suspect this is because MoveMouseRelative starts by getting the current mouse position and it requires a delay before the position it gets is accurate.
Any guidance as to why MouseMoveRelative doesn't work correctly for values above 125? Or any advice on how to quickly move the mouse 12,000 relative units on the x-axis instantaneously?

If I increase MouseMoveRelative beyond 125, it starts to move the mouse in the wrong direction.
The allowed range is -127...+127
I suspect this is because MoveMouseRelative starts by getting the current mouse position
No.
It does not ask the current mouse position.
It invokes SendInput() without flag MOUSEEVENTF_ABSOLUTE to simulate relative mouse movement.
how to quickly move the mouse 12,000 relative units on the x-axis instantaneously?
for i = 0, 96 do
MoveMouseRelative (125,0)
end
If I eliminate the Sleep function, the results are inconsistent. It usually rotates my character between 80-140 degrees.
Try more precise version of Sleep()
for i = 0, 96 do
MoveMouseRelative (125,0)
FastSleep(1)
end

Or any advice on how to quickly move the mouse 12,000 relative units
on the x-axis instantaneously?
If you want to move relative 12000 instantaneously, why do you move 97 steps of 125 with 1ms delays?
97*125 is 12125
Why not MoveMouseRelative(12125, 0) ?
According to the manual MoveMouseRelative takes "a few milliseconds" to complete.
1 ms is not a few. Reading the mouse position too early will give you the starting position. So I would presume that spamming relative movements which refer to that position might cause problems.

Related

Need help moving the mouse cursor relative using a Logitech G910

I'm trying to get some bog standard code to work on my Logitech G910 keyboard. It's nothing much...mostly it is used to help edit a shopping list on a website. To help remove one item at a time I simply have it left click, replace the current number (single digit item) with a 0, move the mouse relative to the right, click, press the up key five times, and move it relative back to the left so that it's in position.
Now I am well aware that I could just as easily change the code to move the mouse somewhere on the screen, and that's all well and good, but since this is a learning opportunity for me, I might as well exploit it for all it's worth for latter use in the future. That said this is the headache I'm having...when the cursor is moved relative to it's location on the screen that's one value, but to move it back into position that's a different value, or in this case if it's moved 100 to the right, it has to be moved -65 to the left to be in the same position. This, of course, makes no sense what-so-ever.
To add to the problem, as if this wasn't bad enough on it's own, the cursor doesn't always end up in the same place when the code is ran. Sure...it will be in place on the first execution of the code, but on the second it's out of place, third it might be in place, and the fourth it might be out of place, etc. While this is all a headache, I can at least say this much: when it comes to using relative commands it sure is nice to have it, especially where using an arrow key won't place it in the exact position it needs to be in. Slightly off mark? No problem...just have it go up -2 on the y axis and it's all golden. :D
That aside, to make things a little easier, here is the snippet of code that I am using.
if (event == "G_PRESSED" and mkey == 1 and arg == 3) then
--Delete the value and replace with a 0 on site
PressAndReleaseMouseButton(1)
Sleep(100)
PressAndReleaseKey("backspace")
PressAndReleaseKey("0")
Sleep(100)
MoveMouseRelative(100, 0)
PressAndReleaseMouseButton(1)
Sleep(100)
PressAndReleaseKey("up")
PressAndReleaseKey("up")
PressAndReleaseKey("up")
PressAndReleaseKey("up")
PressAndReleaseKey("up")
Sleep(200)
MoveMouseRelative(-65, -2)
end

How to change the velocity in each frame in Love2D?

I'm trying to code a Pong game on Lua using the framework Love2D with some extra features. Among others, I want curves to occur. In order to do so, I'm trying to implement the trajectory of horizontally launched projectiles. I have a ball table with a position attribute for x (ball.x) and another for y (ball.y). I, also, have a an attribute for the x velocity (ball.dx) and another for the y velocity (ball.dy). Finally, I have an acceleration variable (gravity)
In my game, if the paddle moves and the ball hits it, the ball should follow and horizontal curve. In order to create my curves, I want to change the y-axis velocity on each frame in order to make my ball move in an arc across the screen. The main issue that I have is that I don't know how to change this velocity in each frame in order to create the expected arc. The most recent attempt that I made was to create a while loop like the following code. However, it creates an infinite loop. Can someone enlighten me please?
Clarification:
-Player.x and player.y are the player coordinate
-Player2.x and Player2.y are the opponent coordinate
-This piece of code is inside another if statement detecting a collision. It is inside the love.update(dt) function.
Thank you so much!
if love.keyboard.isDown("up") and distanceBetween(ball.x,ball.y,player.x,player.y)>30 then
ball.dy=0
while CollisionDetector(ball.x,player2.x,ball.y,player2.y, player2.width,player2.height,ball.size)==false or ball.x>0 or ball.y-20>0 or ball.y+20<love.graphics.getHeight() do
ball.dy=ball.dy+gravity*dt
ball.y=ball.y+ball.dy
end
end
I believe the snippet you've provided is a part of love.update function. (At least it should be.) That function is supposed to perform a single step of the game at a time and return. It is not supposed to handle the whole flight in a single call.
In your particular case, while loop expects the ball to move, but that is not something that will happen until the loop and encompassing function end.
In general, to simulate ongoing processes you'll have to store the information about such process. For example, if you want gravity be dependent on the paddle movement direction, then you'll have to modify the corresponding variable and store it between the call.
In your code, there are multiple other design flaws that make it do not what you think it should do. With some functions and code parts left to be implemented by yourself, the code outline would look as follows:
function collides(ball,player)
return (ball.x,player.x,ball.y,player.y, player.width,player.height,ball.size)
end
function love.update(dt)
handle_paddle_movements()
--handle the ball-paddle interaction
if collides(ball,player1) or collides(ball,player2) then
ball.dx=-ball.dx
if love.keyboard.isDown("up") then
--store the info you need to know about the interaction
ball.d2y = -gravity
else if love.keyboard.isDown("down")
ball.d2y = gravity
else
ball.d2y = 0
end
end
handle_the_wall_collision()
--ball movement code should be separate from collision handling
--concrete equations can be whatever you want
ball.x = ball.x+ball.dx*dt
ball.dy = ball.dy + ball.d2y * dt
ball.y = ball.y + ball.dy * dt
end

Animation in LOGO

I have created a nice pattern using the following one line code
repeat 36 [repeat 10[fd 10 rt 36] rt 10]
Now I want this to appear as if it is rotating. I have tried to clear the screen and then rotate the turtle a at a specific angle and then print the pattern again. But there is something completely wrong in my logic. Can anybody help?
In order to accomplish animation, you need an interpreter which supports it. The interpreter must be one which renders the entire output before displaying it (doesn't show the turtle movement during drawing), and it also must support the wait command (or something similar to it). An example of an interpreter that meets these qualifications would be the one at www.logointerpreter.com. Here's an example which spins your wheel a full rotation and works with that interpreter:
ht
repeat 360
[
clean
repeat 36 [repeat 10[fd 10 rt 36] rt 10]
wait 10
rt 1
]
As you can see, the outer loop draws 360 separate frames. After drawing each frame, it waits 10 milliseconds, so you can see the frame. It then rotates the turtle one degree before clearing the screen and beginning the drawing of the next frame. If you need a little more control, you could also store the starting angle for each frame in a variable, like this:
ht
make "start 0
repeat 360
[
cs
rt :start
repeat 36 [repeat 10[fd 10 rt 36] rt 10]
wait 10
make "start (:start + 1)
]

Corona SDK: Moving a player Up and Down

I have a player who is navigating in space. Since it is space, there is not gravity therefore no parabolic trajectory. The player is just going in a horizontal line from left to right. The player is not actually moving, but the background is, so it looks like he is. The x value is fixed.
I have 2 buttons that help the player avoid obstacles like asteroids. One button gives the player upward force, the other one downward force. The following are the functions called when those buttons are pressed.
function moveUp( event )
if event.phase == "ended" then
player:applyForce(0, 8, player.x, player.y)
player:setSequence("jump")
jumpChannel = audio.play(jumpSound)
end
return true
end
function moveDown( event )
if event.phase == "ended" then
player:applyForce(0, -8, player.x, player.y)
player:setSequence("jump")
jumpChannel = audio.play(jumpSound)
end
return true
end
The problem with this implementation is that whenever a force is applied the player keeps going in that direction. Then you have to apply force in the opposite direction and he will keep going in that direction forever. That is not what I want. What I want is :
when UP is pressed, player goes up for certain value (say 50 px) in Y. Then the player keeps going in the horizontal direction from left to right in the new altitude.
When DOWN is pressed, player goes down certain value. Then the player keeps going in the horizontal direction from left to right in the new altitude.
What is the best way to accomplish this? Can I do this using the applyForce function or is there another method? Thanks in advance for your time!
You have to remember that F=ma: if force applied is 0, a is 0, which means velocity does not change. You have two choices:
apply an opposite force that will decrease the speed, and stop when speed is 0. Every Body has myBody.linearDamping factor which you could set to non-zero. If that doesn't work, you can apply your own damping: you make it proportional to Body velocity, so you need an enterFrame event handler that updates the force based on current velocity:
function enterFrame(e)
local v = player:getLinearVelocity()
player:applyForce(- a * v)
end
Here the "a" is damping, some arbitrary number (0 is what you have now; the larger it is, the faster the player will return to 0 velocity). I haven't checked whether the applyForce() is additive (adds to existing forces) or absolute (replaces existing). But you get the idea.
directly move the player:
function moveUp( event )
if event.phase == "ended" then
player:setLinearVelocity(0, 8) -- pixels/sec
You will still need an enterFrame handler to monitor position and setLinearVelocity(0,0) when desired position reached.
You will get smoother, more "realistic" motion with option 1.

Changing a moving objects direction of travel in corona

I'm new to Corona and looking for a little help manipulating moving objects:
Basically I want a set up where when I can click on a moving object, a dialog box will pop up giving me the option to change the speed of the object and the vector of travel. I'm pretty sure I can figure out the event handling and the dialog but I'm stuck on simply changing the direction of travel to the new vector
in a simple example, I have a rect moving up the screen as follows:
obj1 = display.newRect(500, 800, 10, 40)
transition.to(obj1,{x=500, y = 100, time = 40000})
I know I can change the speed by adjusting the time, but if I use
obj1:rotate(30)
to turn the object 30 degrees, how do I make it travel in the new direction?
Should I be using physics - linear impulse for example, instead of transitions?
Apologies if this is a stupid question but I have searched without success for a solution.
This sounds like what you are trying to do. You would have to modify bits to fit your code but this is a working example. So if you copy it to a new main.lua file and run it you can see how it works. (Click to rotate obj).
local obj = display.newRect(50,50, 10, 40)
local SPEED = 1
local function move(event)
obj.x = obj.x + math.cos(math.rad(obj.rotation)) * SPEED
obj.y = obj.y + math.sin(math.rad(obj.rotation)) * SPEED
end
local function rotate(event)
obj.rotation = obj.rotation + 45
end
Runtime:addEventListener("enterFrame", move)
Runtime:addEventListener("tap", rotate)
Basically I used the "enterFrame" event to 'move' the rectangle, by recalculating the x and y of the objects location using its rotation (which is easy enough to modify) every frame.

Resources