-
-
Save oliver-dew/867369f17d792c2d477c to your computer and use it in GitHub Desktop.
Multiplayer Class (and Drawing Example)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function setup() | |
local connectionMade = function() | |
output.clear() | |
parameter.clear() | |
print("Connected!") | |
gameSetup() | |
end | |
multihandler = Multiplayer(receiveData, connectionMade) | |
parameter.action("Host Game", function() | |
multihandler:hostGame() | |
end) | |
parameter.action("Find Game", function() | |
multihandler:findGame() | |
end) | |
parameter.action("Join Game", function() | |
if other_ip then | |
multihandler:joinGame(other_ip, other_port) | |
else | |
parameter.text("other_ip", "") | |
parameter.text("other_port", "") | |
print("Fill in the host's ip and port, then click join game again") | |
end | |
end) | |
end | |
function gameSetup() | |
canvas = image(WIDTH, HEIGHT) | |
parameter.color("pen_col", color(0, 255, 0)) | |
parameter.integer("pen_size", 2, 100, 10) | |
parameter.action("clear", function() | |
clear() | |
multihandler:sendData("clear") | |
end) | |
pen_touch = nil | |
last_point = vec2(0, 0) | |
end | |
function clear() | |
canvas = image(WIDTH, HEIGHT) | |
end | |
function receiveData(d) | |
if d == "clear" then | |
clear() | |
else | |
local tb = loadstring("return " .. d)() | |
drawPoint(tb.point, tb.last_point, tb.drawing_line, tb.pen_size, tb.pen_col) | |
end | |
end | |
function drawPoint(point, lastPoint, drawingLine, penSize, penCol) | |
pushStyle() | |
setContext(canvas) -- Start drawing to screen image | |
fill(penCol) stroke(penCol) -- Set draw color to color var | |
strokeWidth(penSize) | |
if drawingLine then | |
line(point.x, point.y, lastPoint.x, lastPoint.y) -- draw a line between the two points | |
else | |
ellipse(point.x, point.y, penSize) -- Place a dot there | |
end | |
setContext() | |
popStyle() | |
end | |
function draw() | |
background(255, 255, 255, 255) | |
multihandler:update() | |
if multihandler.connected then | |
sprite(canvas, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT) -- Draw the image onto the screen | |
else | |
fill(0) | |
text("Waiting for connection...", WIDTH / 2, HEIGHT / 2) | |
end | |
end | |
function vec2ToStr(vec) | |
return "vec2" .. tostring(vec) | |
end | |
function colToStr(col) | |
return "color(" .. col.r .. ", " .. col.g .. ", " .. col.b.. ", " .. col.a .. ")" | |
end | |
function touched(t) | |
if multihandler.connected then | |
local p, lp, d, ps, pc = vec2(t.x, t.y), last_point, drawing_line, pen_size, pen_col | |
if t.state == BEGAN then | |
pen_touch = t.id | |
end | |
if t.id == pen_touch then | |
drawPoint(vec2(t.x, t.y), last_point, drawing_line, pen_size, pen_col) | |
drawing_line = true | |
last_point = vec2(t.x, t.y) | |
end | |
if t.state == ENDED then | |
drawing_line = false | |
pen_touch = nil | |
end | |
multihandler:sendData("{ point = " .. vec2ToStr(p) .. ", last_point = " .. vec2ToStr(lp) .. ", drawing_line = " .. tostring(d) .. ", pen_size = " .. ps .. ", pen_col = " .. colToStr(pc) .. " }") | |
end | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local socket = require("socket") | |
Multiplayer = class() | |
function Multiplayer:init(dcb, ccb) | |
self.my_ip, self.my_port = self:getLocalIP(), 5400 | |
self.peer_ip, self.peer_port = nil, self.my_port | |
self.client = socket.udp() | |
self.client:settimeout(0) | |
self.connected = false | |
self.is_host = false | |
self.searching = false | |
self.dataCallback = dcb or function() end | |
self.connectedCallback = ccb or function() end | |
end | |
-- Returns this iPad's local ip | |
function Multiplayer:getLocalIP() | |
local randomIP = "192.167.188.122" | |
local randomPort = "3102" | |
local randomSocket = socket.udp() | |
randomSocket:setpeername(randomIP,randomPort) | |
local localIP, somePort = randomSocket:getsockname() | |
randomSocket:close() | |
randomSocket = nil | |
return localIP | |
end | |
-- Set the connected status and call the connection callback if needed | |
function Multiplayer:setConnectedVal(bool) | |
self.connected = bool | |
if self.connected then | |
self.connectedCallback() | |
end | |
end | |
function Multiplayer:setHostVal(bool) | |
self.is_host = bool | |
end | |
-- Prepare to be the host | |
function Multiplayer:hostGame() | |
print("Connect to " .. self.my_ip .. ":" .. self.my_port) | |
self.client:setsockname(self.my_ip, self.my_port) | |
self:setConnectedVal(false) | |
self.is_host = true | |
self.searching = false | |
end | |
-- Find a host | |
function Multiplayer:findGame() | |
print("Searching for games...") | |
self.searching = true | |
local ip_start, ip_end = self.my_ip:match("(%d+.%d+.%d+.)(%d+)") | |
for i = 1, 255 do | |
if i ~= tonumber(ip_end) then | |
tween.delay(0.01 * i, function() | |
self.client:setsockname(ip_start .. i, self.my_port) | |
self.client:sendto("connection_confirmation", ip_start .. i, self.my_port) | |
end) | |
end | |
end | |
tween.delay(0.01 * 256, function() | |
if not self.connected then | |
alert("Make sure the host has started and is on the same network.", "No matches found.") | |
end | |
end) | |
end | |
-- Prepare to join a host | |
function Multiplayer:joinGame(ip, port) | |
self.peer_ip, self.peer_port = ip, port | |
self.client:setsockname(ip, port) | |
self.is_host = false | |
self.searching = false | |
self:sendData("connection_confirmation") | |
end | |
-- Send data to the other client | |
function Multiplayer:sendData(msg_to_send) | |
if self.peer_ip then | |
self.client:sendto(msg_to_send, self.peer_ip, self.peer_port) | |
end | |
end | |
-- Check for data received from the other client | |
function Multiplayer:checkForReceivedData() | |
local data, msg_or_ip, port_or_nil = self.client:receivefrom() | |
if data then | |
-- Store the ip of this new client so you can send data back | |
self.peer_ip, self.peer_port = msg_or_ip, port_or_nil | |
if not self.connected and data == "connection_confirmation" then | |
self:sendData("connection_confirmation") | |
self:setConnectedVal(true) | |
end | |
-- Call callback with received data | |
if data ~= "connection_confirmation" then | |
self.dataCallback(data) | |
end | |
end | |
end | |
function Multiplayer:update() | |
self:checkForReceivedData() | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment