Touch Controls

I am currently making a game where you explode a dungeon, and I am using touch controls to move your character. I was wondering if anyone could see what the problem with my code is.

Player class:
`Player = class()

function Player:init()
self.position = {x = WIDTH/2, y = HEIGHT/2}
self.health = 100
self.damage = 5
self.gold = 200
end

function Player:draw()
sprite(“Documents:Character”,self.position[“x”],self.position[“y”],40,40)
end

function Player:touched(touch)
– This is where we will manage the movement of the character, and also how the player will attack (if tapped an enemy).
distanceline = touch.y - self.position[“y”] / touch.x - self.position[“x”] / 20
tween(5,self.position,{x = touch.x, y = touch.y})
end`

(The “Main” file does include a touch function that calls the touch function shown in the Player class. So that is not the problem.)

Oops. My copy and paste got the wrong code. Hold on. Here’s the real code…

Player = class()

function Player:init()
    self.position = {x = WIDTH/2, y = HEIGHT/2}
    self.health = 100
    self.damage = 5
    self.gold = 200
end

function Player:draw()
    sprite("Documents:Character",self.position["x"],self.position["y"],40,40)
end

function Player:touched(touch)
    -- This is where we will manage the movement of the character, and also how the player will attack (if tapped an enemy).
    distanceline = touch.y - self.position["y"] / touch.x - self.position["x"] / 20
    tween(5,self.position,{x = touch.x, y = touch.y})
end

@WilkeNine_Co When you post code, put 3 ~'s on a line before and after your code so it shows properly on the forum.

what is the problem? If it is an error message, tell us the message, and which line it is

@dave1707 oh sorry. I couldn’t figure out why it didn’t look like a code post. Thank you.

@Ignatz the problem is that when I tap, the sprite in the same Player class won’t move like it is supposed to via tweens. I am using a table for the X and Y axis positions of where the player’s sprite will spawn in. The tween is also using the same table for the animation. But the tween won’t run, and change the position of the sprite. This, in turn, is making the animation not happen, and the character won’t move.

You haven’t posted any code for most of this (eg tweens), so we can’t help you.

you need to give us ALL the code that might be causing the problem.

I assume that you have a touched function like this. Unless you do, your Player:touched function will never run.

function touched(touch)
    P:touched(touch)  --if P is your player

@Ignatz I know for a fact that the problem with the code is inside what I have given you. I have been messing around with everything else. Yes, there is a “touched” function in the “Main” file. It does exactly what you mentioned. I thought I said that in my post. Anyways, I think it has to do with the table. There is nothing else in the game that depends on any of the things in the code given, therefor they don’t matter.

@WilkeNine_Co - I think you are in the best position to debug this

What I would do is put some print statements in, that tell you what is happening. Put one in Player:touched, to make sure this function is being run when a touch happens, and also in Player:draw, to see what is happening to the location values after a touch.

@Ignatz Lol. I did exactly that. Maybe this will help: the touch locations are being successfully rendered for when the player touches the screen. But I have yet to check what is happening in “Player:draw”. Lemme get back to you on that.

@Ignatz from what I saw in Player:draw was that the tween wasn’t changing the x and y values in self.position. Is there a problem with how I am using the tween?

@Ignatz …in the tween, the position literally isn’t being changed by the tween. Maybe because it isn’t being edited 60 frames a second, only in one?

I am sure there is a quite ordinary bug, and it isn’t in this code. You can prove it by using your class above with the simple code below. The tween works fine when you touch the screen. So I would look in the rest of your code to see if any of it is messing with self.position.

Debugging comes down to isolating the bug, by ruling out different causes. What I am doing with my test code below is showing that the tween works fine, so I probably should be looking somewhere else for the bug.

function setup()
    p=Player()
end

function draw()
    print(p.position.x,p.position.y)
end

function touched(t)
    p:touched(t)
end

@Ignatz okay. Thanks for helping out.

@Ignatz Okay, I finally narrowed down the code, and made a short little copy of my program, but only implementing the basic features (ignore the little health text thing, that was for aesthetics). This one again has no errors, good syntax, and an exact replica of what I have in my real game.

Player Class:

Player = class()

function Player:init()
    -- you can accept and set parameters here
    self.position = {x = 200, y = 512}
    self.health = 100
end

function Player:draw()
    sprite("Planet Cute:Character Boy",self.position["x"],self.position["y"],30,45)
    fill(255, 48, 0, 255)
    fontSize(12)
    text("Health: "..self.health,self.position["x"],self.position["y"]-32)
end

function Player:touched(touch)
    tween(3,self.position,{x = touch.x, y = touch.y})
end

The Main file:

-- TestProject

-- Use this function to perform your initial setup
function setup()
    print("Loaded game and modules.")
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)

    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here
    Player:init()
    Player:draw()
end

function touched(touch)
    if touch.state == BEGAN then
        Player:touched(touch)
    end
end

@Ignatz I’ve learned my lesson. I feel stupid that I did not think of that! That’s such an obvious answer. Thank you!

It’s ok, I make obvious mistakes all the time.

The key thing to learn (and it’s something I’m still learning!) is how to isolate the problem. A good place to start is with print statements, and by simplifying your project as much as possible, as you did with the code above. This gives the bug fewer places to hide.

Your problem is this

function draw()
   Player:init().    --<<<<< !!!!!!!!!!!!!!
   Player:draw()
end  

You are recreating the player object - and resetting the position values - every time you draw. This overwrites the tween values and cause your problem.

That line should be in setup, as it was in my example, because you only need to create it once.

This shows why you have to give us ALL the code, not just the code you think has the problem.

@Ignatz totally. Thank you. But I do have another problem I have been led into. My character needs to be moving at different speeds depending on the distance he is traveling (because obviously, I can’t have the tween duration set to 5 the whole time, or else a 2 foot walk will take forever, when in reality that’s not true). So I am using this little math formula I learned in math this year (I’m a 9th Grader) which determines the resulting length between two points on a graph. But because the screen isn’t a graph, and it only has positive “points” or pixels, the formula is broken. It gives me random huge numbers, instead of the real distance. And sometimes it is a negative number. It’s not possible to have a negative distance to travel.

It is the point-slope formula (at least I think that’s what it’s called). It looks like:
y2 - y1 / x2 - x1

As you’ll see in the code, I have used the touch position, and the current position of the sprite to complete the formula.

Player Class:

Player = class()

function Player:init()
    self.position = {x = 384, y = 512}
    self.health = 100
    self.damage = 5
    self.gold = 200
end

function Player:draw()
    sprite("Documents:Character",self.position["x"],self.position["y"],40,40)
end

function Player:touched(touch)
    -- This is where we will manage the movement of the character, and also how the player will attack (if tapped an enemy).
    timing = (self.position["y"] - touch.y / self.position["x"] - touch.x) / 2
    print(timing)
    if timing < 100 then
        timing = 3.5
    elseif timing < 200 then
        timing = 2.5
    elseif timing < 300 then
        timing = 2
    elseif timing < 400 then
        timing = 1.5
    elseif timing < 500 then
        timing = 1
    elseif timing > 500 then
        timing = 0.5
    end
    print(timing)
    tween(timing,self.position,{x = touch.x, y = touch.y})
end

Main:

-- Project Name: Game 1
-- Description: Run around, loot chests, and survive.
-- Started on December 31st, 2015
-- Developer: Sean Wilkerson

-- Use this function to perform your initial setup
function setup()
    -- The following comment is the template for a randomly generated Sprite positon.
    -- vec2(math.random(WIDTH/2-300,WIDTH/2+300),math.random(HEIGHT/2-400,HEIGHT/2+400))
    chestvalues = {}
    chestpositions = {}
    displayMode(FULLSCREEN)
    supportedOrientations(PORTRAIT)
    print("All game files have been loaded in.")
    print("Physics engine loaded. Force algorythms and bodies have been applied.")
    print("All stored data has been loaded. If any problems occur with lost items in inventory, or even lost coins and stuff, please contact us.")
    -- Choose a random amount of coins to appear on the screen.
    
    Player:init()
    
    coinamount = math.random(1,4)
    -- Insert random position values for up to 5 coins to use and occupy.
    chestpositions[1] = vec2(math.random(WIDTH/2-240,WIDTH/2+240),math.random(HEIGHT/2-400,HEIGHT/2+400))
    chestpositions[2] = vec2(math.random(WIDTH/2-240,WIDTH/2+240),math.random(HEIGHT/2-400,HEIGHT/2+400))
    chestpositions[3] = vec2(math.random(WIDTH/2-240,WIDTH/2+240),math.random(HEIGHT/2-400,HEIGHT/2+400))
    chestpositions[4] = vec2(math.random(WIDTH/2-240,WIDTH/2+240),math.random(HEIGHT/2-400,HEIGHT/2+400))
    chestvalues[1] = math.random(10,50)
    chestvalues[2] = math.random(10,50)
    chestvalues[3] = math.random(10,50)
    chestvalues[4] = math.random(10,50)
    
    -- And next up, we will randomly pick where the Sentinel Tower will appear on the screen, and how much it will heal us for.
    healthAmountChoice = math.random(70,100)
    sentinelPosition = vec2(math.random(WIDTH/2-300,WIDTH/2+300),math.random(HEIGHT/2-400,HEIGHT/2+400))
end

function draw()
    background(113, 119, 119, 255)
    
    for coin = 1, coinamount do
        Chests:init(chestvalues[coin],chestpositions[coin])
        Chests:draw()
        --fill(255, 255, 255, 255)
        --fontSize(16)
        --font("Noteworthy-Bold")
        --text(Chests().tier.." Chest",Chests().chestposition.x,Chests().chestposition.y-25)
    end
    
    Sentinel:init(healthAmountChoice,sentinelPosition)
    Sentinel:draw()
    
    Player:draw()
    
    Inventory:draw()
end

function touched(touch)
    if touch.state == BEGAN then
        Player:touched(touch)
    end
end