Lua Tic Tac Toe Tutorial in Corona - lua

I am trying to complete this Lua tic-tac-toe tutorial in Corona SDK.
I managed to get through the 1st part but got lost during this 2nd part where he is establishing variables within a table to register the alternating turns for "x" and "o".
He is using the tap count to determine which turn it is and I did try to use Corona's touch.id to mimic this technique, to no avail.
I am hoping someone can explain how I can achieve this using Corona.
Here is what I have so far (from Part1 of Tutorial):
d = display
w20 = d.contentWidth * .2
h20 = d.contentHeight * .2
w40 = d.contentWidth * .4
h40 = d.contentHeight * .4
w60 = d.contentWidth * .6
h60 = d.contentHeight * .6
w80 = d.contentWidth * .8
h80 = d.contentHeight * .8
----DRAW LINES FOR BOARD
local lline = d.newLine(w40,h20,w40,h80 )
lline.strokeWidth = 5
local rline = d.newLine(w60,h20,w60,h80 )
rline.strokeWidth = 5
local bline = d.newLine(w20,h40,w80,h40 )
bline.strokeWidth = 5
local tline = d.newLine(w20,h60,w80,h60 )
tline.strokeWidth = 5
--PLACE BOARD COMPARTMENT DIMENSIONS IN TABLE
board ={
{"tl", 1, w20, h40, w40, h20,0},
{"tm",2, w40,h40,w60,h20,0},
{"tr",3, w60,h40,w80,h20,0},
{"ml", 4, w20, h60, w40, h40,0},
{"mm",5, w40,h60,w60,h40,0},
{"mr",6, w60,h60,w80,h40,0},
{"bl", 7, w20, h80, w40, h60,0},
{"bm",8, w40,h80,w60,h60,0},
{"br",9, w60,h80,w80,h60,0}
}
--
--FILL COMPARTMENT W/ COLOR WHEN TOUCHED
local function fill (event)
if event.phase == "began" then
tap = 0
for t = 1, 9 do
if event.x > board[t][3] and event.x < board [t][5] then
if event.y < board[t][4] and event.y > board[t][6] then
r = d.newRect(board[t][3],board [t][6],w20,h20)
r:setFillColor(1,1,0)
r.anchorX=0
r.anchorY=0
end
end
end
end
end
Runtime:addEventListener("touch", fill)

I use new variable whichTurn to figure out what to put on board in each turn. I think code is self-explanatory. Try
...
local EMPTY, X, O = 0, 1, 2
local whichTurn = X -- X is starting game
...
--FILL COMPARTMENT W/ COLOR WHEN TOUCHED
local function fill (event)
if event.phase == "began" then
for t = 1, 9 do
if event.x > board[t][3] and event.x < board [t][5] then
if event.y < board[t][4] and event.y > board[t][6] then
if board[t][7] == EMPTY then
board[t][7] = whichTurn
--[[
The operator AND returns its first argument if it is false;
otherwise, it returns its second argument. The operator OR
returns its first argument if it is not false; otherwise, it
returns its second argument.
--]]
whichTurn = whichTurn == X and O or X
end
end
end
end
end
end
Runtime:addEventListener("touch", fill)
You can read more about differences between tap and touch events in Corona.
Check also this from Corona documentation
Filtering Multiple Taps
Using the event.numTaps property, you can easily determine whether an
object was tapped multiple times and concurrently ignore single taps
on the object.

Related

Corona SDK Attempt to compare number number to nil

Hi I am converting this simple "catch the egg" game from Godot engine to Corona. I am very new to programming and am using this project as a learning exercise.
I have run into a hurdle with it though. I keep getting the following error msg:
**
ERROR: Runtime error
C:\Users\kdoug\Documents\Corona Projects\cathchtheegg\main.lua:19: attempt to compare number with nil
stack traceback:
C:\Users\kdoug\Documents\Corona Projects\cathchtheegg\main.lua:19: in function
?: in function
**
What I am trying to do is see if the egg will delete when it goes beyond a certain point, without having to use a collision with a physics object.
any help would be appreciated!
thanks
Here is the code (a little less discombobulated):
local physics = require "physics"
physics.start()
local h = display.actualContentHeight
local w = display.actualContentWidth
local cx = display.contentCenterX
local cy = display.contentCenterY
local dnir = display.newImageRect
local dnr = display.newRect
local mr = math.random
--local egg
local bask
local idx = 0
local eggs = {}
---------BACKGROUND---------------
local bg = dnir("bg.png", w,h)
bg.x = cx
bg.y = cy
----------DISPLAY BASKET------------
bask = dnir("basket.png", 100,50)
bask.x = cx
bask.y = cy
physics.addBody(bask,"kinematic")
bask.myName = "bask"
----- BASKET MOVE W/ MUSE FUNCTION -----
local function baskMove (e)
bask.x = e.x
bask.y = e.y
end
Runtime:addEventListener("mouse", baskMove)
----------------GROUND---------------
local grd = dnr(cx,h-470,w+50,10)
grd:setFillColor(.1, .8, .15,0)
grd.myName = "ground"
physics.addBody(grd, "static")
grd.collision = collision
grd:addEventListener("collision", grd)
----------****DELETE EGG FUNCTION****------------
--function loop ()
-- if egg and egg.y > 100 then
-- print("Delete")
-- display.remove(egg)
-- end
--end
--
--Runtime:addEventListener("enterFrame", loop)
-----------COLLISIONS FUNCTIION-------------
local function collision ( s, e )
if e.phase == "began" then
if e.target.myName == "bask"
and e.other.myName == "egg" then
display.remove(e.other)
table.remove(eggs, idx)
end
if e.target.myName == "egg"
and e.other.myName == "bask" then
display.remove(e.target)
table.remove(eggs, idx)
end
if e.target.myName == "ground"
and e.other.myName == "egg" then
display.remove(e.other)
table.remove(eggs, idx)
end
if e.target.myName == "egg"
and e.other.myName == "ground" then
display.remove(e.target)
table.remove(eggs, idx)
end
end
end
--
--------------EGG---------------------
function theEgg ()
egg = dnir("egg.png", 50,50)
physics.addBody(egg,"dynamic")
egg.myName = "egg"
idx = idx + 1
egg.x = mr(w)
egg.y = - 100
transition.to (egg, {y = h + 50, time= mr(1000,8000)})
eggs[idx] = egg
eggs[idx].idx = idx
print(eggs[idx])
--------EGG COLLISIION CB-------------
egg.collision = collision
egg:addEventListener("collision", egg)
end
--
-----------Spawn EGG-----------
function spawner()
theEgg()
print(#eggs)-- PRINT AMT IN TABLE
end
timer.performWithDelay(2000, spawner, 0)
I don't know when you remove enterFrame listener. It is important. After you delete egg object loop may be called again. So when egg.y is not defined (=nil) comparision (in if statment) can not be done.
My solution:
function loop ()
if egg and egg.y > 100 then
print("Delete")
display.remove(egg)
end
end
Information from https://www.lua.org/pil/3.3.html
all logical operators consider false and nil as false and anything
else as true
Or (use local variable index instead global variable egg) It is not clear for my purpose use of varaible egg in your code so it may be wrong.
local index
...
function loop ()
if eggs[index] and eggs[index].y > 100 then
print("Delete")
local egg = table.remove(eggs, index)
display.remove(egg)
egg = nil
end
end

Corona SDK. Lua. display.newText() - my updated score text is overlapping old one without erasing

I'm developing clone version of Nintendo Tetris game using Corona SDK. There are two text objects on the top of my screen: one represents current level, another one represents current score. Every time I fill in line with blocks my program erases this line and add some scores and +1 level. The problem is that once I update my score and level variables and use myText.text to refresh my texts it doesn't erase old text and creates the new text that overlapping the old one.
My code is following:
1) I declare two local variables at the begging of my scene
local scoreText
local levelText
2) I have function that erases the line and updates texts
function eraseLines()
-- some code that erases lines
scores = scores + 10
scoreText.text = "Score:"..scores
level = level + 1
levelText.text = "Level:"..level
end
3) In scene:show(event) I create our texts
function scene:show( event )
-- some code
scoreText = display.newText("Score:"..scores, halfW*0.5, 20 )
levelText = display.newText("Level:".. level, halfW*1.5, 20 )
sceneGroup:insert( scoreText )
sceneGroup:insert( levelText )
scoreText:setFillColor( 0, 0, 0 )
levelText:setFillColor( 0, 0, 0 )
end
Please help me to find out why overlapping happens
At the moment you are adding twice score/level labels, 'cause the show event is called two times (phases) will and did. Add display objects when you are creating the scene.
-- create()
function scene:create( event )
local sceneGroup = self.view
-- Code here runs when the scene is first created but has not yet appeared on screen
scoreText = display.newText( "Score: 0", halfW * 0.5, 20 )
levelText = display.newText( "Level: 0", halfW * 1.5, 20 )
sceneGroup:insert( scoreText )
sceneGroup:insert( levelText )
scoreText:setFillColor( 0, 0, 0 )
levelText:setFillColor( 0, 0, 0 )
end
-- show()
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
-- Code here runs when the scene is still off screen (but is about to come on screen)
scoreText.text = "Score: " .. score
levelText.text = "Level: " .. level
elseif ( phase == "did" ) then
-- Code here runs when the scene is entirely on screen
end
end
Here's a poorly constructed single script for displaying score
local scoreCounter = {}
local frameTime = 0
scoreCount = 0
finalScore = nil
local tempText = nil
local function update( event )
frameTime = frameTime + 1
--after every 7 frames score will increase
if(frameTime % 7 == 0) then
scoreCount = scoreCount + 1
tempText.text = scoreCount
frameTime = 0
end
end
-- here is a memory leak I guess
function scoreCounter.displayScore(xCoordinate, yCoordinate)
tempText = display.newText(scoreCount, xCoordinate, yCoordinate)
end
Runtime:addEventListener("enterFrame", update)
return scoreCounter
Usage:
local scoreCounter = require("pathtoluafile")
scoreCounter.displayScore(xCoordinate, yCoordinate)

Receiving "Attempt to index global 'sprite' (a nil value)" in Lua

Im attempting to make a simple game app and keep running into this problem. I stopped programming in Lua for a few years so I don't exactly remember how to fix this. Anyway, my code is as follows:
EDIT: Here is the entire file. Still trying to figure out the formatting of Stack Overflow. Error occurs at line 76.
module(..., package.seeall)
-- Main function - MUST return a display.newGroup()
function new()
local localGroup = display.newGroup()
---------
local Rad = math.rad
local Sin = math.sin
local Cos = math.cos
local Pi = math.pi
local Atan2 = math.atan2
local radD = 180 / Pi
local DegR = Pi / 180
local touchPoint = display.newCircle(localGroup, -50, -50, 20)
touchPoint.isFocus = false
touchPoint.alpha = 0
function GetDistanceFromObjects(obj1, obj2)
local xDist = obj1.x - obj2.x
local yDist = obj1.y - obj2.y
local dist = Sqrt((xDist * xDist) + (yDist * yDist))
return dist
end
function getAngleDeg(inX1, inY1, inX2, inY2)
local xDist = inX2 - inX1
local yDist = inY2 - inY1
local angRad = Atan2(yDist, xDist)
return angRad * radD + 90
end
require "sprite"
function VectorFromAngle(inAngle, inVelocity)
local vx = Cos(Rad(inAngle-90))
local vy = Sin(Rad(inAngle-90))
if(inVelocity ~= nil)then
vx = vx * inVelocity
vy = vy * inVelocity
end
return vx,vy
end
require ( "physics" )
physics.start()
physics.setGravity( 1, 1 )
--( x, y )
--physics.setDrawMode ( "hybrid" )
math.randomseed(os.time())
local background = display.newImage("yazd.jpeg")
localGroup:insert(background)
--width of image divided by # of pics lined up from left to right (in the sprite) = the first #
--height of image divided by # of pics lined up from top to bottom (in the sprite) = the second #
local birdSheet = sprite.newSpriteSheet( "enemy.jpg", 59, 50 )
local birdSet = sprite.newSpriteSet(birdSheet, 1, 1)
-- images 1-14
sprite.add( birdSet, "bird", 1, 1, 200, 0 )
-- play 1-14, each image every 200 ms, 0 = loop count, which is infinite
local bird1 = sprite.newSprite( birdSet )
bird1.x = 40 -- starting point
bird1.y = 40 -- starting point
bird1.xScale = 0.5 --scale down x
bird1.yScale = 0.5 --scale down y
bird1:prepare("bird") --prepare sprite sequence
bird1:play() --play sprite
localGroup:insert(bird1)
--only local to this group
local killSheet = sprite.newSpriteSheet("explosion.png", 100, 100)
local killSet = sprite.newSpriteSet(killSheet, 1, 9)
sprite.add(killSet, "kill", 1, 9, 200, 1)
local birdCount = 1
local transDirection12
local function transDirection1()
bird1.xScale = 0.5
transition.to(bird1, {time=math.random(200,500), x = math.random(200,490), y = math.random(10,310), alpha = (math.random(9,100))/100, onComplete = transDirection12})
end
transDirection12 = function()
bird1.xScale = 0.5
transition.to(bird1, {time= math.random(200,500), x = math.random(200,490), y = math.random(10,310), alpha = (math.random(9,100))/100, onComplete = transDirection1})
end
transDirection1()
-- local transDirection1 declares what will be used (local function)
-- transDirection1 = function
-- following it are the function qualities
-- declares it will use object/image called bird1 and scales it to .5
-- time = ____ means it will take a certain time, between ____ and ____ to complete the transition
-- x=____ means that is where it will move to on the x axis
-- y=____ means that is where it will move to on the y axis
-- alpha = ___ means the is how transparent it will be
-- onComplete = ________ means that when the action is complete, it will call another function
-- The next function has the same qualities as transDirection1, but the onComplete part calls transDirection1 and they continue to loop
-- transDirection1() declares transDirection1 so the app knows about it and can use it
-- the other trans do not need to be declared because they are part of transDirection1, which is already declared
--(x, y, size.x, size.y)
local player = display.newImage( "mk11.png" )
player.x = 240
player.y = 260
player.xScale = .5
player.yScale = .5
localGroup:insert( player )
-- add physics to all the objects wanted: (object wanted, "static" or "dynamic")
physics.addBody(player, "static", {radius=30, isSensor = true})
physics.addBody(bird1, "static", {radius=23})
local function shoot(inPointX, inPointY)
-- (start at the x of the player + 10, also start at the y of the player, the radius of the circle is 5)
local bullet = display.newImage( "bullet2.png" )
bullet.x = player.x
bullet.y = player.y
-- add physics to the object, which is the bullet.
-- Make the bullet "dynamic" or moving
physics.addBody(bullet, "dynamic")
bullet.isFixedRotation = true
localGroup:insert( bullet )
local velocity = 300
local vx, vy = VectorFromAngle(player.rotation, velocity)
bullet.rotation = player.rotation
bullet:setLinearVelocity(vx, vy)
end
function RotateToTouchPoint(inPointX, inPointY)
local ang = getAngleDeg(player.x, player.y, inPointX, inPointY)
player.rotation = ang
end
local function ScreenTouchListener(event)
local phase = event.phase
if(phase == "began")then
if(touchPoint.isFocus == false)then
touchPoint.alpha = 1
touchPoint.x = event.x
touchPoint.y = event.y
display.getCurrentStage():setFocus(touchPoint, event.id)
touchPoint.isFocus = true
RotateToTouchPoint(event.x, event.y)
shoot(event.x, event.y)
end
elseif(touchPoint.isFocus)then
if(phase == "moved")then
touchPoint.x = event.x
touchPoint.y = event.y
RotateToTouchPoint(event.x, event.y)
elseif(phase == "ended" or phase == "cancelled")then
display.getCurrentStage():setFocus(touchPoint, nil)
touchPoint.isFocus = false
touchPoint.alpha = 0
end
end
return true
end
local function gotShot (event)
event.target:removeSelf()
event.other:removeSelf()
local explosion = sprite.newSprite(killSet)
explosion.x, explosion.y = event.target.x, event.target.y
explosion:prepare("kill")
explosion:play()
localGroup:insert( explosion )
birdCount = birdCount - 1
-- when there are no more birds, remove the runtime event listener and perform the
-- function with a delay of 500 m.s. The function changes the scene to test.lua
if "ended" then
if birdCount == 0 then
Runtime:removeEventListener("touch", ScreenTouchListener)
timer.performWithDelay(500, function()
director:changeScene("mainPage") end, 1)
end
end
end
bird1:addEventListener("collision", gotShot)
Runtime:addEventListener("touch", ScreenTouchListener)
---------
-- MUST return a display.newGroup()
return localGroup
end
Any help is appreciated!
The error message is perfectly clear -- the variable sprite used at this line:
local bird1 = sprite.birdSheet( birdSet )
has a nil value, meaning it has not been initialized or was set to nil. You need to show the earlier code where you should have set it up.
(After OP updates)
I think this line
require "sprite"
should actually be
sprite = require "sprite"
You can read more in modules tutorial here:
http://lua-users.org/wiki/ModulesTutorial

Corona Lua display object y property out by three ten-millionths of a pixel (!)

When I run this code (which is based on the "DragMe" sample app) I get very unexpected results in very particular circumstances.
My "snapToGrid" function sets x and y to the nearest round 100 value after a drag.
The "examine" function outputs the x and y values after an object is created, moved or rotated (by clicking on it).
If you place an object in row 5 (so y = 500) and rotate it you will see that the y value changes to 499.99996948242 but this does not happen in any other row.
How can this be explained? I notice this does not happen if the physics bodies are not added to the display object.
I know I could call snapToGrid after rotation or round the value before I use it for anything else but I think there is an important opportunity here for me to learn something useful about Corona.
local function snapToGrid(t)
modHalf = t.x % t.width
if modHalf > t.width/2 then
t.x = t.x + (t.width-modHalf)
end
if modHalf < t.width/2 then
t.x = t.x - modHalf
end
modHalfY = t.y % t.height
if modHalfY > t.height/2 then
t.y = t.y + (t.height-modHalfY)
end
if modHalfY < t.height/2 then
t.y = t.y - modHalfY
end
display.getCurrentStage():setFocus( nil )
t.isFocus = false
return true
end
function rotatePiece(target)
if target.rotation == 270 then
target.rotation = 0
else
target.rotation = target.rotation + 90
end
end
local function dragBody(event)
local target = event.target
local phase = event.phase
local halfWidth = target.width/2
local halfHeight = target.height/2
--get tileX and tileY relative to tile centre
local tileX = event.x-target.x
local tileY = event.y-target.y
local modHalf = ""
local snap = 15
if phase == "began" then
-- Make target the top-most object
display.getCurrentStage():setFocus( target )
-- Spurious events can be sent to the target, e.g. the user presses
-- elsewhere on the screen and then moves the finger over the target.
-- To prevent this, we add this flag. Only when it's true will "move"
-- events be sent to the target.
target.isFocus = true
-- Store initial position
target.x0 = event.x - target.x
target.y0 = event.y - target.y
elseif target.isFocus then
if phase == "moved" then
-- Make object move (we subtract target.x0,target.y0 so that moves are
-- relative to initial grab point, rather than object "snapping").
target.x = event.x - target.x0
target.y = event.y - target.y0
if target.x > display.contentWidth - (target.width/2) then target.x = display.contentWidth - (target.width/2) end
if target.y > display.contentHeight - (target.height/2) then target.y = display.contentHeight - (target.height/2) end
if target.x < 0 + (target.width/2) then target.x = 0 + (target.width/2) end
if target.y < 0 + (target.height/2) then target.y = 0 + (target.height/2) end
modHalf = target.x % target.width
if modHalf < snap then
target.x = target.x - modHalf
end
if modHalf > ((target.width) - snap) then
target.x = target.x + ((target.width)-modHalf)
end
modHalfY = target.y % target.height
if modHalfY < snap then
target.y = target.y - modHalfY
end
if modHalfY > ((target.height) - snap) then
target.y = target.y + ((target.height)-modHalfY)
end
hasMoved = true
return true
elseif phase == "ended" then
if hasMoved then
hasMoved = false
snapToGrid(target)
--tile has moved
examine(target)
return true
else
--rotate piece
rotatePiece(target)
display.getCurrentStage():setFocus( nil )
target.isFocus = false
--tile has rotated
examine(target)
return true
end
end
end
-- Important to return true. This tells the system that the event
-- should not be propagated to listeners of any objects underneath.
return true
end
local onTouch = function(event)
if event.phase == "began" then
local tile = {}
img = display.newRect(event.x,event.y,100,100)
img:addEventListener( "touch", dragBody )
snapToGrid(img)
--top right corner and top middle solid
topRight = {16,-16,16,50,50,50,50,-16}
--top left and left middle solid
topLeft = {-16,-16,-16,-50,50,-50,50,-16}
--bottom right and right middle solid
bottomRight = {16,16,16,50,-50,50,-50,16}
--bottom left and bottom middle solid
bottomLeft = {-16,16,-16,-50,-50,-50,-50,16}
physics.addBody( img, "static",
{shape=topRight},
{shape=topLeft},
{shape=bottomLeft},
{shape=bottomRight}
)
--new tile created
examine(img)
return true
end
end
function examine(img)
print("--------------------------------------------------")
if img ~= nil then
print("X: "..img.x..", Y: "..img.y)
end
print("--------------------------------------------------")
end
local img
local physics = require( "physics" )
physics.setDrawMode( "hybrid" )
--draw gridlines
for i = 49, display.contentHeight, 100 do
local line = display.newLine(0,i,display.contentWidth,i)
local line2 = display.newLine(0,i+2,display.contentWidth,i+2)
end
for i = 49, display.contentWidth, 100 do
local line = display.newLine(i,0,i,display.contentHeight )
local line2 = display.newLine(i+2,0,i+2,display.contentHeight )
end
--init
physics.start()
Runtime:addEventListener("touch", onTouch)
There several possibilities. Firstly, since there are no integers in Lua, all numbers are double floating point values. According to FloatingPoint on Lua wiki,
Some vendors' printf implementations may not be able to handle
printing floating point numbers accurately. Believe it or not, some
may incorrectly print integers (that are floating point numbers). This
can manifest itself as incorrectly printing some numbers in Lua.
Indeed, try the following:
for i=1,50,0.01 do print(i) end
You will see that a lot of numbers print exactly as you would expect, by many print with an error of 10^-12 or even 2 x 10^-12.
However, your x prints fine when you don't give it to physics module. So surely the physics module does some computation on object position and changes it. I would certainly expect that for dynamic objects (due to collision detection), but here your object seems to be "static". So it must be that physics adjusts x even for static objects. The adjustment is so small that it would not be visible on the screen (you can't perceive any motion less than a pixel), but you're right that it is interesting to ask why.
The SO post Lua: subtracting decimal numbers doesn't return correct precision is worth reading; it has some links you might find interesting and gives the neat example that decimal 0.01 cannot be represented exactly in base 2; just like 1/3 can't be represented exactly in base 10 (but it can in base 3: it would be 0.1 base 3!). The question shows that, although Lua (or possibly, the underlying C) is smart enough to print 0.01 as 0.01, it fails to print 10.08-10.07 as 0.01.
If you really want to shake your understanding of floating point values, try this:
> a=0.3
> b=0.3
> print(a==b)
true
> -- so far so good; now this:
> a=0.15 + 0.15
> b=0.1 + 0.2
> print(a,b)
0.3 0.3
> print(c==d)
false -- woa!
This is explained by the fact that 0.15 in binary has a small error which is different from that of 0.1 or 0.2, so in terms of bits they are not identical; although when printed, the difference is too small to show. You may want to read the Floating Point Guide.
Actually this problem only occurs if you add the physics, so I think it is fair to say that the issue is caused by transferring control to box2d, not by Corona handling of the number alone. I asked on Corona forums and got this answer.
http://forums.coronalabs.com/topic/46245-display-object-that-has-static-physics-body-moves-very-slightly-when-rotated/

How to do tile based collision

I am trying to make a simple platform game, and obviously I need tile collision. The problem with the code I have so far is that it moves the character first, then checks to see if it is colliding with something, but sometimes it thinks its colliding at the wrong times depending on if I check the x-axis for collisions first or the y-axis first. Am I going about this the wrong way? Here's some code.
function checkCollision(val, axis, oldPos)
if axis == "x" and char.tX then
local tileX = math.ceil(val/absoluteTileSize)
local tileY = math.floor(oldPos/absoluteTileSize)
local tl, tr, bl ,br = getTouchingTiles(tileX, tileY)
local isOnFlatSurface = math.abs(oldPos/absoluteTileSize-tileY) <= .00001--might not be a good i
if isOnFlatSurface then
if tr.canCollide then
char.tX = nil
char.x = tileX * absoluteTileSize - absoluteTileSize
end
else
if br.canCollide then
char.tX = nil
char.x = tileX * absoluteTileSize - absoluteTileSize
end
end
elseif axis == "y" then
local tileX = math.ceil(oldPos/absoluteTileSize)
local tileY = math.floor(val/absoluteTileSize)
local tl, tr, bl ,br = getTouchingTiles(tileX, tileY)
if bl.canCollide or br.canCollide then
char.tY = nil
char.y = tileY * absoluteTileSize --// - absoluteTileSize
--/////////////idk why i don't need to subtract that but it works
elseif not char.tY then--start falling if walk off something
char.tY = love.timer.getTime()
char.yi = char.y
char.vyi = 0
end
end
end
local tileX = math.ceil(val/absoluteTileSize)
local tileY = math.floor(oldPos/absoluteTileSize)
It seems strange that you would use math.ceil for the x values and math.floor for the y. This may be why you are getting some strange occurrences. I would recommend this little debugging trick that may help you:
-- Since you are using LÖVE, this is what you would use:
love.graphics.setColor( 255, 0, 0, 255 )
love.graphics.rectangle( 'line', ( tileX - 1 ) * absoluteTileSize, ( tileY - 1 ) * absoluteTileSize, absoluteTileSize, absoluteTileSize )
-- assuming absoluteTileSize represents the width/height of the tiles?
This would go at the end of your drawing function and would draw a red box in the "tile" your player is currently inside.

Resources