#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# How to do split screen in 3D

Posts: 103

Hey guys!
So I'm working on a two player game in 3D, but I'm getting stuck on the split screen part. I was able to get the camera to focus on player one on the bottom half of the screen, but I can't figure out how to get the second camera to work.

Here's my code so far

``````--# Main

-- Physics
PLAYER_ONE = 1
PLAYER_TWO = 2
PLATFORM = 3
displayMode(FULLSCREEN)
function setup()
gameMode = 2

platforms = {}
p1 = Player(1)
if gameMode == 2 then p2 = Player(2) end

for i = 1,5 do
table.insert(platforms,
Platform(math.random(WIDTH),math.random(HEIGHT)))
end
end

function draw()
background(40,40,50)

pushMatrix()
ortho()
translate(0,-HEIGHT/4)
clip(0,0,WIDTH,HEIGHT/2)
perspective(10)
camera(p1.cam.x,p1.cam.y,5000,p1.body.x,p1.body.y,0,0,1,0)
for i,p in pairs(platforms) do
p:draw()
end
p1:draw()
p2:draw()
popMatrix()

pushMatrix()
ortho()
translate(WIDTH,HEIGHT)
rotate(180)
translate(0,-HEIGHT/4)
clip(0,HEIGHT/2,WIDTH,HEIGHT/2)
perspective(10)
camera(p2.cam.x,p2.cam.y,5000,p2.body.x,p2.body.y,0,0,1,0)
for i,p in pairs(platforms) do
p:draw()
end
p1:draw()
p2:draw()
popMatrix()

end

function touched(touch)
p1:touched(touch)
p2:touched(touch)
end

--# Player
Player = class()

function Player:init(id)
self.body = physics.body(CIRCLE,50)
self.body.position = vec2(100+200*id,600)
-- self.body.linearDamping = 2
self.body.restitution = 0
self.body.friction = 1
self.body.gravityScale = 1

self.cam = vec2(x,y)
self:createSphere(id)
end

function Player:draw()
pushMatrix()
-- fill(0,100,255)
if self == p1 then
stroke(0,100,255)
else
stroke(255,50,0)
end
strokeWidth(7)
translate(self.body.x,self.body.y)
-- ellipse(0,0,100)
self.sphere:draw()
if self.jump then
line(0,0,self.jump.x,self.jump.y)
end
popMatrix()

self.camTarget = self.body.position-self.body.linearVelocity/50+vec2(0,1)
self.cam.x = self.cam.x + (self.camTarget.x-self.cam.x)/20
self.cam.y = self.cam.y + (self.camTarget.y-self.cam.y)/40

end

function Player:touched(touch)
if touch.state == BEGAN then self.jump = vec2(0,150) end
if self.jump then
if self == p1 then
self.jump = self.jump:rotate(-touch.deltaX/100)
else
self.jump = self.jump:rotate(-touch.deltaX/100)
end
end
if touch.state == ENDED and self.jump then
self.body:applyLinearImpulse(self.jump:normalize()*20)
self.jump = nil
end
end

function Player:createSphere(id)
self.sphere = mesh()
local verts = {}
local colors = {}

local res = 10
local s = 50
local long,lat = 360/res,180/res
for la = 0,lat-1 do
for lo = 1,long do
local c1,c2
if id == 1 then
c1 = color(0,50-la*lat/5,255-la*lat/5)
c2 = color(0,50-la*lat/5,255-(la+1)*lat/5)
else
c1 = color(255-la*lat/5,0,0)
c2 = color(255-(la+1)*lat/5,0,0)
end

local x,y,z
local v1 = vec3(x,y,z)
local v2 = vec3(x,y,z)
local v3 = vec3(x,y,z)
local v4 = vec3(x,y,z)
local v = {v1,v2,v3,v3,v4,v1}
local c = {c1,c1,c2,c2,c2,c1}
for i,vv in pairs(v) do table.insert(verts,vv) end
for i,cc in pairs(c) do table.insert(colors,cc) end
end
end
self.sphere.vertices = verts
self.sphere.colors = colors
print(#verts,#colors)
end

--# Platform
Platform = class()

function Platform:init(x,y)
self.x = x
self.y = y
self.w = math.random(150,200)
self.h = math.random(25,50)
local w,h = self.w/2,self.h/2
self.pivot = physics.body(CIRCLE,10)
self.pivot.position = vec2(x,y)
self.pivot.type = STATIC
self.platform = physics.body(POLYGON,
vec2(w,h),vec2(w,-h),vec2(-w,-h),vec2(-w,h))
self.platform.position = vec2(x,y)
self.platform.restitution = 0
self.platform.friction = 1
self.joint =
physics.joint(WELD,self.pivot,self.platform,vec2(x,y))
self.joint.frequency = 0.9
self.joint.dampingRatio = 0.1

self.m = mesh()
local z = 150
local v1,v2,v3,v4 = vec3(-w,h,z),vec3(w,h,z),vec3(w,-h,z),vec3(-w,-h,z)
local v5,v6,v7,v8 = vec3(-w,h,-z),vec3(w,h,-z),vec3(w,-h,-z),vec3(-w,-h,-z)
self.m.vertices = {
v1,v2,v3,v3,v4,v1,
v1,v2,v6,v6,v5,v1,
v5,v6,v7,v7,v8,v5,
v3,v4,v8,v8,v7,v3,
v1,v4,v8,v8,v5,v1,
v2,v3,v7,v7,v6,v2}
local c1,c2,c3 = color(0,50,255),color(0,45,230),color(0,35,200)
local c4,c5,c6 = color(0,30,190),color(0,40,210),color(0,25,170)
self.m.colors = {
c1,c1,c1,c1,c1,c1,
c2,c2,c2,c2,c2,c2,
c3,c3,c3,c3,c3,c3,
c4,c4,c4,c4,c4,c4,
c5,c5,c5,c5,c5,c5,
c6,c6,c6,c6,c6,c6}
end

function Platform:draw()
pushMatrix()
translate(self.x,self.y)
noStroke()
fill(0,100,255)
rotate(self.platform.angle)
local w,h = self.w/2,self.h/2
self.m:draw()
popMatrix()
end

function Platform:touched(touch)

end

``````

I did also try rendering it onto two separate images, but that didn't work either. Is there a way to save the camera view to an image?

Thanks for the help!

Tagged:

• Mod
Posts: 891

Codea Craft will make 3D easier. As now, I only can think of

• mesh()'es
• `translate(X, y, z)` -- Translates the view to X, y, z
• `rotate(X, y, z)` -- Rotates the view to X, y, z
• Mod
Posts: 2,020

@Dwins you're on the right lines. I did split-screen 3D for Banjax. I created a `Viewport` class for each view (to cut out code repetition, keep it DRY).

The order you need for each viewport draw is (starting in 2D mode) is:

• clip
• perspective
• camera
• draw all objects:

• pushMatrix
• translate
• rotate
• draw
• popMatrix
• `ortho()`
• `viewMatrix(matrix())`
• draw any 2D overlays

Then do it again for the other viewport.

• Posts: 103

@yojimbo2000 thank you!
The problem was actually in this line
`camera(p2.cam.x,p2.cam.y,2000,p2.body.x,p2.body.y,0,0,1,0)`
Changing it to this fixed it
`camera(WIDTH-p2.cam.x,HEIGHT-p2.cam.y,2000,WIDTH-p2.body.x,HEIGHT-p2.body.y,0,0,1,0)`