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

in Questions 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(,,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(,,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 = 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) = + ( = + ( 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 x = math.cos(math.rad(lo*res))*math.cos(math.rad(90-la*res))*s y = math.sin(math.rad(90-la*res))*s z = math.sin(math.rad(lo*res))*math.cos(math.rad(90-la*res))*s local v1 = vec3(x,y,z) x = math.cos(math.rad((lo+1)*res))*math.cos(math.rad(90-la*res))*s y = math.sin(math.rad(90-la*res))*s z = math.sin(math.rad((lo+1)*res))*math.cos(math.rad(90-la*res))*s local v2 = vec3(x,y,z) x = math.cos(math.rad((lo+1)*res))* math.cos(math.rad(90-(la+1)*res))*s y = math.sin(math.rad(90-(la+1)*res))*s z = math.sin(math.rad((lo+1)*res))* math.cos(math.rad(90-(la+1)*res))*s local v3 = vec3(x,y,z) x = math.cos(math.rad(lo*res))*math.cos(math.rad(90-(la+1)*res))*s y = math.sin(math.rad(90-(la+1)*res))*s z = math.sin(math.rad(lo*res))*math.cos(math.rad(90-(la+1)*res))*s 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!



  • Posts: 748

    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
  • Posts: 2,011

    @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
    Changing it to this fixed it

Sign In or Register to comment.