# Need help with applying rotation with Tween

First of all I totally dig Codea. Been using it for less than a year with amazing results. Huge chunks of my code are take from the examples you guys have shared with the community here, couldn’t have got this far without you guys sharing so Thank you.

I am trying to create a turn based game in the vein of Advance Wars or Tabletop games.

In my game scene I move my “Actors” by tweening them between a list of points but I haven’t been able to implement rotating my actor yet. What I am trying to do (in the rotLeft() function) is Tween from my current position to the same position but at a different angle but it isn’t working.

Do you guys have any suggestions on how i can accomplish this? Here is my Actor class.

``````
-- Actor

Actor = class()
function Actor:init(x, y, size, id, cellx, celly)
self.angle = 0
self.x = x
self.y = y
self.id = id
self.size = size
self.ctrlType = 0
self.scale = 1.0
self.ap = 4
self.clipSize = 4
self.bullVel = 60
self.offset=1
self.startTouch = false
self.showMove = false
self.move = false

self.inactive = 0
self.canMove = 1
self.moving = 2
self.fireing = 3
self.state = self.inactive

self.north = 0
self.east = 1
self.south = 2
self.west = 3
self.dir = self.north
self.moves = {}
self.tab1 = {}
self.buttons = {}
self.bullets = {}
self.grid = {}
self.curBullet = self.clipSize
self.selected = 0

self.index = vec2(cellx or 0, celly or 0)
self.last = vec2(x,y)
tweenObject =  vec3(x,y,self.rotation)
end

function Actor:reset()
self.tab1 = {}    -- table for points
self.moves ={}
self.offset=1
self.dx=0
self.dy=0
self.showMove = false
self.move = false
self.startTouch = false
self.buttons = {}
end

for i=1,self.clipSize do
local prog = Projectile()
table.insert(self.bullets,prog)
end
end

function Actor:fire()
local bull = self.bullets[self.curBullet]
bull:fire(self.bullVel, self.angle, self.x, self.y, 20)
sound(SOUND_SHOOT, 17108)
self.curBullet = self.curBullet - 1
if self.curBullet < 1 then
self.curBullet = self.clipSize
end

end

function Actor:toggleShowMoves(grid)
if self.showMove then
self.grid = grid
self:makeButtons(self.ap)
else

end
end

function Actor:draw()
dir = self.dir
state = self.state
local a; local b
local line=line

for z=self.offset+1,#self.tab1 do

pushStyle()
stroke(255)
strokeWidth(3)
line(self.tab1[z-1].x,self.tab1[z-1].y,self.tab1[z].x,self.tab1[z].y)
popStyle()

end
for z=self.offset+1,#self.moves-1 do
pushStyle()
stroke(0, 255, 0, 255)
strokeWidth(3)
line(self.moves[z-1].x,self.moves[z-1].y,self.moves[z].x,self.moves[z].y)
popStyle()
end

if self.move then    -- try to move at constant speed
a=math.sqrt(self.dx*self.dx+self.dy*self.dy)
b=5/a
end
pushMatrix()
rotate(self.angle)
scale(self.scale)
batch:sprite("cmane",self.x,self.y)

if self.selected > 0 then
pushStyle()
tint(64, 255, 0, 255)
batch:sprite("mselect",self.x,self.y)
popStyle()
end

if self.show then
pushStyle()
tint(253, 0, 255, 255)
batch:sprite("jammed",self.x-20,self.y+20)
popStyle()
end

if self.startTouch then
pushStyle()
tint(255, 0, 0, 255)
batch:sprite("jammed",self.x-20,self.y+20)
popStyle()
end

if self.showMove then
pushStyle()
tint(64, 255, 0, 255)
batch:sprite("overwatch",self.x+20,self.y+20)
popStyle()
end
popMatrix()
self:takeMove()
self:drawList(self.bullets)
if self.ctrlType == 0 then
if self.showMove then
if self.selected > 0 then
self:drawList(self.buttons)
else
self.showMove = false
end
end
end

end

function Actor:rotLeft()
self:tweenSelfStep(0,self, {rotate = 270})
end

``````

second part of the Actor class

``````
function Actor:rotRight()
end

function Actor:over()
end

function Actor:makeButtons(ap)
print("AP "..ap)
self.buttons = {}
self.startplace = vec2(0,0)
self.endplace = vec2(0,0)
self.xx = self.x -(ap * self.size)
self.yy = self.y - (ap * self.size)

for i = 0, (ap+ap) do
for j = 0, (ap+ap) do
if i == 4 and j == 4 then

else
self.startplace = GameScene:cellAt(self.x, self.y,self.grid)
self.endplace  = GameScene:cellAt(self.xx+(self.size*j),
self.yy+(self.size*i),self.grid)

if self.endplace then
local startx = self.startplace.x
local starty = self.startplace.y
local endx = self.endplace.x
local endy = self.endplace.y

if self:isValid(self.endplace.x,self.endplace.y,self.grid) then
btnName = "moveButton" .. i .. j
btnName = TileButton(self.xx+(self.size*j),
self.yy+(self.size*i),
false, "mselect", i+j)
btnName.action = function()
startx,
starty,
endx,endy)
)
self:toggleShowMoves(self.grid)
end
table.insert(self.buttons,btnName)
end
end
end
end
end
end

function Actor:isValid(posx, posy, grid)
local cell = grid[posy][posx]
if cell.state < 17 then
return true
end
return false
end

function Actor:drawBullets()

for i=1,#self.bullets do
bull = self.bullets[i]
bull:draw()
end
end

function Actor:drawList(listOfStuff)
for i,thing in ipairs(listOfStuff) do
thing:draw()
end
end

function Actor:chechState() -- doesnt work
if self.state == 4 then
elseif self.state == 1 then
elseif self.state == 2 then
elseif self.state == 3 then
end
end

function Actor:hit(p)
local l = self.x - self.size/2
local r = self.x + self.size/2
local t = self.y + self.size/2
local b = self.y - self.size/2
if p.x > l and p.x < r and
p.y > b and p.y < t then
return true
end

return false
end

function Actor:touchActorButtons(touch,listOfButtons)
for i,btn in ipairs(listOfButtons) do
btn:touched(touch)
end
end

function Actor:touched(t,grid)
self:touchActorButtons(t,self.buttons)

if t.state==ENDED and self:hit(t) then
if DEBUG then
tempVec = vec2(GameScene:cellAt(self.x,self.y,grid).x,
GameScene:cellAt(self.x,self.y,grid).y)
print("Raw pos: "..t.x..","..t.y)
print("I am at: "..self.x..","..self.y)
print("At cell: "..tempVec.x..","..tempVec.y)
end
end

if self.ctrlType == 0 then
if t.state==BEGAN and self:hit(t) and not en then
self:setSelected()
self.startTouch = true

if t.tapCount==2 then
--  print("Double Tap")
self.tab1 = {}
self:fire()
end

if self.x==0 and self.y==0 then
self.x=t.x
self.y=t.y
end

if self.selected > 0 then
self.showMove = true
self:toggleShowMoves(grid)
end
elseif t.state==MOVING then

elseif t.state==ENDED and self.startTouch then

if self.tab1[1] == nil then

else
self.dx=(self.tab1[self.offset].x-self.x)
self.dy=(self.tab1[self.offset].y-self.y)
self.move=true
end
else
end

elseif self.ctrlType == 1 then
if t.state==BEGAN and self:hit(t) and not en then
if t.tapCount==2 then
--   print("Double Tap")
self.tab1 = {}
end

if self.x==0 and self.y==0 then
self.x=t.x
self.y=t.y
end

self.startTouch = true
elseif t.state==MOVING and self.startTouch then
self.hx=t.x
self.hy=t.y
if self:calcDist() then -- limit points in the table
table.insert(self.tab1,vec2(t.x,t.y))    -- insert points in table
end
elseif t.state==ENDED and self.startTouch then
if self.tab1[1] == nil then
print("Err. no self.tab1 to index")
else
self.dx=(self.tab1[self.offset].x-self.x)
self.dy=(self.tab1[self.offset].y-self.y)
self.move=true
self.startTouch = false
end
else
print("ctrl 1")
self:reset()
end
else
print("self.ctrlType unknown")
end

end

function Actor:isSelected()
if self.selected > 0 then
return true
else
return false
end
end

function Actor:setSelected()
self.selected = 1
print("selected: "..tostring(self.selected))
for i,itm in ipairs(actors) do
if itm.id ~= self.id then
itm.selected = 0
itm.startTouch = false
itm.buttons = {}
end
end
end

if table == nil then
print("-- Error: table is nill")
else
if #table > 1 then

for i,vec in ipairs(table) do
self.tab1[i] = vec
end
end
end
end

function Actor:takeMove()
if self.move then
self.buttons = {}
if self.offset==#self.tab1+1 then
print("Reset")
self:reset()
self.selected = 0
return
end

a=math.abs(self.tab1[self.offset].x-self.x)    -- calc new x,y direction
b=math.abs(self.tab1[self.offset].y-self.y)
ab=math.sqrt(a*a+b*b)
local target = self.tab1[self.offset]
self:tweenSelfStep(self.id,target)

if ab<4 then
local mypos = GameScene:posAt(self.x,self.y,self.grid)
self.offset = self.offset + 1
self.ap = self.ap - 1
print("AP: "..self.ap)
local mycell = GameScene:cellAt(self.x,self.y,self.grid)
print(mycell)
end

end
end

function Actor:tweenSelfStep(id,target)
for i,act in ipairs(actors) do
if act.id == id then
self.move = false
print("tweening: "..id)
tween( 0.25 , act, target, tween.easing.quadInOut,
function()
self.index = GameScene:cellAt(self.x,self.y,self.grid)
self.move = true
end )
end
end
end

``````

Third part of the Actor Class

``````
function Actor:takeMoves()
local a; local b; local ab

if self.move then
if self.offset==#self.tab1 then
self:reset()
local mypos = GameScene:posAt(self.mx,self.my,self.grid)
self.mx = mypos.x
self.my = mypos.y
return
end

a=math.abs(self.tab1[self.offset].x-self.mx)    -- calc new x,y direction
b=math.abs(self.tab1[self.offset].y-self.my)
ab=math.sqrt(a*a+b*b)
print(self.offset..".) a,b,ab: "..a..","..b..","..ab)
print(self.offset..".) mx,my: "..self.mx..","..self.my)
if ab<4 then
local mypos = GameScene:posAt(self.mx,self.my,self.grid)

self.offset = self.offset + 1
self.dx=self.tab1[self.offset].x-self.mx
self.dy=self.tab1[self.offset].y-self.my
local mycell = GameScene:cellAt(self.mx,self.my,self.grid)
GameScene:setPos(mycell)

end

end
end

function Actor:moveCircle()
local a; local b; local ab
local startX
local startY

if self.move then
if self.offset==#self.tab1-1 then
self:reset()
return
end

a=math.abs(self.tab1[self.offset].x-self.mx)    -- calc new x,y direction
b=math.abs(self.tab1[self.offset].y-self.my)
ab=math.sqrt(a*a+b*b)

if ab<5 then
self.offset = self.offset + 1
startX = self.dx
startY = self.dy
self.dx=self.tab1[self.offset].x-self.mx
self.dy=self.tab1[self.offset].y-self.my
local vecself= vec2(self.tab1[self.offset-1].x,self.tab1[self.offset-1].y)
local vecother = vec2(self.tab1[self.offset].x,self.tab1[self.offset].y)
local vec = vecother - vecself
self.angle = math.deg(vec:angleBetween(vec2(0,1)))
end
end
end

function printTables(table)
for i=1,#table do
print(i..".) table.x,y: "..table[i].x..","..table[i].y)
end
end

function Actor:calcDist()
local t=#self.tab1
local a; local b
if t>1 then
a=self.hx-self.tab1[t].x
b=self.hy-self.tab1[t].y

if a*a+b*b>1024 then
return true
end
return false
end
return true

end

function Actor:fillMoveList()
print("filling list")

local last = vec2(self.x,self.y)
table.insert(self.moves,last)
for z=self.offset+1,#self.tab1-1 do

local startX = self.tab1[z-1].x
local startY = self.tab1[z-1].y
local nextX = self.tab1[z].x
local nextY = self.tab1[z].y
local diffX = startX - nextX
local diffY = startY - nextY
local buffer = 20

local up = vec2(last.x,(last.y + self.size))
local right = vec2((last.x + self.size),last.y)
local down = vec2(last.x,(last.y - self.size))
local left = vec2((last.x - self.size),last.y)

print("diff x,y: "..diffX..","..diffY)
if diffX < -buffer then
print("Right")
table.insert(self.moves,right)
last = right
elseif diffX > buffer then
print("Left")
table.insert(self.moves,left)
last = left
elseif diffY < -buffer then
print("Up")
table.insert(self.moves,up)
last = up
elseif diffY > buffer then
print("Down")
table.insert(self.moves,down)
last = down
end
end
end

``````

it seems to me you are providing self as the target for tweening. My understanding is that target needs to be a table of key value pairs.

Isn’t self a table of key-value pairs?

maybe, but not the ones he wants. He needs to provide the set of numeric values he actually wants to tween. Self includes all sorts of stuff including text, which doesn’t tween very well

self totally works, now I just have to figure out how to also apply rotation.

this is what my rotLeft function looks like now,

``````function Actor:rotLeft()
local target = {x=self.x+10, y=self.y+10}
self.move = false