How to make a bitmap follow mouse? - Gideros Forum

#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

#### Top Posters

• ar2rsawseen 6991
• SinisterSoft 3836
• hgy29 2541
• keszegh 2104
• antix 2056
• OZApps 1983
• totebo 1764
• oleg 1609
• hgvyas123 1412
• techdojo 1321
• phongtt 1029
• Mells 1024
• MikeHart 1020
• john26 995
• GregBUG 962
• pie 960
• talis 911
• Scouser 898
• Apollo14 876
• MoKaLux 866

# How to make a bitmap follow mouse?

Hi.

I'm trying to make the bitmap follow my mouse movement. I don't want it to move if the distance to mouse where less than a treshold (say 20px).

Any snippet on how to do it?

Regards.

• edited December 2019 Accepted Answer
 ```local cos,sin=math.cos,math.sin function angle(x1,y1, x2,y2) return math.atan2(y2-y1, x2-x1) end   function distance(x1,y1, x2,y2) return (x2-x1)^2+(y2-y1)^2 end   function lerp(a, b, t) return a + t * (b - a) end   FollowSprite = Core.class(Sprite)   function FollowSprite:init(speed, color, distance) self.g = Pixel.new(color, 1, 32, 32) self.g:setAnchorPoint(.5,.5) self:addChild(self.g) self.tx = 0 self.ty = 0 self.speed = speed self.dist = distance end   function FollowSprite:follow(x, y) self.tx = x self.ty = y end   function FollowSprite:update(dt) local x, y = self:getPosition() local distSq = distance(x, y, self.tx, self.ty)   if (distSq > self.dist^2) then local t = 0.1 x = lerp(x, self.tx, t) y = lerp(y, self.ty, t) self:setPosition(x, y) local a = angle(x, y, self.tx, self.ty) self:setRotation(^>a) end end   function FollowSprite:update2(dt) local x, y = self:getPosition() local distSq = distance(x, y, self.tx, self.ty)   if (distSq > self.dist^2) then local a = angle(x, y, self.tx, self.ty) local dx = cos(a) * self.speed * dt local dy = sin(a) * self.speed * dt x += dx y += dy self:setRotation(^>a) self:setPosition(x, y) end end   local obj = FollowSprite.new(300, 0xff0000, 20) stage:addChild(obj)   local obj2 = FollowSprite.new(300, 0x00ff00, 20) stage:addChild(obj2)   stage:addEventListener(Event.ENTER_FRAME, function(e) local dt = e.deltaTime obj:update(dt) obj2:update2(dt) end) stage:addEventListener(Event.MOUSE_HOVER, function(e) obj:follow(e.x, e.y) obj2:follow(e.x, e.y) end)```

EDIT:
You can add noise to make it move "randomly" around given point  Noise code (refernce):
 ```local tmp = { {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0}, {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1}, {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1} } local grad3 = {} -- make 0 based indices for i,t in ipairs(tmp) do local gr = {} for j = 1, 3 do gr[j-1]=t[j] end grad3[i-1]=gr end tmp = nil   local p = {151,160,137,91,90,15, 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 }   local perm = {} for i=0, 511 do perm[i] = p[(i & 255) + 1] end   local function dot(g, x, y, z) return g*x + g*y + g*z; end   local function mix(a, b, t) return (1-t)*a + t*b end   local function fade(t) return t*t*t*(t*(t*6-15)+10); end   local function noise(x, y, z) -- Find unit grid cell containing point local X = (x//1) local Y = (y//1) local Z = (z//1)   -- Get relative xyz coordinates of point within that cell x -= X y -= Y z -= Z   -- Wrap the integer cells at 255 (smaller integer period can be introduced here) X = X & 255 Y = Y & 255 Z = Z & 255   -- Calculate a set of eight hashed gradient indices local gi000 = perm[X+perm[Y+perm[Z]]] % 12 local gi001 = perm[X+perm[Y+perm[Z+1]]] % 12 local gi010 = perm[X+perm[Y+1+perm[Z]]] % 12 local gi011 = perm[X+perm[Y+1+perm[Z+1]]] % 12 local gi100 = perm[X+1+perm[Y+perm[Z]]] % 12 local gi101 = perm[X+1+perm[Y+perm[Z+1]]] % 12 local gi110 = perm[X+1+perm[Y+1+perm[Z]]] % 12 local gi111 = perm[X+1+perm[Y+1+perm[Z+1]]] % 12   -- Calculate noise contributions from each of the eight corners local n000= dot(grad3[gi000], x, y, z) local n100= dot(grad3[gi100], x-1, y, z) local n010= dot(grad3[gi010], x, y-1, z) local n110= dot(grad3[gi110], x-1, y-1, z) local n001= dot(grad3[gi001], x, y, z-1) local n101= dot(grad3[gi101], x-1, y, z-1) local n011= dot(grad3[gi011], x, y-1, z-1) local n111= dot(grad3[gi111], x-1, y-1, z-1) -- Compute the fade curve value for each of x, y, z local u = fade(x); local v = fade(y); local w = fade(z); -- Interpolate along x the contributions from each of the corners local nx00 = mix(n000, n100, u); local nx01 = mix(n001, n101, u); local nx10 = mix(n010, n110, u); local nx11 = mix(n011, n111, u); -- Interpolate the four results along y local nxy0 = mix(nx00, nx10, v); local nxy1 = mix(nx01, nx11, v); -- Interpolate the two last results along z local nxyz = mix(nxy0, nxy1, w);   return nxyz; end   return noise```

And thats how you can use it with code above:
 ```-- add -- self.x = 0 -- self.y = 0 -- to init function of FollowSprite function FollowSprite:update3(dt) local x, y = self.x,self.y--self:getPosition() local distSq = distance(x, y, self.tx, self.ty) local n1 = 0 local n2 = 0 local power = 20 --self.speed = math.sqrt(distSq) * 0.75 --< dynamic speed based on distance if (distSq > self.dist^2) then local a = angle(x, y, self.tx, self.ty) local dx = cos(a) * self.speed * dt local dy = sin(a) * self.speed * dt x += dx y += dy   --self:setRotation(^>a) n1 = noise(y/100, 0.1, self.zoff) * power / 2 n2 = noise(0.1, x/100, self.zoff) * power / 2 else n1 = noise(y/100, 0.1, self.zoff) * power n2 = noise(0.1, x/100, self.zoff) * power end   self:setPosition(x + n1, y + n2) self.zoff += dt self.x = x self.y = y end```
+1 -1 (+4 / -0 ) Share on Facebook
• For some reason I decided to create a noise plugin  And after a few hours, its working, and its x5 times faster than lua version.
But it only works for windows, cuz idk how to build for other platforms ¯\_(ツ)_/¯

Likes: MoKaLux, talis

+1 -1 (+2 / -0 ) Share on Facebook
• if you make it public, I can add it to gideros distributon as well as port it to other platforms
+1 -1 (+2 / -0 ) Share on Facebook
• edited December 2019
hgy29 said:

if you make it public, I can add it to gideros distributon as well as port it to other platforms

The question is, does someone need it? Maybe it should have more than just simplex and perlin noises Maybe something like this: https://github.com/Auburns/FastNoise
If so, I can also create a few examples Likes: SinisterSoft

+1 -1 (+1 / -0 ) Share on Facebook
• +1 for this to happen Likes: plicatibu

my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
+1 -1 (+1 / -0 ) Share on Facebook
• +1!
> Newcomers roadmap: from where to start learning Gideros
"What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
“The more you do coding stuff, the better you get at it.” - Aristotle (322 BC)﻿
• @rrraptor That's exactly what I wanted. It is amazing.

Thank you for sharing.

Regards.

Likes: MoKaLux

+1 -1 (+1 / -0 ) Share on Facebook
• Yes, Gideros needs more general purpose things like this.

Likes: Apollo14

+1 -1 (+1 / -0 ) Share on Facebook
• @hgy29 for me to create a binding of FastNoise I need to rewrite in C? Or its ok to use C++?
• You can use C++, it is can cooperate with C code
• edited December 2019
hgy29 said:

You can use C++, it is can cooperate with C code

Ok, good So, how to properly create a binding?

The way I did it is:
Define noise variable
 `static FastNoise noise;`
Create instance:
 ```static void g_initializePlugin(lua_State* L) { noise = FastNoise(); // rest of the code }```
And the binding functions like that:
 ```static int GetNoise(lua_State* L) { FN_DECIMAL x = lua_tonumber(L, -1); FN_DECIMAL y = lua_tonumber(L, -2); FN_DECIMAL z = lua_tonumber(L, -3);   FN_DECIMAL v = noise.GetNoise(x, y, z);   lua_pushnumber(L, v);   return 1; }```
g_deinitializePlugin is empty, cuz idk how to destroy static instance, google says that it will be automatically destroyed.
Also, should I to use lua_pop every time Im getting/pushing values from/to stack?

Or I need to use g_createClass ?
• if You don’t need to instanciate your generator, you won’t need to create classes. For basic lua C interface, take a look at how it is done for other plugins in gideros