Portal 2D (new game, old idea)

I decided to make a 2D version of portal. Ive created a player class that handles all the movement, portals and a map editor to easily make the maps. I’m just scrubbing down the physics for the player and the movement (still a few things to be perfected) but as you’ll see in the video the teleporting has no special fx (or effects) and it just does it by distance, I want to find out how to use things like clip and others to create this sort of effect: http://images5.fanpop.com/image/photos/29300000/Portal-Images-portal-the-game-29379422-1920-1080.jpg or http://www.previewsworld.com/catalogimages/STK_IMAGES/STK460001-480000/STK466807.jpg
I’m not sure which way to do this and keep the same physics of being able to constantly loop through teleports.
Any ideas are greatly appreciated!


Nice Work @Luatee I tried to make Portal 2D once but failed cause I couldn’t make the player teleport properly. And I love the way you handle your players. Even in spline rider your bike guy was awesome!!

Well he never actually enters the portal ATM as its just a wall and a position on the wall, I’m more concerned about the teleportation at the moment, I tend to need to finish what I’m on before I move on but I don’t organise my coding time like you get taught in computer sciences and such so it can get a bit messy, I’m glad I handle the player all in one class though. The draw function in main is 13 lines and the touch function is 17, Ill also handle the levels in a class aswell probably, but I want to get some nice fx on the portal when he enters. Thanks for the feedback!

That little dude is going to need a helmet! ;))

This is bad! http://www.youtube.com/watch?v=c3MkFvPBgCA

Haha!, so cool :slight_smile: I liked it, add some particle effects and short term objetives!

I’m planning on creating an fx class and I’m going to make about 10 levels for now and there are obstacles on the map and you need to get from one side of the other using teleports. Thanks!

I use to get the same problem as you have shown in the video. The way i did the teleportation was make sensors on the wall and then changing its position every time it it was shot on another wall. To teleport i used to check whether the player was 20 pixels ahead of the portal. I had to do that else he would teleport continuously. And during this check if he falls vertically then the same things happens. How do you check for teleportation??

I use polygons and function collide() to check, im planning on using a different method as i need to be able to make the player move in to the wall to give a half in half out effect

the only way i can think of is destroying part of the wall when a portal is created on it and then recreate it.

I was thinking along these lines aswell but I had an idea to make it so when the player touches the portal sensor, I remove the collision from either the ragdoll or wall to allow it to pass through, then use set context to get the image behind the portal, and then when most of his body is inside it teleports him

Nice I didn’t think about that.

Nice! Maybe you can render it as confusing as the portal 2d ascii version?


Wow! That looks pretty cool, its not a bad idea either but that’s not my focus at the moment, I’ll definitely look in to the effects for this game once I get the portals mirroring effect working properly

Added a little effect to the portals and improved the teleportation, added character body and improved walking and getting up: http://www.youtube.com/watch?v=HtMpvHCwqTQ

Nice! I love how he walks lol

Thanks, any ideas people would like to throw in? I’m going to add a companion cube for the story mode

How can I replicate this portal effect more efficiently?

-- portalmiror

-- Use this function to perform your initial setup
function setup()
    p1 = {}
    p2 = {}
    normal = vec2(-1,0)
    local w,h = 70,70
    local verts = {vec2(-w/2,-h/2),vec2(w/2,-h/2),vec2(w/2,h/2),vec2(-w/2,h/2)}
    companion = physics.body(POLYGON,unpack(verts))
    companion.position = vec2(WIDTH/2,HEIGHT/2)
    companion.gravityScale = 0
    m = mesh()
    r = m:addRect(companion.x,companion.y,w,h)
    m.texture = readImage("Documents:ROBOTHEAD")
    p1.x,p1.y = WIDTH-50,HEIGHT/2
    local w,h
    if math.abs(normal.x) > 0.5 then
        w,h = 10,130
        w,h = 130,10
    local verts = {vec2(-w/2,-h/2),vec2(-w/2,h/2),vec2(w/2,h/2),vec2(w/2,-h/2)}
    p1.normal = normal
    if p1.portal then
    p1.portal = physics.body(POLYGON,unpack(verts))
    p1.pedgeup = physics.body(EDGE,vec2(-w/2,h/2),vec2(w/2,h/2))
    p1.pedgeup.type = STATIC
    p1.pedgeup.position = vec2(p1.x,p1.y)
    p1.pedgedown = physics.body(EDGE,vec2(-w/2,-h/2),vec2(w/2,-h/2))
    p1.pedgedown.type = STATIC
    p1.pedgedown.position = vec2(p1.x,p1.y)
    p1.pback = physics.body(POLYGON,vec2(40,h/2),vec2(40,-h/2),vec2(50,-h/2),vec2(50,h/2))
    p1.pback.position = vec2(p1.x,p1.y)
    p1.pback.type = STATIC
    p1.pback.sensor = true
    p1.portal.position = vec2(p1.x,p1.y)
    p1.portal.type = STATIC
    p1.portal.sensor = true
    p1.m = mesh()
    p1.r = p1.m:addRect(p1.x,p1.y,w,h)
    p1.texture = readImage("Documents:whitecircle",w,h)
    p2.x,p2.y = 50,HEIGHT/2
    local w,h
    if math.abs(-normal.x) > 0.5 then
        w,h = 10,130
        w,h = 130,10
    local verts = {vec2(-w/2,-h/2),vec2(-w/2,h/2),vec2(w/2,h/2),vec2(w/2,-h/2)}
    p2.normal = -normal
    if p2.portal then
    p2.pedgeup = physics.body(EDGE,vec2(-w/2,h/2),vec2(w/2,h/2))
    p2.pedgeup.type = STATIC
    p2.pedgeup.position = vec2(p2.x,p2.y)
    p2.pedgedown = physics.body(EDGE,vec2(-w/2,-h/2),vec2(w/2,-h/2))
    p2.pedgedown.type = STATIC
    p2.pedgedown.position = vec2(p2.x,p2.y)
    p2.pback = physics.body(POLYGON,vec2(-40,h/2),vec2(-40,-h/2),vec2(-50,-h/2),vec2(-50,h/2))
    p2.pback.position = vec2(p2.x,p2.y)
    p2.pback.type = STATIC
    p2.pback.sensor = true
    p2.portal = physics.body(POLYGON,unpack(verts))
    p2.portal.position = vec2(p2.x,p2.y)
    p2.portal.type = STATIC
    p2.portal.sensor = true
    p2.m = mesh()
    p2.r = p2.m:addRect(p2.x,p2.y,w,h)
    p2.texture = readImage("Documents:whitecircle",w,h)
    img = image(WIDTH,HEIGHT)
    t = nil

function collide(c)
    if c.bodyA == companion and c.bodyB == p1.pback then
        companion.position = vec2(p2.x,p2.y)
    if c.bodyA == companion and c.bodyB == p2.pback then
        companion.position = vec2(p1.x,p1.y)

function touched(tch)
    t = tch
    if tch.state == ENDED then
        t = nil
-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)

    -- This sets the line thickness
    if t~=nil then
    companion.linearVelocity = companion.linearVelocity*0.9
    companion.angularVelocity = companion.angularVelocity*0.9
    -- Do your drawing here
    local imgt
    local imgy
    if companion.x > WIDTH-85 then
        imgt = img:copy(WIDTH-50,HEIGHT/2-65,50,130)
    if companion.x < 85 then
        imgy = img:copy(0,HEIGHT/2-65,50,130)
    if imgt then
    if imgy then

Why are you using those bodies? , I am thinking that you could just a sprite or spritesheet (animation) or a single image with the fx shader ripple or other which give the appearance of moving/blur/glow…

Looks very cool.

Can I ask a slightly unrelated question: What happens when both of your portals are on the same side of a wall e.g. both on the right. Then you move the guy right and he has some momentum and he comes out of the portal with momentum left? and as long as you stop pushing right its ok? It would be difficult to slowly walk through a portal I imagine? What happens when you stop halfway through and try to go left/right?

Sorry I am a complete noob, but conceptually I see that being slightly related to your dilemma.