Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Gamestate game
- function game:init() -- run once
- playerTypes = {
- runner = {},
- hunter = {}
- }
- end
- function game:enter(previous, playerTable, ownID) -- speak: load
- participants = {}
- playerID = ownID
- function collide(dt, shape_one, shape_two, mtv_x, mtv_y) -- to-do: player collsion via network => update network player nicht lokal!
- --print('colliding:', shape_one, shape_two)
- if shape_one.data ~= nil then -- resolve player collision
- shape_one:move(mtv_x, mtv_y)
- shape_one.data.x = shape_one.data.x + mtv_x
- shape_one.data.y = shape_one.data.y + mtv_y
- end
- if shape_two.data ~= nil then -- resolve player player collision
- shape_two:move(-mtv_x, -mtv_y)
- shape_two.data.x = shape_two.data.x - mtv_x
- shape_two.data.y = shape_two.data.y - mtv_y
- if shape_one.data.t == playerTypes.runner and shape_two.data.t == playerTypes.hunter
- or shape_one.data.t == playerTypes.hunter and shape_two.data.t == playerTypes.runner then
- print("Hunter wins!")
- end
- end
- end
- function addRunner(id, x, y)
- local runner = HC:addRectangle(x, y, playerDefault.collisionWidth, playerDefault.collisionHeight)
- HC.addToGroup("player", runner)
- if id == ownID then
- print(id .. " That's me!")
- runner.data = Player:New(id, playerTypes.runner, x, y)
- player = runner
- else
- runner.data = Participant:New(id, playerTypes.runner, x, y)
- participants[id] = runner
- end
- end
- function addHunter(id, x, y)
- local hunter = HC:addRectangle(x, y, playerDefault.collisionWidth, playerDefault.collisionHeight)
- HC.addToGroup("player", hunter)
- if id == ownID then
- print(id .. " That's me!")
- hunter.data = Player:New(id, playerTypes.hunter, x, y)
- player = hunter
- else
- hunter.data = Participant:New(id, playerTypes.hunter, x, y)
- participants[id] = hunter
- end
- end
- function updatePlayer(dt)
- local dx, dy = player.data.x, player.data.y
- player.data:Update(dt, player.data.headingTowards.x, player.data.headingTowards.y)
- dx, dy = player.data.x - dx, player.data.y - dy
- player:move(dx, dy)
- end
- function updateParticipant(id, playerUpdate, dt)
- local participant = participants[id]
- local dx, dy = playerUpdate.x - participant.data.x, playerUpdate.y - participant.data.y
- participant.data:Update(dt, playerUpdate)
- participant:move(dx, dy)
- end
- HC = Collider.new(100)
- love.graphics.setBackgroundColor(255, 255, 255)
- for i = 0,#playerTable do
- if playerTable[i].playerType == playerTypes.runner then
- print(playerTable[i].id .. ': Runner')
- addRunner(playerTable[i].id, playerTable[i].x, playerTable[i].y)
- else
- print(playerTable[i].id .. ': Hunter')
- addHunter(playerTable[i].id, playerTable[i].x, playerTable[i].y)
- end
- end
- -- set callbacks
- HC:setCallbacks(collide, stop)
- cam = Camera(player.data.x, player.data.y, 1, 0)
- -- light cone
- lightRadius = 350 --love.graphics.getWidth()/2
- surroundingLightRadius = 50
- lightCone = love.image.newImageData(2*lightRadius, 2*lightRadius)
- lightCone:mapPixel(function(x, y)
- xn = (x - lightRadius) / lightRadius
- yn = (y - lightRadius) / lightRadius
- local d = math.sqrt(xn*xn + yn*yn)
- if(d <= 1.5) then --(math.pow(d,5) < 1.5) then
- local m = vector_hv(lightRadius, lightRadius)
- local o = vector_hv(0, -lightRadius)
- local p = vector_hv(x,y)
- p = p - m
- if(math.deg(math.acos(o * p / (o:len() * p:len()))) > 45) then
- if(d < surroundingLightRadius/lightRadius) then --lichtkegel
- return 255, 255, 255, math.min(1, math.pow(d + 1 - surroundingLightRadius/lightRadius, 80)) * 255
- else -- im kreis, außerhalb sichtkegel
- return 0, 0, 0, 255
- end
- else -- lichtkreis direkt am spieler
- return 255, 255, 255, math.min(1, math.pow(d, 7)) * 255 -- math.pow(d, ...) bestimmt den Kegel / den Übergang
- end
- else -- ecken
- return 255, 255, 255, 0
- end
- end)
- lightCone = love.graphics.newImage(lightCone)
- -- corners for making a dark mask around the light radius
- lightRadiusCorners = love.image.newImageData(2*lightRadius, 2*lightRadius)
- lightRadiusCorners:mapPixel(function(x, y)
- x = (x - lightRadius) / lightRadius
- y = (y - lightRadius) / lightRadius
- local d = math.sqrt(x*x + y*y)
- if (d < 1 - 1/lightRadius) then
- return 255, 255, 255, 0
- else
- return 255, 255, 255, 255
- end
- end)
- lightRadiusCorners = love.graphics.newImage(lightRadiusCorners)
- require 'maps.map01' -- noch umschreiben zu abfrage aus network info
- background = love.graphics.newImage("maps/map01.png") -- dito
- shadowCasters = {}
- for _,obj in pairs(obstacles) do
- HC.addToGroup("obstacle", obj)
- shadowCasters[#shadowCasters+1] = obj._polygon
- end
- t = 0 -- zwecks network-updates
- end
- function game:update(dt)
- --print(love.timer.getFPS() .. " fps")
- t = t + dt
- time.sinceStart = time.sinceStart + dt
- time.s = math.floor(time.sinceStart) % 60
- time.m = math.floor(time.sinceStart / 60) % 60
- time.h = math.floor(time.sinceStart / 60 / 60) % 60
- player.data.headingTowards.x, player.data.headingTowards.y = 0, 0
- if love.keyboard.isDown("w") then player.data.headingTowards.y = -1 end
- if love.keyboard.isDown("s") then player.data.headingTowards.y = 1 end
- if love.keyboard.isDown("a") then player.data.headingTowards.x = -1 end
- if love.keyboard.isDown("d") then player.data.headingTowards.x = 1 end
- player.data.isClickingRun = love.keyboard.isDown(" ")
- updatePlayer(dt)
- player.data.directionSight = math.atan2(love.mouse.getX() - love.graphics.getWidth()/2, love.graphics.getHeight()/2 - love.mouse.getY())
- player.data.directionHead = player.data.directionSight
- local angleSightToBody = math.deg(player.data.directionSight - player.data.directionBody)
- if (angleSightToBody < -90 and angleSightToBody > -180) or angleSightToBody >= 180 then
- player.data.directionHead = player.data.directionBody - math.pi/2
- elseif angleSightToBody > 90 or (angleSightToBody < -180 and angleSightToBody >= -270) then
- player.data.directionHead = player.data.directionBody + math.pi/2
- end
- -- verschicken der Updates an alle
- local updateSelf = {
- id = playerID,
- dt = dt,
- x = player.data.x,
- y = player.data.y,
- directionBody = player.data.directionBody,
- directionHead = player.data.directionHead,
- directionSight = player.data.directionSight,
- speed = player.data.speed
- }
- if t > updateRate then
- --t = 0
- for i = 0,#playerTable do
- if playerTable[i].id ~= playerID then
- udp:setpeername(playerTable[i].ip, playerTable[i].port)
- udp:send(json.encode(updateSelf))
- end
- end
- end
- repeat
- data, msg = udp:receive()
- if data then
- local update = json.decode(data)
- updateParticipant(update.id, update, dt)
- end
- -- elseif msg ~= 'timeout' then
- -- error("Network error: "..tostring(msg))
- -- end
- until not data
- HC:update(dt)
- cam.x = player.data.x + player.data.offsetBody.x -- eigentlich cam:move(),
- cam.y = player.data.y + player.data.offsetBody.y -- aber da das einen Vektor braucht und wir nur Koordinaten haben ...
- end
- function game.draw()
- cam:attach()
- love.graphics.setColor(255,255,255,255)
- love.graphics.draw(background)
- local ppos = vector(player:center())
- player.data:Draw()
- for i = 0,#participants do
- if participants[i] ~= nil then
- participants[i].data:Draw()
- end
- end
- love.graphics.setColor(0, 0, 0, 225)
- love.graphics.draw(lightCone, ppos.x, ppos.y, player.data.directionSight, 1, 1, lightRadius, lightRadius)
- love.graphics.setColor(0, 0, 0, 255)
- love.graphics.draw(lightRadiusCorners, ppos.x, ppos.y, 0, 1, 1, lightRadius, lightRadius)
- -- ___________
- --|1 | 2|
- --| |_______|
- --| | p | |
- --|___|___| |
- --|4 | 3|
- --|_______|___|
- --
- local innerLeft, innerRight = ppos.x - lightRadius, ppos.x + lightRadius
- local innerTop, innerBottom = ppos.y - lightRadius, ppos.y + lightRadius
- local outerLeft, outerRight = player.data.x - love.graphics.getWidth()/2, player.data.x + love.graphics.getWidth()/2
- local outerTop, outerBottom = player.data.y - love.graphics.getHeight()/2, player.data.y + love.graphics.getHeight()/2
- local widthWithOffset, heightWithOffset = love.graphics.getWidth()/2 + player.data.offsetBody.x, love.graphics.getHeight()/2 + player.data.offsetBody.y
- love.graphics.rectangle('fill', outerLeft, outerTop, widthWithOffset - lightRadius, heightWithOffset + lightRadius) -- 1
- love.graphics.rectangle('fill', innerLeft, outerTop, widthWithOffset + lightRadius, heightWithOffset - lightRadius) -- 2
- love.graphics.rectangle('fill', innerRight, innerTop, widthWithOffset - lightRadius, heightWithOffset + lightRadius) -- 3
- love.graphics.rectangle('fill', outerLeft, innerBottom, widthWithOffset + lightRadius, heightWithOffset - lightRadius) -- 4
- -- cast shadows
- love.graphics.setColor(0,0,0,255)
- for _,poly in ipairs(shadowCasters) do
- if ppos:dist(poly.centroid) < 5 * lightRadius then
- local startv, endv = poly.vertices[1], poly.vertices[1]
- local vertices = {}
- for i,v in ipairs(poly.vertices) do
- local w = vector(poly.vertices[(i % #poly.vertices) + 1].x,poly.vertices[(i % #poly.vertices) + 1].y)
- local c = .5 * (w + v)
- local n = (w - v):perpendicular()
- local is_hidden = n * (c - ppos) < 0
- if is_hidden then
- vertices[1] = v.x
- vertices[2] = v.y
- vertices[3] = w.x
- vertices[4] = w.y
- v = v + (v - ppos) * 800
- w = w + (w - ppos) * 800
- vertices[5] = w.x
- vertices[6] = w.y
- vertices[7] = v.x
- vertices[8] = v.y
- love.graphics.polygon('fill', unpack(vertices))
- end
- end
- end
- end
- drawHud()
- cam:detach()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement