Created
May 10, 2012 12:24
-
-
Save peteroyle/2652743 to your computer and use it in GitHub Desktop.
Split Screen In Codea
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# 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