Howdy, Stranger!

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

Multiplayer Splitscreen Help

in Questions Posts: 104

In my game, I’ve clipped my screen so you can only see one half of what’s happening on the screen. How do I make it so you can see a different screen on the other side?

Thank you :)

Comments

  • edited August 28 Posts: 2,364

    @Creator27 - I think you need to provide us with a little more detail. For instance:

    1. Are both screens animated - like a two player game?
    2. Does one screen area hold controls or player details?
    3. Does one screen hold a map?

    You may not need two clipped areas.

  • Posts: 104
    1. The screens are supposed to be two separate cameras beside each other.

    2.The cameras are both looking at two capsules that move left and right depending on where you are touching on the screen.

  • edited August 28 Posts: 104

    Here’s the code that I have done on my game so far just to give you a bit of context on what I’m dealing with here:

    -- Test Shooter
    
    function setup()
        -- Create a new craft scene
        scene = craft.scene()
        scene.physics.gravity = vec3(0, 1, 0)
        viewer.mode = FULLSCREEN
    
    
        -- Create a new entity
        local entity = scene:entity()
        body = entity:add(craft.rigidbody)
        entity.model = craft.model(asset.builtin.Primitives.Capsule)
        entity.material = craft.material(asset.builtin.Materials.Specular)
        entity.y = -1
        entity.z = 0
        entity.scale = vec3(1,1,1) / 8
        entity.eulerAngles = vec3(0, 180, 0)
    
        scene.camera.z = -4 
    
    
    
        local entity2 = scene:entity()
        body2 = entity2:add(craft.rigidbody)
    
        entity2.model = craft.model(asset.builtin.Primitives.Capsule)
        entity2.material = craft.material(asset.builtin.Materials.Specular)
        entity2.y = -1
        entity2.z = 0
        entity2.scale = vec3(1,1,1) / 8
        entity2.eulerAngles = vec3(0, 180, 0)
    
    
        if entity.y >= 700 then
            body:applyForce(vec3(0, -30, 0))
        end
    end
    
    function touched(touch)
        if touch.state == MOVING and touch.x < 500 then
            body:applyForce(vec3(1, 0, 0))
        end
    
        if touch.state == MOVING and touch.x < 500 then
            body:applyForce(vec3(1, 0, 0))
        end
    end
    
    function update(dt)
        -- Update the scene (physics, transforms etc)
        scene:update(dt)
    end
    
    -- Called automatically by codea 
    function draw()
        update(DeltaTime)
        clip(0, 0, 540, 900)
    
        -- Draw the scene
        scene:draw()    
    end
    
  • Posts: 1,090

    The easiest thing for me is this:

    1. Write two drawStuff functions that can draw the view for one player or the other, on the left side of the screen.
    2. In the one I want on the right, add a pushMatrix at the top, a popMatrix at the bottom.
    3. After the pushMatrix, put a call to translate, giving it the coordinate I want the second guy to draw at, typically WIDTH/2, 0

    After that, the second guy should draw on the right side. Try it with a small example first to get the hang of it.

    Good luck!

  • edited August 28 Posts: 2,364
    @Creator27 - just looking at your code. I was thinking of doing something similar with a plane in flight. So you could access views of the craft from 6 90degree angles. What I was thinking of doing was having just 1 view selectable by having 6 camera view definitions in Craft. That would allow 360° views around the ship.

    I intended locking the camera position to the ship so you always see the ship as it was defined but the background rotates around you.
  • edited August 28 Posts: 1,292

    In Codea, some folks savor the experience of figuring out how to do everything from scratch, and some folks prefer to search out stuff other people have already done and try to build on top of it—I’m more of the second camp, myself, and if you are too, I suggest downloading @Steppers’s phenomenal WebRepo project and using it to get a project called “Shooter”.

    It’s not fully finished, so it’s rough around the edges, and it’s made in 2D not in Craft, and for a beginner all that code might be a formidable challenge to dig through, but it’s a split-screen head-to-head shooter, with different weapons, power ups, teleportation portals, and a map editor.

    If I were you I’d consider it a treasure trove of free code that would save me countless hours of re-inventing the wheel, and I’d rummage through the code, pull out everything I could use, and rejigger it to serve my own purposes.

    WebRepo is here: https://codea.io/talk/discussion/11724/webrepo-1-3-easy-access-to-projects-from-the-codea-community/p2

    You’ll need a GitHub account, but those are free too.

  • edited August 29 Posts: 104

    Hey there, before any of you guys commented on this, I was able to “partially” fix the split screen but with two problems.

    The first problem, is that when I restart my game, one of the players is frozen on the spot until I touch the screen somewhere.

    The second problem, is that at any given time, either the left screen, the right screen or even both screens can freeze instantaneously, and the only way to fix it is to reset the game.

    Here’s the code that I have written so you can see if there might be any potential errors or bugs:

    -- Test Shooter
    
    function setup()
        -- Create a new craft scene
        scene = craft.scene()
        scene.physics.gravity = vec3(0, 1, 0)
        viewer.mode = FULLSCREEN
        clipScreen = false
    
    
        -- Create a new entity
        local entity = scene:entity()
        body = entity:add(craft.rigidbody)
        entity.model = craft.model(asset.builtin.Primitives.Capsule)
        entity.material = craft.material(asset.builtin.Materials.Specular)
        entity.material.map = readImage(asset.builtin.Blocks.Grass_Top)
        entity.y = -1
        entity.z = 0
        entity.scale = vec3(1,1,1) / 8
        entity.eulerAngles = vec3(0, 0, 0)
    
        scene.camera.z = -4 
    
    
    
        local entity2 = scene:entity()
        body2 = entity2:add(craft.rigidbody)
    
        entity2.model = craft.model(asset.builtin.Primitives.Capsule)
        entity2.material = craft.material(asset.builtin.Materials.Specular)
        entity2.y = -1
        entity2.z = 0
        entity2.scale = vec3(1,1,1) / 8
        entity2.eulerAngles = vec3(0, 180, 0)
    
    
    
    
    
    
        if entity.y >= 700 then
            body:applyForce(vec3(0, -30, 0))
        end
    end
    
    function touched(touch)
        if touch.state == MOVING and touch.x < 500 then
            body:applyForce(vec3(1, 0, 0))
        end
    
        if touch.state == MOVING and touch.x > 500 then
            body2:applyForce(vec3(-1, 0, 0))
        end
    
        if clipScreen == false then
            clipScreen = true
        end
    
        if touch.state == BEGAN and touch.x < 500 then
            body:applyForce(vec3(0, -60, 0))
        end
    
        if touch.state == BEGAN and touch.x > 500 then
            body2:applyForce(vec3(0, -60, 0))
        end
    
        if touch.tapCount == 4 then
            body:applyForce(vec3(0, -60, 0))
            body2:applyForce(vec3(0, -60, 0))
        end
    end
    
    function update(dt)
        -- Update the scene (physics, transforms etc)
        scene:update(dt)
    end
    
    -- Called automatically by codea 
    function draw()
        update(DeltaTime)
    
        -- Buggy splitscreen :)
        if clipScreen == false then
            clip(0, 0, 540, 900)
            clip(540, 0, 540, 900)
        end
    
    
        -- Draw the scene
        scene:draw()
    
        -- Indicate the splitscreen point
        rect(535, 0, 10, 810)   
    end
    
  • dave1707dave1707 Mod
    Posts: 9,441

    @Creator27 Whenever you post code, put ~~~ (3 tildes) on a line before and after your code so it formats correctly. I added them to your above code.

  • Posts: 104

    Thank you :)

  • edited August 29 Posts: 104

    @RonJeffries, your method did not work. Is there some sort of alternative to your comment?

  • Posts: 198

    @Creator27 Take a look at the setContext() function.

    You should be able to create new texture (framebuffer) for the splitscreens/viewports at the correctly divided resolution, use setContext prior to drawing and render to it from the corresponding players perspective.

    Once you've drawn to the framebuffer you can then call setContext() again with no arguments before rendering the framebuffer to the screen to be visible to the user.

    Rinse and repeat for each viewport.

    local fb
    local w = WIDTH * ContentScaleFactor
    local h = (HEIGHT/2) * ContentScaleFactor
    
    function setup()
        -- Create framebuffer image
        fb = image(w, h)
    
        -- Render defaults
        fill(255)
        spriteMode(CORNER)
    end
    
    function draw()
        -- Bind the framebuffer
        setContext(fb, true)
        background(255, 0, 0)
    
        -- Draw view 1 here
        ellipse(w/2, 3*h/4, 40, 60)
    
        -- Draw framebuffer to screen
        setContext()
        sprite(fb, 0, 0, WIDTH, HEIGHT/2)
    
    
        -- Bind the framebuffer
        setContext(fb, true)
        background(63, 0, 255)
    
        -- Draw view 2 here
        ellipse(w/4, h/2, 60, 40)
    
        -- Draw framebuffer to screen
        setContext()
        sprite(fb, 0, HEIGHT/2, WIDTH, HEIGHT/2)
    end
    

    Doing it this way you can probably avoid a lot of strange transformation awkwardness you'd get by doing it any other way as the rendering will be correctly mapped to the framebuffer image.

  • Posts: 1,292

    There’s a post here called “how to do split screen in 3D:” https://codea.io/talk/discussion/7798/how-to-do-split-screen-in-3d

  • Posts: 1,090

    ah, sorry, didn't realize you were doing 3d. My scheme only works for simple 2D

Sign In or Register to comment.