Skip to content

Instantly share code, notes, and snippets.

@peteroyle
Created May 10, 2012 12:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peteroyle/2652743 to your computer and use it in GitHub Desktop.
Save peteroyle/2652743 to your computer and use it in GitHub Desktop.
Split Screen In Codea
--# Menu
Menu = class()
function Menu:init()
end
function Menu:draw()
if self.main then
-- draw game
self.main:draw()
else
-- draw menu
fill(17, 17, 17, 255)
rect(0,0,WIDTH, HEIGHT)
fill(255, 216, 0, 255)
fontSize(100)
text("1 player", WIDTH*0.25, HEIGHT*0.5)
text("2 players", WIDTH*0.75, HEIGHT*0.5)
end
end
function Menu:touched(touch)
if self.main then
-- main game crontrol
self.main:touched(touch)
else
-- menu control
if touch.state == BEGAN then
local numPlayers = 1
if touch.x > WIDTH*0.5 then
numPlayers = 2
end
self:startGame(numPlayers)
end
end
end
function Menu:startGame(numPlayers)
print("Starting with " .. numPlayers .. " player(s)")
self.main = Main()
if numPlayers == 1 then
self.main:setupGame(self, nil)
else
local trans1 = GameBoardTransform(vec2(0.65, 0.65), -90, vec2(0-WIDTH, 0)) -- s, r, t
self.main:setupGame(self, trans1)
local trans2 = GameBoardTransform(vec2(0.65, 0.65), 90, vec2(0, 0-HEIGHT*2.05)) -- s, r, t
self.main:setupGame(self, trans2)
end
end
--# Main
displayMode(FULLSCREEN)
menu = Menu()
-- This function gets called once every frame
function draw()
menu:draw()
end
function touched(t)
menu:touched(t)
end
Main = class()
function Main:init()
self.touches={}
self.players = {}
self.numPlayers = 0
end
-- After you create a Main() instance, call this method once for each pplayer
function Main:setupGame(menu, transform)
local gameBoard = GameBoard(transform, menu, table.maxn(self.players)+1)
table.insert(self.players, {gameBoard=gameBoard})
self.numPlayers = self.numPlayers + 1
end
-- render each player's game board
function Main:draw()
fill(0, 0, 0, 255)
rect(0,0,WIDTH+1,HEIGHT+1)
for i,p in ipairs(self.players) do
p.gameBoard:draw()
end
end
-- handle multitouch, passing each touch to each player's game board
function Main:touched(touch)
self.touches[touch.id] = touch
for i,p in ipairs(self.players) do
for j,t in pairs(self.touches) do
p.gameBoard:touched(t)
end
end
if touch.state == ENDED then
self.touches[touch.id] = nil
end
end
--# GameBoard
GameBoard = class()
-- each player will get their own game board
function GameBoard:init(transform, mainMenu, playerNum)
self.transform = transform
self.mainMenu = mainMenu
self.playerNum = playerNum
self.circles={}
self.color = color(math.random()*255, math.random()*255, math.random()*255, 255)
self:initClipping()
end
-- calculate the appropriate clipping rectangle for the game board taking
-- into account the transformation if any
function GameBoard:initClipping()
if self.transform then
local a = self.transform:applyToPoint(0,0)
local b = self.transform:applyToPoint(WIDTH, HEIGHT)
self.clipDimA = vec2(math.min(a.x, b.x), math.min(a.y,b.y))
self.clipDimB = vec2(math.max(a.x, b.x), math.max(a.y,b.y))
-- convert b to width/height for clip()
self.clipDimB = (self.clipDimB - self.clipDimA) + vec2(1,1)
else
self.clipDimA = vec2(0,0)
self.clipDimB = self.frameDimensions
end
end
function GameBoard:applyMultiplayerClip()
if self.transform then
clip(self.clipDimA.x, self.clipDimA.y, self.clipDimB.x, self.clipDimB.y)
end
end
function GameBoard:removeMultiplayerClip()
if self.transform then
clip()
end
end
-- draw the game board, applying the transformation first if one is specified
function GameBoard:draw()
pushStyle()
pushMatrix()
if self.transform then
self.transform:transform()
self:applyMultiplayerClip()
end
fill(self.color)
for i,v in ipairs(self.circles) do
ellipse(v.x, v.y, 200, 200)
end
fontSize(200)
text("Player " .. self.playerNum, WIDTH*0.5, HEIGHT*0.5)
self:removeMultiplayerClip()
popMatrix()
popStyle()
end
function GameBoard:isTouchInsideBoard(t)
return t.x >= 0 and t.x <= WIDTH and
t.y >= 0 and t.y <= HEIGHT
end
-- if a visual transform is specified, apply the reverse transformation
-- to the touch before using it
function GameBoard:touched(t)
if self.transform then
local oldTouch = t
local newVec = self.transform:applyInvToPoint(t.x, t.y)
t = {x = newVec.x, y = newVec.y, state = oldTouch.state,
id = oldTouch.id}
end
if self:isTouchInsideBoard(t) then
table.insert(self.circles, vec2(t.x,t.y))
end
end
--# GameBoardTransform
GameBoardTransform = class()
function GameBoardTransform:init(tscale, trotate, ttranslate)
self.tscale = tscale
self.trotate = trotate
self.ttranslate = ttranslate
end
function GameBoardTransform:transform()
if self.trotate then
rotate(self.trotate)
end
if self.tscale then
scale(self.tscale.x, self.tscale.y)
end
if self.ttranslate then
translate(self.ttranslate.x, self.ttranslate.y)
end
end
function GameBoardTransform:calcInverse()
if self.inverse then
return
end
self.inverse = GameBoardTransform(
vec2(1/self.tscale.x, 1/self.tscale.y), 360-self.trotate,
vec2(0,0)-self.ttranslate)
end
function GameBoardTransform:applyToPoint(x, y)
local vec = vec2(x,y)
vec = vec + vec2(self.ttranslate.x,self.ttranslate.y)
vec = vec2(vec.x*self.tscale.x,vec.y*self.tscale.y)
vec = vec:rotate(math.rad(self.trotate))
return vec
end
function GameBoardTransform:applyInvToPoint(x, y)
self:calcInverse()
local vec = vec2(x, y)
vec = vec2(x*self.inverse.tscale.x,y*self.inverse.tscale.y)
vec = vec:rotate(math.rad(self.inverse.trotate))
vec = vec + (self.inverse.ttranslate)
return vec
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment