Howdy, Stranger!

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

In this Discussion

Multiplayer games using sockets.

dave1707dave1707 Mod
edited May 9 in Code Sharing Posts: 5,744

I just got a second iPad and decided to try a multiplayer game using sockets. One problem I had was trying to keep the code in sync on both iPads as I kept making changes/fixes. At first, I would copy the Codea code, paste it in an email and email it to the other iPad. I would open the email there, copy the code and paste it into a project. Well, that got old real fast. So I set up this code to make it easier for me. I copy the code I want to send, run this code on both iPads, paste the copied code into the parameter message area, and press send message. On the other iPad, the sent code is printed in the print area. I then tap on the print area which copies the code to the pasteboard. I close this code, open the project where I want the new code and do a paste. It's a little easier and I'm not messing around with email. To use this code, go to the Settings app, select Wi-Fi, tap your wi-fi name and get your IP address. Put that IP address in myIp. Get the IP address of the other iPad and put it in theirIp. Do the same on the other iPad. The myIp and theirIp will be flipped on both iPads. There's code that will get the IP address automatically, but I didn't include it. Once the ip addresses are set, I don't think they change. At least they haven't for me.

As for the multiplayer game, it's a simple game similar to TRON. Not a lot is being put into the game because I want to show what it takes to use sockets for a multiplayer game. The game currently runs OK, but I'm still testing it. I'll post it here a little later. One of the problems people were having was the games getting out of sync as you played. I added code that keeps both iPads in sync for this game.

function setup()    
    socket = require("socket")

    myIp="192.168.254.27"           -- this ipads IP address
    theirIp="192.168.254.15"        -- the other ipads ip address

    server = socket.udp()
    server:setsockname(myIp,5544)
    server:settimeout(0)

    client = socket.udp()
    client:setpeername(theirIp,5544)
    client:settimeout(0)

    parameter.text("msg", "")
    parameter.action("send message", sendMessage)
end

function sendMessage()
    client:send(msg)
end

function draw()
    background(0)
    local data, msgOrIp, portOrNil=server:receivefrom()
    if data~=nil then
        print(data)
    end
end

Comments

  • dave1707dave1707 Mod
    edited May 9 Posts: 5,744

    Here's the simple multiplayer TRON type game. Copy this code to both iPads. See the discussion above for setting the 2 ip addresses. One other thing that needs to be done is to select the player color. One iPad needs to set the col variable to 1 (red) and the other iPad to 2 (green). The object of the game is to surround the other player and force them to either run into their own trail or your trail. When that happens I show the losing color. To change the player direction, tap one of the buttons. If your going up, don't press the down button or you'll run into your own tail. Same for the other directions, don't press the opposite button. I don't have any restart code, so when the game is over, press the arrow in the lower left corner to get back to the editor. Start both programs to play again.

    EDIT: Corrected an error.

    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_ANY)
    
    function setup()
        col=1   -- determine who wants to be 1 (red) and who wants to be 2 (green)
        cTab={color(255,0,0),color(0,255,0)}
        w=1020  -- size for a 9.7" ipad, multiple of size
        h=760   -- size for a 9.7" ipad, multiple of size
        size=10
        sr=0
        tabSr={}
        cnt=0
        if col==1 then
            x=200
        else
            x=w-200
        end
        y=100
        vx,vy=0,size
        tab={vec3(x,y,col)}
    
        myIp="192.168.254.27"           -- this ipads ip address
        theirIp="192.168.254.15"        -- the other ipads ip address
    
        socket = require("socket")
        server = socket.udp()
        server:setsockname(myIp,5544)
        server:settimeout(0)
        client = socket.udp()
        client:setpeername(theirIp,5544)
        client:settimeout(0)
    end
    
    function draw()
        background(0)
        fill(123, 200, 225, 255)
        rect(0,0,w,h)
        fill(cTab[col])
        rect(50,h/2,50,50)
        rect(w-100,h/2,50,50)
        rect(w/2,50,50,50)
        rect(w/2,h-100,50,50)
        receive()
        stroke(255)
        strokeWidth(2)
        -- draw both player positions
        for a,b in pairs(tab) do
            fill(cTab[b.z])
            rect(b.x,b.y,size,size)
        end
        cnt=cnt+1
        if cnt%5==0 then
            checkSr()
        end
        if cnt>15 and not over then -- move player every 1/2 second
            cnt=0
            x=x+vx
            y=y+vy
            if x<=0 or x>=w or y<=0 or y>=h then
                gameOver()
            else
                checkHit()
            end
            table.insert(tab,vec3(x,y,col))
            sr=sr+1
            tabSr[sr]=vec4(x,y,sr,0)
            send(sr..","..x..","..y..","..col)
        end
        if over then    -- display game over message
            fill(255)
            rect(w/2-200,h/2-50,400,100)
            fill(cTab[lost])    
            text("GAME OVER...THIS COLOR LOST",w/2,h/2)
        end
    end
    
    function checkHit()
        -- check if player ran into itself or the other player
        for z=1,#tab-1 do
            if x==tab[z].x and y==tab[z].y then
                gameOver()
            end
        end    
    end
    
    function gameOver()
        -- set gameover for this ipad
        over=true
        lost=col
        vx,vy=0,0
        send("GameOver"..col)   -- send gameover message to other ipad
    end
    
    function checkSr()
        -- check the sent/received table to see if player message was received
        -- if it wasnt, send the player info again
        for a,b in pairs(tabSr) do
            if b.w==0 then
                send(a..","..b.x..","..b.y..","..col)
                cnt=0
                text("checkSr "..a,WIDTH/2,HEIGHT-30)
            end
        end
    end
    
    function touched(t)
        -- check if a button was pressed
        if t.state==BEGAN and not over then
            if t.x>50 and t.x<100 and t.y>h/2 and t.y<h/2+50 then
                vy=0
                vx=-size
            elseif t.x>w-100 and t.x<w-50 and t.y>h/2 and t.y<h/2+50  then
                vy=0
                vx=size
            elseif t.x>w/2 and t.x<w/2+50 and t.y>50 and t.y<100 then
                vx=0
                vy=-size
            elseif t.x>w/2 and t.x<w/2+50 and t.y>h-100 and t.y<h-50 then
                vx=0
                vy=size
            end
        end
    end
    
    function send(msg)  -- send a message to the other ipad
        client:send(msg)
    end
    
    function receive()  -- check if a message was received
        local data=server:receivefrom()
        if data~=nil then
            -- check for gameover message from other ipad
            if string.sub(data,1,8)=="GameOver" then
                for a in string.gmatch(data,"GameOver(%d+)") do
                    lost=tonumber(a)
                end
                over=true
                vx,vy=0,0
                return
            end
            -- if the sent message was received, update the table
            if string.sub(data,1,1)=="R" then
                for a in string.gmatch(data,"R(%d+)") do
                    tabSr[a//1].w=1
                end
                return
            end
            -- get the other ipads player position
            for a,b,c,d in string.gmatch(data,"(%d+),(%d+.%d+),(%d+.%d+),(%d)") do
                table.insert(tab,vec3(b,c,d))
                code=a
            end
            send("R"..code) -- send message received code back to the other ipad
        end
    end
    
  • edited May 9 Posts: 67

    @dave1707 I wrote some code based on yours and @JakAttak s library. It'd be nice if you could test it, since I don't have another iPad. It's basically what your code does, but it automatically takes code from the clipboard and sends it when you press the send message button. And when the other iPad receives the message, it automatically copies that to its clipboard.


    Code removed, it didn't work properly. Original code at this link. https://codea.io/talk/discussion/6344/luasocket-questions/p1
  • dave1707dave1707 Mod
    Posts: 5,744

    @Attila717 It gets my IP address OK, but then it displays the message Waiting for Connection not matter what else I do.

  • Posts: 67

    @dave1707 Huh, well I guess code from 2014 won't always work. I'm not sure what to fix. Maybe it's just the automatic IP finder not working.

  • dave1707dave1707 Mod
    Posts: 5,744

    @Attila717 That's why I didn't add any of that code to my program. It's easier just to use the settings app to get the ip addresses.

  • Posts: 67

    @dave1707 Right. I'll keep looking into finding that address automatically though. I'm thinking maybe a http request to a "find my ip" site would work.

Sign In or Register to comment.