Discord
Login
Community
DARK THEME

How do I use the mouse buttons individually?

Hi! I haven't found a way to use the mouse buttons separately. I needed to track the mouse buttons that I had just pressed or released. I did it this way:

if mouse.press and mouse.left then local prLEFT = 1 end

if mouse.release and not mouse.left then local relLEFT = 1 end

if mouse.press and mouse.right then local prRIGHT = 1 end

if mouse.release and not mouse.right then local relRIGHT = 1 end

But if you use this code, then the mouse buttons cannot be used at the same time. This would be necessary if my character in the game could jump (by pressing the right button) and shoot (by pressing the left button). But if we click "Jump", then shooting won't work - so I can't use the mouse in the game this way. I haven't really found a way to use the buttons separately. Does anyone have any ideas how to do this? I think it could be something like mouse.press.left.

Hi there :)

Not sure if I understand the question right, so my apologies if this goes into the wrong direction.

mouse.left and mouse.right only change their state when they are pressed, so there is really no need to check for the mouse.press in addition to it. Here an example how I do it sometimes (simplified):

draw = function()
  screen.clear()
  if mouse.left then
    prLeft = 1
    screen.fillRect(-20,0,20,20,"#f00")
  else
    prLeft = 0
    screen.drawRect(-20,0,20,20,"#f00")
  end

  if mouse.right then
    prRight = 1
    screen.fillRect(20,0,20,20,"#0f0")
  else
    prRight =0
    screen.drawRect(20,0,20,20,"#0f0")
  end
end

:embed https://microstudio.io/TinkerSmith/test/A99K3GBU/

Just run it and you will see. So in essence you could just say prLeft = mouse.left and it will change its value from 0 to 1 accordingly.

As said, if that's not what you're looking for, more details please :)

P.S. here a modified version where I check the mouse buttons in the update loop and react somewhere else accordingly (draw in this example)

init = function()
end

update = function()
  prLeft  = mouse.left
  prRight = mouse.right
end

draw = function()
  screen.clear()
  if prLeft then
    screen.fillRect(-20,0,20,20,"#f00")
  else
    screen.drawRect(-20,0,20,20,"#f00")
  end

  if prRight then
    screen.fillRect(20,0,20,20,"#0f0")
  else
    screen.drawRect(20,0,20,20,"#0f0")
  end
end

Hello TinkerSmith! Thank you for such a detailed answer. As always, you are very responsive! Using your example, I'll show you what the problem is, adding mouse.press:

if mouse.press and mouse.left then
  screen.fillRect(-20,0,20,20,"#f00")
else
  screen.drawRect(-20,0,20,20,"#f00")
end

if mouse.press and mouse.right then
  screen.fillRect(20,0,20,20,"#0f0")
else
  screen.drawRect(20,0,20,20,"#0f0")
end

Now look at how the program works differently. Now the squares are colored once when the buttons are pressed (this is what I wanted to achieve). This is something like mouse.press.left or mouse.press.right. The fact is that the mouse object does not have fields such as mouse.press.left or mouse.press.right. Using the example I gave, you can track the mouse button click, but look what happens if you hold down the right mouse button and then press the left - the left button will not work! It won't work because if the right button is clamped, then mouse.press = 0. And for the condition of coloring squares, it is necessary that mouse.press == 1 and mouse.press.left == 1. That's actually the problem. The fact is that I do not know how to write code so that the mouse buttons are tracked separately and independently.

I'm sorry if I didn't make myself very clear, I tried :-)

I might need another coffee and read it again, lol. The way I see it, the mouse.left response acts actually as mouse.press.left It is only true when the left button is pressed. But as said, more coffee and I try to wrap my head around it :)

In my example i get the feedback for when the left button is pressed, when the right one is pressed, and both together. So I could jump and shoot as I please?

Maybe i would need to see the whole picture, you can always DM on Discord with details

Regarding your first post, would this work for you :

prLEFT  =  mouse.left  
relLEFT = 1-mouse.left

I'm sorry that the code is so badly formatted, I do not know how to do it effectively, I use indents - but I got confused with them :-)

This is a modified lesson from microStudio. By clicking the left mouse button, the character jumps, by clicking the right mouse button, the character changes the sprite (variable hero_name).

Press and hold the left mouse button - the character jumps constantly. Press and hold the right mouse button - the sprite changes and will remain so until we remove our finger from the button.

 init = function()
    gameover = 0
    running = 0
    blades = [200,300,400]
    passed = [0,0,0]
    score = 0
    position = 0
    speed = 2
  end

update = function()

local LEFT = mouse.left
local RIGHT = mouse.right

if RIGHT then
  hero_name = "hero.1"
else hero_name = "hero.0"
end

if gameover>0 then
  gameover = gameover+1
  if gameover>50 then init() end
elsif running then
  position = position+speed
  speed = speed + 0.001

if LEFT and hero_y == 0 then
   hero_vy = 7
   audio.beep("square tempo 20000 volume 10 span 100 C4 to C6")
end

hero_vy -= 0.3
hero_y = max(0,hero_y+hero_vy)

for i=0 to blades.length-1
  if blades[i]<position-120 then
    blades[i] = position+280+random.next()*200
    passed[i] = 0
  end
  if abs(position-blades[i])<10 then
    if hero_y<10 then
      running = 0
      gameover = 1
      audio.beep("saw tempo 10000 volume 50 span 50 C2 to C4 to C2 to C4")
    elsif not passed[i] then
      passed[i] = 1
      score += 1
      audio.beep("saw tempo 960 volume 50 span 20 C6")
  end
  end
  end
  else
    if mouse.pressed then running = 1 end
  end
end

draw = function()
screen.fillRect(0,0,screen.width,screen.height,"rgb(176,227,227)")

for i=-6 to 6 by 1
  screen.drawSprite("wall",i*40-position%40,-80,40)
end

screen.drawSprite(hero_name,-80,-50+hero_y,20)

for i=0 to blades.length-1
  screen.drawSprite("blade",blades[i]-position-80,-50,20)
end

screen.drawText(score,120,80,20,"#FFF")
if gameover then
  screen.fillRect(0,0,screen.width,screen.height,"rgba(255,0,0,.5)")
  screen.drawText("GAME OVER",0,0,50,"#FFF")
elsif not running then
  screen.drawText("READY?",0,30,50,"#FFF")
end
end

The question is how to make the character jump once, even if the left mouse button remains clamped?

The second question is how to make the character change his sprite once (he should blink), even if the right mouse button is pressed and held?

And finally the third point: the buttons must work under any conditions. It should not be the case that if the left button is clamped, the right one will not work and vice versa. Like for example with this example:

if mouse.press and mouse.left then
  screen.fillRect(-20,0,20,20,"#f00")
else
  screen.drawRect(-20,0,20,20,"#f00")
end

if mouse.press and mouse.right then
  screen.fillRect(20,0,20,20,"#0f0")
else
  screen.drawRect(20,0,20,20,"#0f0")
end

Please let me know if you know how to do it! Maybe I don't understand something and make a mistake somewhere.

Here is a link to this example: https://microstudio.io/Constantine_RetroGamer/test2/FWWH3T2H/

Aah, that is a completely different problem then :)

So you need a 'one shot' marker. I suspect once the jump is finished the left mouse button can be checked again? So you need to memorize that the jump is active. I'm on the phone, so can't provide an example. But there are many games that do that, mainly to prevent double jumps.

Sort of like this:

JUMP = 0 // in init section

// in update loop
  if JUMP==0 then     // check only when no jump
    JUMP = mouse.left // will be 0 or 1
  end 

// somewhere else 
  if JUMP then 
   // do jump stuff
   // when all done then
   JUMP = 0 // allows mouse check again
  end

Sorry for the pseudo code mess, as said, I'm on phone. But I hope it somehow shows what I try to explain.

Folks on PC, give that man a proper example :)

Exactly as tinkersmith said :). This is what I would normally do to for a once-off key/mouse press:

init = function()
  mousepress=false
end

update = function()
  if mouse.press then // checks if mouse just pressed
    mousepress=true // pressed mouse
  end
  if mouse.release then
    mousepress=false // released mouse
  end
  if mousepress then // mousepress=true, draw green rect
    screen.fillRect(0,0,100,100,"rgb(0,255,0)") // This would be replaced with your 'jump' script
    mousepress=false // finished 'jump' script, mousepress is then false even if mouse is still pressed
                     // this works because mouse.press only checks if the mouse was just pressed
  else
    screen.fillRect(0,0,100,100,"rgb(255,0,0)") // mousepress=false, draw red rect
  end
end

Which results in this, where you should see the rectangle turn green for a frame when clicking for the first time:

:embed https://microstudio.io/this_name_is_taken/example/KPD2P2W2/

As a sidenote, if you want each click to last longer you can instead use a timer-type system:

init = function()
  mousetime=30 // how long each click lasts in frames (30 in this case)
  mousetimer=0 // timer for each click
end

update = function()
  if mouse.press then
    mousetimer=-mousetime // set the timer to how long each click lasts
  end
  if mouse.release then // if not clicking mouse, reset timer
    mousetimer=0
  end
  if mousetimer<0 then // If the click timer is above 0 the green rect is drawn
    screen.fillRect(0,0,100,100,"rgb(0,255,0)")
    mousetimer+=1 // add to timer if it is below 0, until it reaches 0
  else
    screen.fillRect(0,0,100,100,"rgb(255,0,0)")
  end
end

Hopefully that answered your question :)

Hello @this_name_is_taken! Hello again @TinkerSmith!

@this_name_is_taken i tried to use your example. Let's see what I got.

Let me remind you what I'm trying to achieve: mouse buttons should be tracked separately and independently. In the examples below, a cube will be used. The cube can jump and change color.

The task set:

1. The cube must jump once every time the left mouse button is pressed (in my examples, it can also jump only if it is on the ground). The cube should not jump if the button remains clamped.

2. The cube should change color once every time the right mouse button is pressed (blink). The cube should not change color if the button is still clamped.

3. The jump should not interfere with the color change of the cube. Changing the color of the cube should not interfere with the jump in any way.

4. The "jump" must be performed exclusively with the left mouse button. The "color change" should be performed exclusively with the right mouse button.

Let's see if I managed to meet all the conditions.

I made my code examples based on what @this_name_is_taken replied to me.

Example 1:

init = function()
  LeftMousePress=false
  RightMousePress=false
end

update = function()
  if mouse.press then
    LeftMousePress=true
    RightMousePress=true
  end
  
  if mouse.release then
    LeftMousePress=false
    RightMousePress=false
  end
  
  if LeftMousePress and cub_y==0 then
    cub_vy=7
    LeftMousePress=false
  end

  if RightMousePress then
    cub_color="rgb(0,255,0)"
    RightMousePress=false
    else cub_color="rgb(255,0,0)"
  end

  cub_vy-=0.3
  cub_y=max(0,cub_y+cub_vy)
end

draw = function()
  screen.clear("rgb(142,217,255)")
  screen.fillRect(0,-80,400,40,"rgb(0,170,170)")
  screen.fillRect(0,-50+cub_y,20,20,cub_color)
end

It was obvious that it wouldn't work. The cube reacts to any mouse buttons and jumps and changes color at the same time. Also, the cube cannot jump if the right mouse button remains clamped. In addition, it cannot change color if the left mouse button remains clamped. Thus, conditions 3 and 4 are not met.

Well, I excluded the color change to check if the right mouse button would interfere with the jump:

init = function()
  LeftMousePress=false
end

update = function()
  if mouse.press then
    LeftMousePress=true
  end
  
  if mouse.release then
    LeftMousePress=false
  end
  
  if LeftMousePress and cub_y==0 then
    cub_vy=7
    LeftMousePress=false
  end

  cub_vy-=0.3
  cub_y=max(0,cub_y+cub_vy)
end

draw = function()
  screen.clear("rgb(142,217,255)")
  screen.fillRect(0,-80,400,40,"rgb(0,170,170)")
  screen.fillRect(0,-50+cub_y,20,20,"rgb(0,255,0)")
end

It turns out that it interferes. Hold down the right mouse button and you will see that it is now impossible to make a jump!

In addition, the jump is still performed with any mouse button - which contradicts the condition. Therefore, I will significantly rewrite and shorten the code. Now I will also track the left mouse button at the same time as mouse.press.

update = function()
  if mouse.press and mouse.left and cub_y==0 then
    cub_vy=7
  end

  cub_vy-=0.3
  cub_y=max(0,cub_y+cub_vy)
end

draw = function()
  screen.clear("rgb(142,217,255)")
  screen.fillRect(0,-80,400,40,"rgb(0,170,170)")
  screen.fillRect(0,-50+cub_y,20,20,"rgb(0,255,0)")
end

Well, now the jump is made only by pressing the left mouse button. In addition, the code has become much shorter. But the right mouse button still interferes with making the jump.

Now I will return the ability to change the color of the cube:

Example 2:

update = function()
  if mouse.press and mouse.left and cub_y==0 then
    cub_vy=7
  end

  if mouse.press and mouse.right then
    cub_color="rgb(0,255,0)"
    else cub_color="rgb(255,0,0)"
  end

  cub_vy-=0.3
  cub_y=max(0,cub_y+cub_vy)
end

draw = function()
  screen.clear("rgb(142,217,255)")
  screen.fillRect(0,-80,400,40,"rgb(0,170,170)")
  screen.fillRect(0,-50+cub_y,20,20,cub_color)
end

Condition 3 is not met.

OK, I'll rewrite the first example. Now I use everything: the variables "LeftMousePress" and "RightMousePress", as well as "mouse.left" and "mouse.right".

Example 3:

init = function()
  LeftMousePress=false
  RightMousePress=false
end

update = function()
  if mouse.press and mouse.left then
    LeftMousePress=true
  end
  if mouse.press and mouse.right then
    RightMousePress=true
  end
  
  if mouse.release and not mouse.left then
    LeftMousePress=false
  end
  if mouse.release and not mouse.right then
    RightMousePress=false
  end
  
  if LeftMousePress and cub_y==0 then
    cub_vy=7
    LeftMousePress=false
  end

  if RightMousePress then
    cub_color="rgb(0,255,0)"
    RightMousePress=false
    else cub_color="rgb(255,0,0)"
  end

  cub_vy-=0.3
  cub_y=max(0,cub_y+cub_vy)
end

draw = function()
  screen.clear("rgb(142,217,255)")
  screen.fillRect(0,-80,400,40,"rgb(0,170,170)")
  screen.fillRect(0,-50+cub_y,20,20,cub_color)
end

Paste this code into the editor and check. You will immediately realize that example 3 does the same thing as example 2. Only the code has become twice as long!

Now the most successful example is the 2nd example. It does not comply with only one third condition, and is also much shorter and clearer.

Let's talk about him. The third condition is not met because mouse.press==1 only when any mouse button is pressed for the first time, then mouse.press==0. But while any mouse button is clamped, when another button is pressed, mouse.press==0 is still used. Therefore, for example, one condition for the jump will not be met:

if mouse.press and mouse.left and cub_y==0 then //With the right mouse button held down, mouse.press=false
  cub_vy=7
end

Thus, I failed to meet all four conditions. The question is still open to me. You can send your code examples where all 4 conditions will be met.

@this_name_is_taken thanks for the example with timers, I haven't tried to do this, it will definitely come in handy for me!

After some inspection in the console of the third example (as I thought that the 3rd example should work), I decided that the problem is definitely mouse.press, as you deduced. The solution to this seems to be to manually make a workaround for mouse.press:

init = function()
  LeftMousePress=false
  RightMousePress=false
  RightJustPressed=false // manual workaround for mouse.press (separate for both buttons)
  LeftJustPressed=false 
end

update = function()
  if mouse.left and not LeftJustPressed then
    LeftMousePress=true
    LeftJustPressed=true // this is used instead of mouse.press - once this is set to true it can only be set to false by releasing                         
                         // the associated button. Only when it is false can it be set to true again.
  end
  if mouse.right and not RightJustPressed then
    RightMousePress=true
    RightJustPressed=true
  end
  if not mouse.left then // mouse.release runs into the same problem as before, but is thankfully unnecessary as we are now checking 
                         // individual buttons
    LeftMousePress=false
    LeftJustPressed=false // reset the JustPressed variables for the reasons noted above
  end
  if not mouse.right then
    RightMousePress=false
    RightJustPressed=false 
  end
  if LeftMousePress and cub_y==0 then
    cub_vy=7
    LeftMousePress=false
  end

  if RightMousePress then
    cub_color="rgb(0,255,0)"
    RightMousePress=false
    else cub_color="rgb(255,0,0)"
  end

  cub_vy-=0.3
  cub_y=max(0,cub_y+cub_vy)
end

draw = function()
  screen.clear("rgb(142,217,255)")
  screen.fillRect(0,-80,400,40,"rgb(0,170,170)")
  screen.fillRect(0,-50+cub_y,20,20,cub_color)
end

This code then produces this result, which seems to meet your criteria :) :

:embed https://microstudio.io/this_name_is_taken/example2/95K8ZWCZ/

I notice that this is exactly what I need!!! The incredible maestro :-) I do not know how soon I would have guessed to do it. I haven't studied the code yet, but I can see from the example that it works the way I wanted. I express my gratitude to you!

No problem - that's what the community is for. Thank you as well for the level of detail in your posts, it made it much easier to answer the question. :)

Good to see the community working together :-)

Post a reply

Progress

Status

Preview
Cancel
Post
Validate your e-mail address to participate in the community