Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --# Combat
- Combat = class()
- function Combat:init(p1, p2, dist)
- self.p1 = p1
- self.p2 = p2
- self.p1.fighting = true
- self.p2.fighting = true
- self.inCombat = true
- self.timer = 0
- self.dist = dist
- self.closedUp = false
- end
- function Combat:doCombat()
- local sin = math.sin
- local cos = math.cos
- local atan2 = math.atan2
- local p1m = self.p1.model
- local p2m = self.p2.model
- self.p1.direction = atan2(p2m.y - p1m.y, p2m.x - p1m.x)
- self.p2.direction = atan2(p1m.y - p2m.y, p1m.x - p2m.x)
- if not self.closedUp or self.dist > 35 then
- local x = p1m.x - p2m.x
- local y = p1m.y - p2m.y
- local dist = math.sqrt(x*x + y*y)
- if self.dist ~= dist then
- self.closedUp = true
- end
- self.dist = dist
- p1m.x = p1m.x + cos(self.p1.direction)*30*DeltaTime
- p1m.y = p1m.y + sin(self.p1.direction)*30*DeltaTime
- p2m.x = p2m.x + cos(self.p2.direction)*30*DeltaTime
- p2m.y = p2m.y + sin(self.p2.direction)*30*DeltaTime
- return
- end
- if not self.closedUp or self.dist < 34 then
- local x = p1m.x - p2m.x
- local y = p1m.y - p2m.y
- local dist = math.sqrt(x*x + y*y)
- if self.dist ~= dist then
- self.closedUp = true
- end
- self.dist = dist
- p1m.x = p1m.x - cos(self.p1.direction)*30*DeltaTime
- p1m.y = p1m.y - sin(self.p1.direction)*30*DeltaTime
- p2m.x = p2m.x - cos(self.p2.direction)*30*DeltaTime
- p2m.y = p2m.y - sin(self.p2.direction)*30*DeltaTime
- return
- end
- self.p1.direction = self.p1.direction + sin(-self.timer*8)
- self.p2.direction = self.p2.direction + sin(-self.timer*8)
- self.timer = self.timer + DeltaTime
- if self.timer > .8 then
- self.timer = 0
- if self.p1.despawning or self.p2.despawning then
- self.p1.despawning = true
- self.p2.despawning = true
- self.inCombat = false
- self.p1.fighting = false
- self.p2.fighting = false
- return
- end
- self.p1:modLife(-self.p2.power)
- self.p2:modLife(-self.p1.power)
- if self.p1.life <= 0 then
- self.p1.dying = true
- self.inCombat = false
- if self.p2.life > 0 then
- self.p2.fighting = false
- self.p2.despawning = true
- end
- end
- if self.p2.life <= 0 then
- self.p2.dying = true
- self.inCombat = false
- if self.p1.life > 0 then
- self.p1.fighting = false
- self.p1.despawning = true
- end
- end
- end
- end
- --# GUI
- GUI = class()
- function GUI:init(player)
- self.stick = Stick()
- self.button = {}
- self.id = player
- end
- function GUI:draw()
- local stick = self.stick
- if stick.active then
- stick:draw()
- end
- for _, button in ipairs(self.button) do
- button:draw()
- end
- end
- function GUI:touched(touch, side)
- if side then
- self.stick:touched(touch)
- else
- for _, button in ipairs(self.button) do
- local type = button:touched(touch)
- if type == "summon" then
- if touch.state == BEGAN then
- self.id:summon(graphics.toon)
- end
- end
- if type == "attack" then
- if touch.state == BEGAN and not self.id.shielding then
- self.id.attacking = true
- end
- end
- if type == "fire" then
- if touch.state == BEGAN and not self.id.fire and self.id.mana > 1 then
- self.id.fire = true
- self.id:getNearestEnemy()
- self.id:modMana(-1)
- end
- end
- if type == "unsummon" then
- if touch.state == BEGAN and not self.id.unsummon and self.id.mana > 2 then
- self.id.unsummon = true
- self.id:getNearestEnemy()
- self.id:modMana(-2)
- end
- end
- if type == "buff" then
- if touch.state == BEGAN and not self.id.buff and self.id.mana > 2 then
- self.id.buff = true
- self.id:getNearestFriend()
- self.id:modMana(-2)
- end
- end
- if type == "shield" then
- if touch.state == ENDED and not self.id.attacking then
- self.id.shielding = false
- self.id.timer = 0
- else
- if self.id.mana >= 1 and not self.id.attacking then
- self.id.shielding = true
- end
- end
- end
- end
- end
- end
- --# Main
- -- PvP latest
- function setup()
- displayMode(FULLSCREEN)
- spriteMode(CENTER)
- bnw = false
- Camera = vec3(1,1,1)
- Light = vec3(1,1,1)
- font("Futura-CondensedExtraBold")
- -- noSmooth()
- parameter.integer("mode", 1, 2, 1)
- parameter.integer("zzz", -20, 20, 0)
- parameter.integer("lx", -100, 100, 1)
- parameter.integer("ly", -100, 100, 1)
- parameter.integer("lz", -100, 100, 100)
- -- parameter.integer("zoomX", 1, 1000, 200)
- -- parameter.integer("zoomY", -1000, -1, -175)
- -- sprite setup
- graphics = Graphics()
- -- player setup
- player1 = Player(graphics.toon, -110, 0)
- player2 = Player(graphics.toon, 150, 0)
- player1.target = player2
- local ins = table.insert
- ins(player1.gui.button, Buttons("attack", WIDTH - 100,200))
- ins(player1.gui.button, Buttons("shield", WIDTH - 200,100))
- ins(player1.gui.button, Buttons("summon", WIDTH - 32,300))
- ins(player1.gui.button, Buttons("fire", WIDTH - 96,300))
- ins(player1.gui.button, Buttons("unsummon", WIDTH - 32,364))
- ins(player1.gui.button, Buttons("buff", WIDTH - 96,364))
- player2.target = player1
- ins(player2.gui.button, Buttons("attack", 100, HEIGHT - 200))
- ins(player2.gui.button, Buttons("shield", 200, HEIGHT - 100))
- ins(player2.gui.button, Buttons("summon", 32, HEIGHT - 300))
- ins(player2.gui.button, Buttons("unsummon", 32, HEIGHT - 364))
- ins(player2.gui.button, Buttons("buff", 96, HEIGHT - 364))
- ins(player2.gui.button, Buttons("fire", 96, HEIGHT - 300))
- player2.gui.stick.direction = -3.14
- graphics.players = {player1, player2}
- tick = 0
- timer = 0
- fps = 0
- x = 0
- y = 0
- smoothing = 0
- -- im = image(WIDTH,HEIGHT)
- end
- function draw()
- if bnw then
- background(200, 200, 200, 255)
- else
- background(102, 150, 80, 255)
- end
- setCamera()
- -- scene
- graphics:drawWorld()
- -- draw players ane minions
- player1:draw()
- translate(0,0,.2)
- player2:draw()
- if bnw then
- tint(200, 200, 200, 255)
- else
- tint(102, 150, 80, 255)
- end
- -- sprite(graphics.BG, xxx, yyy, zzz, zzz)
- translate(0,0,-4)
- sprite(graphics.BG, 0, 0, 880, 880)
- noTint()
- -- draw shadows, spawn points, text, etc...
- graphics:draw()
- -- move seemless sky texture and draw it
- --[[
- x = x + (1/2048)
- y = y + (1/2048)
- translate(0,0,200)
- graphics.sky:setRectTex(graphics.skyId, x, y, 1, 1)
- graphics.sky:draw()
- translate(0,0,-200)
- ]]--
- ortho()
- viewMatrix(matrix())
- sprite(graphics.mask, WIDTH/2, HEIGHT/2, WIDTH+300, HEIGHT+300)
- -- draw pads and buttons
- player1.gui:draw()
- player2.gui:draw()
- if timer > .4 then
- timer = 0
- tick = tick + .2
- fps = math.floor(1/DeltaTime*10)/10
- player1:modMana(.1)
- player2:modMana(.1)
- end
- local n = 2
- for i=1, 5 do
- if player1.summons[i] then
- n = n + 1
- end
- if player2.summons[i] then
- n = n + 1
- end
- end
- text(n.." objects, "..(n*graphics.toon.size/3).." polygons", 150, HEIGHT - 20)
- text("FPS: "..fps, WIDTH - 50, HEIGHT - 20)
- timer = timer + DeltaTime
- end
- function touched(touch)
- if touch.y < HEIGHT/2 then
- player1.gui:touched(touch, touch.x < WIDTH/2)
- else
- player2.gui:touched(touch, touch.x > WIDTH/2)
- end
- end
- function setCamera()
- -- set camera to point between both players
- -- and zoom out so both are always on screen
- local p1 = player1.model
- local p2 = player2.model
- local x, y, dist, tmp
- x = (p1.x - p2.x)
- y = (p1.y - p2.y)
- dist = math.sqrt(x*x+y*y)
- x = (p1.x + p2.x)/2
- y = (p1.y + p2.y)/2
- perspective(60, WIDTH/HEIGHT)
- if mode == 1 then
- Light = vec3(lx, ly, lz):normalize()
- Camera = vec3(x,-175+y,200+dist):normalize()
- camera(x,-175+y,200+dist, x,y,0, 0,1,0)
- else
- Camera = vec3(x,-1+y,200+dist):normalize()
- Light = vec3(lx, ly, lz):normalize()
- camera(x,-1+y,200+dist, x,y,0, 0,1,0)
- end
- end
- --# Player
- Player = class()
- function Player:init(mdl, x, y)
- self.summons = {nil, nil, nil, nil, nil}
- self.direction = 0
- -- numerical life and power
- self.life = 10
- self.mana = 10
- self.maxMana = 10
- self.speed = 1
- -- graphical format of life and power
- self:modLife(0)
- self:modMana(0)
- -- enemy player
- self.target = nil
- self.nearestEnemy = nil
- self.nearestFriend = nil
- -- player 3d model, position and scale
- self.model = Cube(mdl, x, y, 12)
- -- player touchpad and buttons
- self.gui = GUI(self)
- self.casting = false
- self.shielding = false
- self.buff = false
- self.fire = false
- self.unsummon = false
- self.attacking = false
- self.hasHit = false
- self.timer = 0
- end
- function Player:modLife(val)
- self.life = self.life + val
- if self.life > 10 then
- self.life = 10
- end
- self.lifeText = self:setStat(self.life)
- end
- function Player:modMana(val)
- self.mana = self.mana + val
- if self.mana >= self.maxMana then
- self.mana = self.maxMana
- end
- if self.mana <= 0 then
- self.mana = 0
- end
- self.manaText = self:setStat(self.mana)
- end
- -- convert numeral stats to graphics so it can be displayed
- function Player:setStat(val)
- local txt = ""
- for i=1, val do
- txt = txt.."|"
- end
- return txt
- end
- function Player:draw()
- local pos = self.model
- local target = self.target.model
- local stick = self.gui.stick
- -- draw all minions
- for i=1, 5 do
- local minion = self.summons[i]
- if minion then
- if minion.dead then
- self.summons[i] = nil
- else
- translate(0,0,.2)
- minion:draw()
- end
- end
- end
- self.direction = stick.direction
- -- do attack
- if self.attacking then
- self.direction = self.direction + math.sin(-self.timer*math.pi*2)
- self.timer = self.timer + DeltaTime
- if self.timer > 1 then
- self.attacking = false
- self.hasHit = false
- self.timer = 0
- end
- end
- -- do shield
- if self.shielding then
- self.timer = self.timer + DeltaTime
- self:modMana(-DeltaTime*1.5)
- if self.mana == 0 then
- self.shielding = false
- self.timer = 0
- end
- end
- -- do fire
- if self.fire then
- self.timer = self.timer + DeltaTime
- if self.timer > 1 then
- self.fire = false
- if not self.nearestEnemy.shielding then
- self.nearestEnemy:modLife(-1)
- end
- self.timer = 0
- end
- end
- -- do unsummon
- if self.unsummon then
- self.nearestEnemy.despawning = true
- self.unsummon = false
- end
- -- do buff
- if self.buff then
- self.timer = self.timer + DeltaTime
- if self.timer > 1 then
- self.buff = false
- if self.nearestFriend then
- self.nearestFriend:modLife(1)
- self.nearestFriend:modPower(1)
- else
- self:modMana(2)
- end
- self.timer = 0
- end
- end
- -- check if player can move, and move if possible
- if stick.active and not self:checkCollision() then
- pos.x = pos.x + math.cos(self.direction)*self.speed*60*DeltaTime
- pos.y = pos.y + math.sin(self.direction)*self.speed*60*DeltaTime
- end
- -- face other player
- -- local direction = math.atan2(target.y - pos.y, target.x - pos.x)
- -- draw player based on stick direction
- self.model:draw(self.direction, stick.active)
- end
- function Player:summon(mdl)
- -- add minion in front of player
- if self.mana >= 1 then
- local deltaX = self.model.x+50*math.cos(self.direction)
- local deltaY = self.model.y+50*math.sin(self.direction)
- for i=1, 5 do
- if self.summons[i] == nil then
- self.summons[i] = Summon(mdl, deltaX, deltaY, self.target, i)
- self:modMana(-1)
- return
- end
- end
- end
- end
- function Player:getNearestEnemy()
- local x = self.model.x - self.target.model.x
- local y = self.model.y - self.target.model.y
- local closest = -1
- local sqrt = math.sqrt
- local pos = self.model
- local dist = 0
- local targ = nil
- -- test collision on enemy minions
- for i=1, 5 do
- local minion = self.target.summons[i]
- if minion then
- if not (minion.despawning or minion.spawning or minion.dying) then
- x = pos.x - minion.model.x
- y = pos.x - minion.model.y
- dist = sqrt(x*x + y*y)
- if dist < closest or closest == -1 then
- targ = minion
- closest = dist
- end
- end
- end
- end
- if closest == -1 then
- targ = self.target
- end
- self.nearestEnemy = targ
- end
- function Player:getNearestFriend()
- local closest = -1
- local sqrt = math.sqrt
- local pos = self.model
- local dist = 0
- local targ = nil
- -- test collision on friendly minions
- for i=1, 5 do
- local minion = self.summons[i]
- if minion then
- if not (minion.despawning or minion.spawning or minion.dying) then
- x = pos.x - minion.model.x
- y = pos.x - minion.model.y
- dist = sqrt(x*x + y*y)
- if dist < closest or closest == -1 then
- targ = minion
- closest = dist
- end
- end
- end
- end
- if closest == -1 then
- targ = nil
- end
- self.nearestFriend = targ
- end
- function Player:checkCollision()
- local x, y
- local sqrt = math.sqrt
- -- set collision point in front of player
- local deltaX = self.model.x + 15*math.cos(self.direction)
- local deltaY = self.model.y + 15*math.sin(self.direction)
- -- test collision on opposing player
- x = deltaX - self.target.model.x
- y = deltaY - self.target.model.y
- if sqrt(x*x + y*y) < 15 then
- return true
- end
- -- test collision on enemy minions
- for i=1, 5 do
- local minion = self.target.summons[i]
- if minion then
- if not (minion.despawning or minion.spawning or minion.fighting) then
- x = deltaX - minion.model.x
- y = deltaY - minion.model.y
- if sqrt(x*x + y*y) < 15 then
- return true
- end
- end
- end
- end
- return false
- end
- --# Summon
- Summon = class()
- function Summon:init(mdl, x, y, target, id)
- self.id = id
- -- numerical life and power
- self.life = 1+math.floor(math.random(3))
- self.power = 1
- -- update format of life and power
- self:modLife(0)
- self:modPower(0)
- self.spawnTime = 1
- self.combat = nil
- -- model, position, scale, direction, spawn point and speed of minion
- self.model = Cube(mdl, x, y, 12)
- self.direction = math.atan2(target.model.y - self.model.y, target.model.x - self.model.x)
- self.spawn = vec2(x, y)
- self.speed = 1 + math.random()
- -- current player target
- self.target = target
- self.dead = false
- self.spawning = true
- self.dying = false
- self.despawning = false
- self.fighting = false
- self.attackingPlayer = false
- self.timer = 0
- end
- function Summon:modLife(val)
- self.life = self.life + val
- self.lifeText = self:setStat(self.life)
- end
- function Summon:modPower(val)
- self.power = self.power + val
- self.powerText = self:setStat(self.power)
- end
- -- convert numeral stats to graphics so it can be displayed
- function Summon:setStat(val)
- local txt = ""
- for i=1, val do
- txt = txt.."|"
- end
- return txt
- end
- function Summon:draw()
- if self.life <= 0 then
- self.dying = true
- end
- local pos = self.model
- local target = self.target.model
- -- draw minion in correct direction
- if self.dying then
- pushMatrix()
- translate(0, 0, -self.timer*50)
- pos:draw(self.direction, false)
- popMatrix()
- elseif self.spawning then
- if self.timer>self.spawnTime/2 then
- pos:draw(self.direction, false)
- end
- elseif self.despawning then
- if self.timer<.5 then
- pos:draw(self.direction, false)
- end
- else
- pos:draw(self.direction, not (self.fighting or self.attackingPlayer))
- end
- -- check if engaged in combat
- if self.combat then
- self.combat:doCombat()
- if not self.combat.inCombat then
- self.combat = nil
- end
- return
- end
- -- stop movement until poping is done
- if self.spawning then
- self.direction = self.timer*(4*math.pi/self.spawnTime)
- self.timer = self.timer + DeltaTime
- if self.timer > self.spawnTime then
- self.spawning = false
- self.timer = 0
- end
- return
- end
- -- stop movement until poping is done
- if self.despawning then
- self.direction = self.timer*(4*math.pi/self.spawnTime)
- self.timer = self.timer + DeltaTime
- if self.timer > 1 then
- self.despawning = false
- self.spawning = true
- self.timer = 0
- pos.x = self.spawn.x
- pos.y = self.spawn.y
- end
- return
- end
- -- stop movement then die
- if self.dying then
- self.timer = self.timer + DeltaTime
- if self.timer > 1 then
- self.dying = false
- self.timer = 0
- self.dead = true
- end
- return
- end
- -- stop movement until attack to player is done, then respawn
- if self.attackingPlayer then
- if self.target.attacking and not self.target.hasHit then
- self:modLife(-1)
- self.target.hasHit = true
- end
- self.direction = math.atan2(target.y - pos.y, target.x - pos.x) + math.sin(self.timer*math.pi*2)
- self.timer = self.timer + DeltaTime
- if self.timer > .7 then
- if self.target.shielding then
- self.target:modLife(-math.floor(self.power/2))
- else
- self.target:modLife(-self.power)
- end
- self.attackingPlayer = false
- self.despawning = true
- self.timer = 0
- end
- return
- end
- if not self.fighting then
- -- check distance to target
- local x = pos.x - target.x
- local y = pos.y - target.y
- local dist = math.sqrt(x*x + y*y)
- -- attack player when in range
- if not self.attackingPlayer and dist < 50 then
- self.attackingPlayer = true
- self.timer = 0
- return
- end
- -- face target at all times
- self.direction = math.atan2(target.y - pos.y, target.x - pos.x)
- if not self:checkCollision() then
- pos.x = pos.x + math.cos(self.direction)*self.speed*60*DeltaTime
- pos.y = pos.y + math.sin(self.direction)*self.speed*60*DeltaTime
- end
- end
- end
- function Summon:checkCollision()
- local x, y, deltaX, deltaY, friend, enemy
- local sqrt = math.sqrt
- local dist
- for i=1, 5 do
- -- check collision vs enemy minions and start fighting
- enemy = self.target.summons[i]
- if enemy and not (enemy.attackingPlayer or enemy.despawning or enemy.spawning or enemy.fighting) then
- x = self.model.x - enemy.model.x
- y = self.model.y - enemy.model.y
- dist = sqrt(x*x + y*y)
- if dist < 45 then
- self.combat = Combat(self, enemy, dist)
- return true
- end
- end
- -- check collision vs friendly minions
- friend = self.target.target.summons[i]
- if friend and (friend.id ~= self.id) and not (friend.despawning or friend.spawning or friend.fighting) then
- -- set collision point in front of minion
- deltaX = self.model.x + 16*math.cos(self.direction)
- deltaY = self.model.y + 16*math.sin(self.direction)
- x = deltaX - friend.model.x
- y = deltaY - friend.model.y
- if sqrt(x*x + y*y) < 15 then
- return true
- end
- end
- end
- return false
- end
- --# Cube
- Cube = class()
- function Cube:init(mdl, x, y, s)
- self.x = x
- self.y = y
- self.size = s
- -- 3D model to be used
- self.mdl = mdl
- end
- function Cube:draw(dir, moving)
- local direction = dir or 0
- direction = direction/math.pi*180
- pushMatrix()
- -- position 3D model
- translate(self.x,self.y, self.size/2+20)
- -- animate 3D model
- if moving then
- rotate(math.sin(ElapsedTime*20)*5, 1, 1, 1)
- else
- rotate(math.sin(ElapsedTime*5)*1, 1, 1, 1)
- end
- -- set 3D model orientation
- rotate(direction, 0, 0, 1)
- scale(self.size,self.size,self.size)
- if self.mdl.shader then
- self.mdl.shader.camera = Camera
- self.mdl.shader.light = Light
- end
- self.mdl:draw()
- popMatrix()
- end
- --# Stick
- Stick = class()
- function Stick:init()
- self.direction = 0
- self.dist = 0
- self.active = false
- self.origin = vec2(150, 150)
- self.center = self.origin
- self.pos = self.origin
- stroke(127, 127, 127, 127)
- strokeWidth(10)
- noFill()
- self.stick_bg = image(128, 128)
- setContext(self.stick_bg)
- ellipse(64, 64, 128)
- noStroke()
- fill(192, 192, 192, 127)
- self.stick = image(96, 96)
- setContext(self.stick)
- ellipse(48, 48, 96)
- end
- function Stick:draw()
- sprite(self.stick_bg, self.center.x, self.center.y)
- sprite(self.stick, self.pos.x, self.pos.y)
- end
- function Stick:touched(touch)
- if touch.state == BEGAN then
- self.center = vec2(touch.x, touch.y)
- self.active = true
- end
- self.pos = vec2(touch.x, touch.y)
- self.direction = math.atan2(self.pos.y - self.center.y, self.pos.x - self.center.x)
- self.dist = math.min(2, self.pos:dist(self.center)/32)
- if touch.state == ENDED then
- self.center = self.origin
- self.pos = self.center
- self.active = false
- end
- end
- --# Buttons
- Buttons = class()
- function Buttons:init(type, x, y)
- self.type = type
- self.x = x
- self.y = y
- end
- function Buttons:draw()
- if self.type == "summon" then
- sprite(graphics.buttonSummon, self.x, self.y)
- elseif self.type == "attack" then
- sprite(graphics.buttonAttack, self.x, self.y)
- elseif self.type == "shield" then
- sprite(graphics.buttonShield, self.x, self.y)
- elseif self.type == "fire" then
- sprite(graphics.buttonFire, self.x, self.y)
- elseif self.type == "buff" then
- sprite(graphics.buttonBuff, self.x, self.y)
- elseif self.type == "unsummon" then
- sprite(graphics.buttonUnsummon, self.x, self.y)
- end
- end
- function Buttons:touched(touch)
- if touch.x > self.x - 48 and touch.x < self.x + 48 then
- if touch.y > self.y - 48 and touch.y < self.y + 48 then
- return self.type
- end
- end
- return false
- end
- --# ModelLoader
- --Model = class()
- function Model(mdl, texture)
- local img = readImage(mdl)
- local width, height = spriteSize(mdl)
- local verts = {}
- local normals = {}
- local colors = {}
- local coords = {}
- local a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, x, y, z, X, Y, n, size
- local strToChar = string.char
- local ins = table.insert
- cnt = 0
- X = 1
- Y = height
- n = 1
- a1, b1, c1 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- d1 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- size = bytesToFloat(strToChar(a1, b1, c1, d1))
- cnt = 0
- -- vertices
- while n<=size do
- a1, b1, c1 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- d1, a2, b2 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- c2, d2, a3 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- b3, c3, d3 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- x = bytesToFloat(strToChar(a1, b1, c1, d1))
- y = bytesToFloat(strToChar(a2, b2, c2, d2))
- z = bytesToFloat(strToChar(a3, b3, c3, d3))
- ins(verts, vec3(x, y, z))
- n = n + 1
- end
- print(cnt.." for "..size.." vertices")
- cnt = 0
- -- normals
- n = 1
- while n<=size do
- a1, b1, c1 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- d1, a2, b2 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- c2, d2, a3 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- b3, c3, d3 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- x = bytesToFloat(strToChar(a1, b1, c1, d1))
- y = bytesToFloat(strToChar(a2, b2, c2, d2))
- z = bytesToFloat(strToChar(a3, b3, c3, d3))
- ins(normals, vec3(x, y, z))
- n = n + 1
- end
- print(cnt.." for "..size.." normals")
- cnt = 0
- -- colors
- n = 1
- while n<=size do
- a1, b1, c1 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- d1, a2, b2 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- c2, d2, a3 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- b3, c3, d3 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- x = bytesToFloat(strToChar(a1, b1, c1, d1))*255
- y = bytesToFloat(strToChar(a2, b2, c2, d2))*255
- z = bytesToFloat(strToChar(a3, b3, c3, d3))*255
- ins(colors, color(x, y, z, 255))
- n = n + 1
- end
- print(cnt.." for "..size.." colors")
- cnt = 0
- -- texture coordinates
- if texture then
- n = 1
- while n<=size do
- a1, b1, c1 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- d1, a2, b2 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- c2, d2, a3 = img:get(X,Y)
- X, Y = nextPixel(X, Y, width)
- x = bytesToFloat(strToChar(a1, b1, c1, d1))
- y = bytesToFloat(strToChar(a2, b2, c2, d2))
- ins(coords, vec2(x,y))
- n = n + 1
- end
- end
- local total = 3*(size*4)+(size*3)+2
- print(cnt.." for "..size.." texture coords")
- print("total:"..total.." pixels, for a model of "..(size/3).." polygons")
- local min = math.ceil(math.sqrt(total))
- print("min img size:"..min.."x"..min)
- cnt = 0
- local data = mesh()
- data.vertices = verts
- data.colors = colors
- data.normals = normals
- if texture then
- data.texture = texture
- data.texCoords = coords
- data.shader = shader("Documents:cellShadingTextured")
- else
- data.shader = shader("Documents:cellShading")
- end
- data.shader.light = vec3(100,-100,100):normalize()
- data.shader.thickness = 0.1
- verts = nil
- coords = nil
- colors = nil
- normals = nil
- img = nil
- return data
- end
- -- Converts a string of 4 bytes to a float
- function bytesToFloat(x)
- local byte = string.byte
- local ldexp = math.ldexp
- local sign = 1
- local mantissa = byte(x, 3) % 128
- for i = 2, 1, -1 do
- mantissa = mantissa * 256 + byte(x, i)
- end
- if byte(x, 4) > 127 then
- sign = -1
- end
- local exponent = (byte(x, 4) % 128) * 2 + math.floor(byte(x, 3) / 128)
- if exponent == 0 then
- return 0
- end
- mantissa = (ldexp(mantissa, -23) + 1) * sign
- return ldexp(mantissa, exponent - 127)
- end
- -- Goes to next available pixel
- function nextPixel(x, y, max)
- cnt = cnt + 1
- x = x + 1
- if x>max then
- x = 1
- y = y - 1
- end
- return x, y
- end
- --# Graphics
- Graphics = class()
- function Graphics:init()
- self.players = nil
- -- 2D graphics
- self.shadow = readImage("Documents:Shadow")
- self.spawn = readImage("Documents:Spawn")
- self.BG = readImage("Dropbox:background2")
- self.mask = readImage("Dropbox:mask")
- self.swirl = readImage("Dropbox:swirl")
- self.bolt = readImage("Dropbox:bolt2")
- self.blast = readImage("Dropbox:blast2")
- self.buttonShield = readImage("Dropbox:shield")
- self.buttonAttack = readImage("Dropbox:sword")
- self.buttonSummon = readImage("Dropbox:Summon")
- self.buttonUnsummon = readImage("Dropbox:Unsummon")
- self.buttonBuff = readImage("Dropbox:Buff")
- self.buttonFire = readImage("Dropbox:Fire")
- -- 3D graphics
- if bnw then
- self.toon = Model("Dropbox:model")
- else
- self.toon = Model("Dropbox:model", "Dropbox:texture2")
- end
- -- self.toon:setColors(128, 128, 128, 255)
- self.shield = Model("Dropbox:model2") --,"Dropbox:shieldBubble")
- self.shield:setColors(64, 225, 255, 128)
- self.world = Model("Dropbox:worldModel")
- if bnw then
- self.world:setColors(255, 255, 255, 255)
- end
- self.sky = mesh()
- self.skyId = self.sky:addRect(0, 0, 880, 880)
- self.sky.texture = "Dropbox:sky"
- self.sky:setColors(128, 128, 128, 100)
- local rnd = math.random
- local ins = table.insert
- self.randoms = {}
- for i=1, 10 do
- ins(self.randoms, rnd())
- end
- end
- function Graphics:draw()
- local playerModel, minionModel
- local shadow = self.shadow
- local spawn = self.spawn
- pushStyle()
- pushMatrix()
- fontSize(8)
- for _, player in ipairs(self.players) do
- playerModel = player.model
- -- draw player shadow
- translate(0,0,.2)
- sprite(shadow, playerModel.x-12, playerModel.y, 40)
- -- draw player life and mana
- translate(0,0,.2)
- fill(0, 255, 0, 255)
- text(player.life.." "..player.lifeText, playerModel.x, playerModel.y - 20)
- fill(0, 0, 255, 255)
- text(player.manaText, playerModel.x, playerModel.y - 30)
- for i=1, 5 do
- minion = player.summons[i]
- if minion then
- minionModel = minion.model
- -- draw minion spawn point and shadow
- translate(0,0,.2)
- sprite(spawn, minion.spawn.x, minion.spawn.y)
- translate(0,0,.2)
- sprite(shadow, minionModel.x-12, minionModel.y, 40)
- -- draw minion life and power
- translate(0,0,.2)
- fill(0, 255, 0, 255)
- text(minion.lifeText, minionModel.x, minionModel.y - 15)
- fill(255, 0, 0, 255)
- text(minion.powerText, minionModel.x, minionModel.y - 25)
- end
- end
- end
- for _, player in ipairs(self.players) do
- if player.shielding then
- self:drawShield(player)
- end
- translate(0,0,.2)
- if player.fire then
- pushMatrix()
- translate(player.nearestEnemy.model.x,player.nearestEnemy.model.y,0)
- local n = math.cos(player.timer*4.5)
- scale(n,n,1)
- if player.timer>.5 then
- sprite("Dropbox:blast4", 0, 0, 50)
- translate(0,0,35)
- sprite("Dropbox:blast2", 0, 0, 100)
- translate(0,0,35)
- sprite("Dropbox:blast4", 0, 0, 75)
- end
- translate(0,0,260)
- rotate(90, 1,0,0)
- rotate((player.timer)*720, 0,1,0)
- sprite(graphics.bolt, 0,0, 100-math.sin(player.timer*2)*100, 512)
- -- rotate(math.pi/2+(player.timer)*math.pi/2, 0,1,0)
- -- sprite(graphics.bolt, 0,0, 100-math.sin(player.timer*2)*100, 512)
- popMatrix()
- end
- end
- local delta
- for _, player in ipairs(self.players) do
- playerModel = player.model
- for i=1, 5 do
- minion = player.summons[i]
- if minion then
- minionModel = minion.model
- if minion.spawning or minion.despawning or minion.dying then
- local rnd = math.random
- if minion.spawning then
- delta = 1/minion.spawnTime
- else
- delta = 1
- end
- tint(255, 255, 255, 255-minion.timer*delta*255)
- for i=1, 5 do
- translate(0,0,.2)
- local n = 180 + self.randoms[i]*360
- pushMatrix()
- translate(minionModel.x,minionModel.y,i*15)
- scale(delta*minion.timer*n/540, delta*minion.timer*n/540, delta*minion.timer*n/540)
- rotate(n+math.sin(minion.timer)*n, 0,0,1)
- sprite(graphics.swirl, 0,0, 130)
- popMatrix()
- end
- end
- end
- end
- end
- popStyle()
- popMatrix()
- end
- function Graphics:drawShield(player)
- moving = true
- local direction = player.timer*1800
- local pos = player.model
- pushMatrix()
- -- position 3D model
- translate(pos.x,pos.y, pos.size/2+20)
- self.shield:setColors(0,0,255,64*math.abs(math.sin(player.timer*10)))
- -- animate 3D model
- if moving then
- rotate(math.sin(ElapsedTime*20)*5, 1, 1, 1)
- else
- rotate(math.sin(ElapsedTime*5)*1, 1, 1, 1)
- end
- -- set 3D model orientation
- rotate(direction, 0, 0, 1)
- scale(pos.size,pos.size,pos.size)
- self.shield:draw()
- popMatrix()
- end
- function Graphics:drawWorld()
- pushMatrix()
- -- position 3D model
- -- translate(pos.x,pos.y, pos.size/2+20)
- -- animate 3D model
- -- set 3D model orientation
- -- translate(0, 30, 0)
- scale(40, 40, 40)
- if self.world.shader then
- self.world.shader.camera = Camera
- self.world.shader.light = Light
- end
- self.world:draw()
- popMatrix()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement