Howdy, Stranger!

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

Relative touch

Hi, so I’m experimenting with a relative touch version of Starsceptre

It’s easy to get the ship to follow my finger if I use:

 sh.x=touch.x
sh.y=touch.y

sh.x is the x position of the Ship
sh.y if the y postition of the ship

I’m looking to implement a couple of lines of code that moves the ship relative to where you finger is. So if the ship starts off in the middle of the screen, when I Touch I want it to work out it’s relative position to the ship and when I move adjust the x of the ship accordingly. Currently it just snaps to the position of the touch.

I’ve been wracking my brain and not been able to work out the code. Can anyone help?

Thanks
Rich

Comments

  • dave1707dave1707 Mod
    Posts: 7,200

    Are you after something like this or did I not understand what you’re after.

    displayMode(FULLSCREEN)
    
    function setup()
        sx,sy,dx,dy=WIDTH/2,HEIGHT/2,0,0
    end
    
    function draw()
        background(40, 40, 50)
        sprite("Tyrian Remastered:Evil Orb",sx-dx,sy-dy)
    end
    
    function touched(t)
        if t.state==BEGAN then
            tx,ty=t.x,t.y
        elseif t.state==MOVING then
            dx,dy=tx-t.x,ty-t.y
        elseif t.state==ENDED then
            sx,sy,dx,dy=sx-dx,sy-dy,0,0
        end
    end
    
  • THanks @dave1707 - that works great. I’m just gonna look into how it works to help my head ! Lol. Thank you

  • Hey @dave1707 - so I understand that code well now. Great piece of code.

    What I’m finding is if you touch a second finger it interrupts the code and the ship jumps around. So I’m looking to define a single touch, then multiple touch is to be ignored by this code.

  • dave1707dave1707 Mod
    Posts: 7,200

    @Majormorgan Try this.

    displayMode(FULLSCREEN)
    
    function setup()
        sx,sy,dx,dy,td=WIDTH/2,HEIGHT/2,0,0,0
    end
    
    function draw()
        background(40, 40, 50)
        sprite("Tyrian Remastered:Evil Orb",sx-dx,sy-dy)
    end
    
    function touched(t)
        if t.state==BEGAN and td==0 then
            tx,ty,td=t.x,t.y,t.id
        elseif t.state==MOVING and td==t.id then
            dx,dy=tx-t.x,ty-t.y
        elseif t.state==ENDED and td==t.id then
            sx,sy,dx,dy,td=sx-dx,sy-dy,0,0,0
        end
    end
    
  • A small adjustment to use vec2s:

    displayMode(FULLSCREEN)
    
    function setup()
        position = vec2(WIDTH/2,HEIGHT/2)
    end
    
    function draw()
        background(40, 40, 50)
        sprite("Tyrian Remastered:Evil Orb",position.x,position.y)
    end
    
    function touched(t)
        if t.state==BEGAN and not tid then
            offset = position - vec2(t.x,t.y)
            tid = t.id
        elseif tid and tid==t.id then
            position = vec2(t.x,t.y) + offset
            if t.state == ENDED then
                tid = nil
            end
        end
    end
    
  • dave1707dave1707 Mod
    edited December 2017 Posts: 7,200

    Here’s a way using vec3's, but it’s a little confusing.

    displayMode(FULLSCREEN)
    
    function setup()
        ship=vec3(WIDTH/2,HEIGHT/2,0)
    end
    
    function draw()
        background(40, 40, 50)
        sprite("Tyrian Remastered:Evil Orb",ship.x,ship.y)
    end
    
    function touched(t)
        if t.state==BEGAN and ship.z==0 then
            diff=ship-vec3(t.x,t.y,t.id)
        elseif t.state==MOVING and math.abs(diff.z)==t.id then
            ship=vec3(t.x,t.y,0)+diff
        elseif t.state==ENDED and math.abs(diff.z)==t.id then
            ship.z=0
        end
    end
    
  • @dave1707 I really do not recommend using vec3s. If you want to combine the data into a single object, use a table.

    displayMode(FULLSCREEN)
    
    function setup()
        ship={
            position = vec2(WIDTH/2,HEIGHT/2)
            offset = vec2(0,0),
            inTouch = false,
            sprite = "Tyrian Remastered:Evil Orb"
         }
    end
    
    function draw()
        background(40, 40, 50)
        sprite(ship.sprite,ship.position.x,ship.position.y)
    end
    
    function touched(t)
        if t.state==BEGAN and not ship.inTouch then
            ship.inTouch = true
            ship.offset = self.position - vec2(t.x,t.y)
            ship.touchid = t.id
        end
        if ship.inTouch and ship.touchid == t.id then 
            ship.position = vec2(t.x,t.y) + ship.offset
            if t.state == ENDED then
                ship.inTouch = false
            end
        end
    end
    

    But of course, by this stage you may as well introduce a class.

    Ship = class()
    
    function Ship:init(p,s)
        self.position = p
        self.sprite = s
    end
    
    function Ship:draw()
        sprite(self.sprite, self.position.x,self.position.y)
    end
    
    function Ship:touched(t)
        if not self.inTouch then
            self.offset = self.position - vec2(t.x,t.y)
            self.inTouch = true
            self.touchid = t.id
            return true
        end
        if not self.touchid == t.id then
            return false
        end
        self.position = vec2(t.x,t.y) + self.offset
        if t.state == ENDED then
            self.inTouch = false
        end
        return true
    end
    
    function setup()
        ship = Ship(vec2(WIDTH/2,HEIGHT/2), "Tyrian Remastered:Evil Orb")
    end
    
    function draw()
        background(40,40,50)
        ship:draw()
    end
    
    function touched(t)
        if ship:touched(t) then
            return
        end
    end
    
  • dave1707dave1707 Mod
    Posts: 7,200

    @LoopSpace For this purpose, a vec3 worked just fine. Would I use a vec3 or vec4 to hold different variables, probably not, but then it would depend on what I was doing. As I said above, it’s a little confusing mixing the vec3 data and having to take the absolute value of the Touch ID to get it to work. Using a table or a class works, but those use more code compared to what is actually needed. The above examples just show that there are different ways to accomplish the same thing. It just depends on your coding style and what you’re used to.

  • @dave1707 Different coding styles is fine, but I don't think that co-opting a vec3 or vec4 like that is good style. It implies a relationship between the components that doesn't exist. Using a table is hardly any more code but keeps the relationship of the different pieces clear.

  • dave1707dave1707 Mod
    Posts: 7,200

    @LoopSpace Like I said, it all depends on your coding style. Would I mix data in a vec for a production program, no. Would I mix data in a vec just to show it can be done, yes. My days of production programming are long gone, but my days of hacked programming is still going on. Right now I’m a lazy programmer. In my examples I use a lot of abbreviated names (a couple of characters long) just so I don’t have to type much. I don’t expect someone to take my code and use it in their code without understanding what it does and changing the variable names to something that they understand. A lot of times I rewrite code just to make it as small as possible just to do it. I wouldn’t consider myself a good teacher.

  • @dave1707 But people do take your code and work with it since you provide so many examples, often without really understanding it. So you really ought to consider all your code here as "production programming". There are lots of things that "can be done", but shouldn't be and without any commentary then people who don't know better are going to think that that is a good idea.

  • dave1707dave1707 Mod
    Posts: 7,200

    @LoopSpace You’re probably correct, I should do a better job with my examples. As I said, I’m not a very good teacher and I’m a lazy programmer and I probably won't change. Even when I was working I never commented my code even though I was told more than once to do so. I always said that the code was the comments because it was always correct and current.

  • Thanks @dave1707 and @LoopSpace these are really cool

    Currently I can using the version before Vec2 onwards was introduced. This works great for me.

    Now one thing I would love to have is based on how fast I move the finger left or right I’d like to measure that change so I can switch the state of the ship to another state. Currently the ship is in flat mode. When you start to move slowly right it tilts right (I have the animation code already for that) and if you move faster right it goes to extreme tilt right.

    Ignore calling the states, for decidImg how far I’ve dragged do I use touch.delta?

    Thanks and Merry Christmas!!!!

  • dave1707dave1707 Mod
    Posts: 7,200

    @Majormorgan You can use t.deltaX to determine how fast you’re moving your finger. Each call to the touched function MOVING will give you how far your finger moved.

  • Works a treat @dave1707 - perfect!

    One other question. When the ship dies some of the touches are still engaged and play up on the next life. Is there a way to reset all that touches?

    Thanks and merry Christmas!!

  • dave1707dave1707 Mod
    Posts: 7,200

    Are you saving the touches in a table. If so, when the ship dies just set the table to nil and start over.

  • Perfect. Thank you @dave1707 I’m really starting to understand this stuff. Got it saving to a table and wiping that when I start over. Perfect

Sign In or Register to comment.