Advertisement
ezak

Arena

Jan 3rd, 2013
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 36.35 KB | None | 0 0
  1. --# Combat
  2. Combat = class()
  3.  
  4. function Combat:init(p1, p2, dist)
  5.     self.p1 = p1
  6.     self.p2 = p2
  7.    
  8.     self.p1.fighting = true
  9.     self.p2.fighting = true
  10.    
  11.     self.inCombat = true
  12.     self.timer = 0
  13.     self.dist = dist
  14.     self.closedUp = false
  15. end
  16.  
  17. function Combat:doCombat()
  18.     local sin = math.sin
  19.     local cos = math.cos
  20.     local atan2 = math.atan2
  21.    
  22.     local p1m = self.p1.model
  23.     local p2m = self.p2.model
  24.    
  25.     self.p1.direction = atan2(p2m.y - p1m.y, p2m.x - p1m.x)
  26.     self.p2.direction = atan2(p1m.y - p2m.y, p1m.x - p2m.x)
  27.    
  28.     if not self.closedUp or self.dist > 35 then
  29.         local x = p1m.x - p2m.x
  30.         local y = p1m.y - p2m.y
  31.         local dist = math.sqrt(x*x + y*y)
  32.        
  33.         if self.dist ~= dist then
  34.             self.closedUp = true
  35.         end
  36.        
  37.         self.dist = dist
  38.            
  39.         p1m.x = p1m.x + cos(self.p1.direction)*30*DeltaTime
  40.         p1m.y = p1m.y + sin(self.p1.direction)*30*DeltaTime
  41.            
  42.         p2m.x = p2m.x + cos(self.p2.direction)*30*DeltaTime
  43.         p2m.y = p2m.y + sin(self.p2.direction)*30*DeltaTime
  44.  
  45.         return
  46.     end
  47.    
  48.     if not self.closedUp or self.dist < 34 then
  49.         local x = p1m.x - p2m.x
  50.         local y = p1m.y - p2m.y
  51.    
  52.         local dist = math.sqrt(x*x + y*y)
  53.        
  54.         if self.dist ~= dist then
  55.             self.closedUp = true
  56.         end
  57.        
  58.         self.dist = dist
  59.            
  60.         p1m.x = p1m.x - cos(self.p1.direction)*30*DeltaTime
  61.         p1m.y = p1m.y - sin(self.p1.direction)*30*DeltaTime
  62.            
  63.         p2m.x = p2m.x - cos(self.p2.direction)*30*DeltaTime
  64.         p2m.y = p2m.y - sin(self.p2.direction)*30*DeltaTime
  65.         return
  66.     end
  67.        
  68.  
  69.     self.p1.direction = self.p1.direction + sin(-self.timer*8)
  70.     self.p2.direction = self.p2.direction + sin(-self.timer*8)
  71.    
  72.     self.timer = self.timer + DeltaTime
  73.    
  74.     if self.timer > .8 then
  75.         self.timer = 0
  76.         if self.p1.despawning or self.p2.despawning then
  77.             self.p1.despawning = true
  78.             self.p2.despawning = true
  79.             self.inCombat = false
  80.             self.p1.fighting = false
  81.             self.p2.fighting = false
  82.             return
  83.         end
  84.        
  85.        
  86.         self.p1:modLife(-self.p2.power)
  87.         self.p2:modLife(-self.p1.power)
  88.        
  89.         if self.p1.life <= 0 then
  90.             self.p1.dying = true
  91.             self.inCombat = false
  92.             if self.p2.life > 0 then
  93.                 self.p2.fighting = false
  94.                 self.p2.despawning = true
  95.             end
  96.         end
  97.        
  98.         if self.p2.life <= 0 then
  99.             self.p2.dying = true
  100.             self.inCombat = false
  101.             if self.p1.life > 0 then
  102.                 self.p1.fighting = false
  103.                 self.p1.despawning = true
  104.             end
  105.         end
  106.        
  107.     end
  108.    
  109. end
  110. --# GUI
  111. GUI = class()
  112.  
  113. function GUI:init(player)
  114.     self.stick = Stick()
  115.     self.button = {}
  116.     self.id = player
  117. end
  118.  
  119. function GUI:draw()
  120.     local stick = self.stick
  121.  
  122.     if stick.active then
  123.         stick:draw()
  124.     end
  125.    
  126.     for _, button in ipairs(self.button) do
  127.         button:draw()
  128.     end
  129. end
  130.  
  131. function GUI:touched(touch, side)
  132.     if side then
  133.         self.stick:touched(touch)
  134.     else
  135.         for _, button in ipairs(self.button) do
  136.             local type = button:touched(touch)
  137.             if type == "summon" then
  138.                 if touch.state == BEGAN then
  139.                     self.id:summon(graphics.toon)
  140.                 end
  141.             end
  142.            
  143.             if type == "attack" then
  144.                 if touch.state == BEGAN and not self.id.shielding then
  145.                     self.id.attacking = true
  146.                 end
  147.             end
  148.            
  149.             if type == "fire" then
  150.                 if touch.state == BEGAN and not self.id.fire and self.id.mana > 1 then
  151.                     self.id.fire = true
  152.                     self.id:getNearestEnemy()
  153.                     self.id:modMana(-1)
  154.                 end
  155.             end
  156.            
  157.             if type == "unsummon" then
  158.                 if touch.state == BEGAN and not self.id.unsummon and self.id.mana > 2 then
  159.                     self.id.unsummon = true
  160.                     self.id:getNearestEnemy()
  161.                     self.id:modMana(-2)
  162.                 end
  163.             end
  164.            
  165.             if type == "buff" then
  166.                 if touch.state == BEGAN and not self.id.buff and self.id.mana > 2 then
  167.                     self.id.buff = true
  168.                     self.id:getNearestFriend()
  169.                     self.id:modMana(-2)
  170.                 end
  171.             end
  172.            
  173.             if type == "shield" then
  174.                 if touch.state == ENDED and not self.id.attacking then
  175.                     self.id.shielding = false
  176.                     self.id.timer = 0
  177.                 else
  178.                     if self.id.mana >= 1 and not self.id.attacking then
  179.                         self.id.shielding = true
  180.                     end
  181.                 end
  182.                    
  183.             end
  184.         end
  185.     end
  186. end
  187.  
  188. --# Main
  189. -- PvP latest
  190. function setup()
  191.     displayMode(FULLSCREEN)
  192.     spriteMode(CENTER)
  193.    
  194.     bnw = false
  195.    
  196.     Camera = vec3(1,1,1)
  197.     Light = vec3(1,1,1)
  198.     font("Futura-CondensedExtraBold")
  199.   --  noSmooth()
  200.     parameter.integer("mode", 1, 2, 1)
  201.    
  202.     parameter.integer("zzz", -20, 20, 0)
  203.    
  204.     parameter.integer("lx", -100, 100, 1)
  205.     parameter.integer("ly", -100, 100, 1)
  206.     parameter.integer("lz", -100, 100, 100)
  207. --    parameter.integer("zoomX", 1, 1000, 200)
  208.  --   parameter.integer("zoomY", -1000, -1, -175)
  209.  
  210.     -- sprite setup
  211.     graphics = Graphics()
  212.    
  213.     -- player setup
  214.     player1 = Player(graphics.toon, -110, 0)
  215.     player2 = Player(graphics.toon, 150, 0)
  216.    
  217.     player1.target = player2
  218.     local ins = table.insert
  219.    
  220.    
  221.     ins(player1.gui.button, Buttons("attack", WIDTH - 100,200))
  222.     ins(player1.gui.button, Buttons("shield", WIDTH - 200,100))
  223.    
  224.     ins(player1.gui.button, Buttons("summon", WIDTH - 32,300))
  225.     ins(player1.gui.button, Buttons("fire", WIDTH - 96,300))
  226.     ins(player1.gui.button, Buttons("unsummon", WIDTH - 32,364))
  227.     ins(player1.gui.button, Buttons("buff", WIDTH - 96,364))
  228.    
  229.     player2.target = player1
  230.     ins(player2.gui.button, Buttons("attack", 100, HEIGHT - 200))
  231.     ins(player2.gui.button, Buttons("shield", 200, HEIGHT - 100))
  232.    
  233.     ins(player2.gui.button, Buttons("summon", 32, HEIGHT - 300))
  234.     ins(player2.gui.button, Buttons("unsummon", 32, HEIGHT - 364))
  235.     ins(player2.gui.button, Buttons("buff", 96, HEIGHT - 364))
  236.     ins(player2.gui.button, Buttons("fire", 96, HEIGHT - 300))
  237.     player2.gui.stick.direction = -3.14
  238.    
  239.     graphics.players = {player1, player2}
  240.    
  241.     tick = 0
  242.     timer = 0
  243.     fps = 0
  244.    
  245.     x = 0
  246.     y = 0
  247.     smoothing = 0
  248.   --  im = image(WIDTH,HEIGHT)
  249. end
  250.  
  251. function draw()
  252.     if bnw then
  253.         background(200, 200, 200, 255)
  254.     else
  255.         background(102, 150, 80, 255)
  256.     end
  257.     setCamera()
  258.     -- scene
  259.    
  260.     graphics:drawWorld()
  261.    
  262.     -- draw players ane minions
  263.     player1:draw()
  264.     translate(0,0,.2)
  265.     player2:draw()
  266.    
  267.     if bnw then
  268.         tint(200, 200, 200, 255)
  269.     else
  270.         tint(102, 150, 80, 255)
  271.     end
  272.        
  273.  --   sprite(graphics.BG, xxx, yyy, zzz, zzz)
  274.     translate(0,0,-4)
  275.     sprite(graphics.BG, 0, 0, 880, 880)
  276.     noTint()
  277.     -- draw shadows, spawn points, text, etc...
  278.     graphics:draw()
  279.    
  280.    
  281.    
  282.     -- move seemless sky texture and draw it
  283.     --[[
  284.     x = x + (1/2048)
  285.     y = y + (1/2048)
  286.     translate(0,0,200)
  287.     graphics.sky:setRectTex(graphics.skyId, x, y, 1, 1)
  288.     graphics.sky:draw()
  289.     translate(0,0,-200)
  290.     ]]--
  291.    
  292.     ortho()
  293.     viewMatrix(matrix())
  294.     sprite(graphics.mask, WIDTH/2, HEIGHT/2, WIDTH+300, HEIGHT+300)
  295.    
  296.     -- draw pads and buttons
  297.     player1.gui:draw()
  298.     player2.gui:draw()
  299.    
  300.     if timer > .4 then
  301.         timer = 0
  302.         tick = tick + .2
  303.         fps = math.floor(1/DeltaTime*10)/10
  304.        
  305.         player1:modMana(.1)
  306.         player2:modMana(.1)
  307.     end
  308.    
  309.     local n = 2
  310.     for i=1, 5 do
  311.         if player1.summons[i] then
  312.             n = n + 1
  313.         end
  314.         if player2.summons[i] then
  315.             n = n + 1
  316.         end
  317.     end
  318.    
  319.     text(n.." objects, "..(n*graphics.toon.size/3).." polygons", 150, HEIGHT - 20)
  320.     text("FPS: "..fps, WIDTH - 50, HEIGHT - 20)
  321.    
  322.     timer = timer + DeltaTime
  323. end
  324.  
  325. function touched(touch)
  326.     if touch.y < HEIGHT/2 then
  327.         player1.gui:touched(touch, touch.x < WIDTH/2)
  328.     else
  329.         player2.gui:touched(touch, touch.x > WIDTH/2)
  330.     end
  331. end
  332.  
  333.  
  334. function setCamera()
  335.     -- set camera to point between both players
  336.     -- and zoom out so both are always on screen
  337.     local p1 = player1.model
  338.     local p2 = player2.model
  339.     local x, y, dist, tmp
  340.     x = (p1.x - p2.x)
  341.     y = (p1.y - p2.y)
  342.     dist = math.sqrt(x*x+y*y)
  343.     x = (p1.x + p2.x)/2
  344.     y = (p1.y + p2.y)/2
  345.     perspective(60, WIDTH/HEIGHT)
  346.    
  347.     if mode == 1 then
  348.        
  349.         Light = vec3(lx, ly, lz):normalize()
  350.         Camera = vec3(x,-175+y,200+dist):normalize()
  351.         camera(x,-175+y,200+dist, x,y,0, 0,1,0)
  352.     else
  353.         Camera = vec3(x,-1+y,200+dist):normalize()
  354.         Light = vec3(lx, ly, lz):normalize()
  355.         camera(x,-1+y,200+dist, x,y,0, 0,1,0)
  356.     end
  357. end
  358. --# Player
  359. Player = class()
  360.  
  361. function Player:init(mdl, x, y)
  362.     self.summons = {nil, nil, nil, nil, nil}
  363.     self.direction = 0
  364.    
  365.     -- numerical life and power
  366.     self.life = 10
  367.     self.mana = 10
  368.     self.maxMana = 10
  369.     self.speed = 1
  370.    
  371.     -- graphical format of life and power
  372.     self:modLife(0)
  373.     self:modMana(0)
  374.    
  375.     -- enemy player
  376.     self.target = nil
  377.     self.nearestEnemy = nil
  378.     self.nearestFriend = nil
  379.    
  380.     -- player 3d model, position and scale
  381.     self.model = Cube(mdl, x, y, 12)
  382.    
  383.     -- player touchpad and buttons
  384.     self.gui = GUI(self)
  385.    
  386.     self.casting = false
  387.     self.shielding = false
  388.    
  389.     self.buff = false
  390.     self.fire = false
  391.     self.unsummon = false
  392.    
  393.     self.attacking = false
  394.     self.hasHit = false
  395.    
  396.     self.timer = 0
  397. end
  398.  
  399. function Player:modLife(val)
  400.     self.life = self.life + val
  401.     if self.life > 10 then
  402.         self.life = 10
  403.     end
  404.     self.lifeText = self:setStat(self.life)
  405. end
  406.  
  407. function Player:modMana(val)
  408.     self.mana = self.mana + val
  409.     if self.mana >= self.maxMana then
  410.         self.mana = self.maxMana
  411.     end
  412.     if self.mana <= 0 then
  413.         self.mana = 0
  414.     end
  415.     self.manaText = self:setStat(self.mana)
  416. end
  417.  
  418. -- convert numeral stats to graphics so it can be displayed
  419. function Player:setStat(val)
  420.     local txt = ""
  421.     for i=1, val do
  422.         txt = txt.."|"
  423.     end
  424.     return txt
  425. end
  426.  
  427.  
  428. function Player:draw()
  429.     local pos = self.model
  430.     local target = self.target.model
  431.     local stick = self.gui.stick
  432.    
  433.     -- draw all minions
  434.     for i=1, 5 do
  435.         local minion = self.summons[i]
  436.         if minion then
  437.             if minion.dead then
  438.                 self.summons[i] = nil
  439.             else
  440.                 translate(0,0,.2)
  441.                 minion:draw()
  442.             end
  443.         end
  444.     end
  445.    
  446.     self.direction = stick.direction
  447.     -- do attack
  448.     if self.attacking then
  449.         self.direction = self.direction + math.sin(-self.timer*math.pi*2)
  450.         self.timer = self.timer + DeltaTime
  451.         if self.timer > 1 then
  452.             self.attacking = false
  453.             self.hasHit = false
  454.             self.timer = 0
  455.         end
  456.     end
  457.    
  458.     -- do shield
  459.     if self.shielding then
  460.         self.timer = self.timer + DeltaTime
  461.         self:modMana(-DeltaTime*1.5)
  462.         if self.mana == 0 then
  463.             self.shielding = false
  464.             self.timer = 0
  465.         end
  466.     end
  467.    
  468.     -- do fire
  469.     if self.fire then
  470.         self.timer = self.timer + DeltaTime
  471.         if self.timer > 1 then
  472.             self.fire = false
  473.             if not self.nearestEnemy.shielding then
  474.                 self.nearestEnemy:modLife(-1)
  475.             end
  476.             self.timer = 0
  477.         end
  478.     end
  479.    
  480.     -- do unsummon
  481.     if self.unsummon then
  482.         self.nearestEnemy.despawning = true
  483.         self.unsummon = false
  484.     end
  485.    
  486.     -- do buff
  487.     if self.buff then
  488.         self.timer = self.timer + DeltaTime
  489.         if self.timer > 1 then
  490.             self.buff = false
  491.             if self.nearestFriend then
  492.                 self.nearestFriend:modLife(1)
  493.                 self.nearestFriend:modPower(1)
  494.             else
  495.                 self:modMana(2)
  496.             end
  497.             self.timer = 0
  498.         end
  499.     end
  500.    
  501.    
  502.     -- check if player can move, and move if possible
  503.     if stick.active and not self:checkCollision() then
  504.         pos.x = pos.x + math.cos(self.direction)*self.speed*60*DeltaTime
  505.         pos.y = pos.y + math.sin(self.direction)*self.speed*60*DeltaTime
  506.     end
  507.         -- face other player
  508.     -- local direction = math.atan2(target.y - pos.y, target.x - pos.x)
  509.    
  510.     -- draw player based on stick direction
  511.     self.model:draw(self.direction, stick.active)
  512. end
  513.  
  514. function Player:summon(mdl)
  515.     -- add minion in front of player
  516.     if self.mana >= 1 then
  517.         local deltaX = self.model.x+50*math.cos(self.direction)
  518.         local deltaY = self.model.y+50*math.sin(self.direction)
  519.        
  520.         for i=1, 5 do
  521.             if self.summons[i] == nil then
  522.                 self.summons[i] = Summon(mdl, deltaX, deltaY, self.target, i)
  523.                 self:modMana(-1)
  524.                 return
  525.             end
  526.         end
  527.        
  528.     end
  529. end
  530.  
  531. function Player:getNearestEnemy()
  532.     local x = self.model.x - self.target.model.x
  533.     local y = self.model.y - self.target.model.y
  534.     local closest = -1
  535.     local sqrt = math.sqrt
  536.     local pos = self.model
  537.    
  538.     local dist = 0
  539.     local targ = nil
  540.     -- test collision on enemy minions
  541.     for i=1, 5 do
  542.         local minion = self.target.summons[i]
  543.         if minion then
  544.             if not (minion.despawning or minion.spawning or minion.dying) then
  545.                 x = pos.x - minion.model.x
  546.                 y = pos.x - minion.model.y
  547.                 dist = sqrt(x*x + y*y)
  548.                 if dist < closest or closest == -1 then
  549.                     targ = minion
  550.                     closest = dist
  551.                 end
  552.             end
  553.         end
  554.     end
  555.    
  556.     if closest == -1 then
  557.         targ = self.target
  558.     end
  559.    
  560.     self.nearestEnemy = targ
  561.    
  562. end
  563.  
  564. function Player:getNearestFriend()
  565.     local closest = -1
  566.     local sqrt = math.sqrt
  567.     local pos = self.model
  568.    
  569.     local dist = 0
  570.     local targ = nil
  571.     -- test collision on friendly minions
  572.     for i=1, 5 do
  573.         local minion = self.summons[i]
  574.         if minion then
  575.             if not (minion.despawning or minion.spawning or minion.dying) then
  576.                 x = pos.x - minion.model.x
  577.                 y = pos.x - minion.model.y
  578.                 dist = sqrt(x*x + y*y)
  579.                 if dist < closest or closest == -1 then
  580.                     targ = minion
  581.                     closest = dist
  582.                 end
  583.             end
  584.         end
  585.     end
  586.    
  587.     if closest == -1 then
  588.         targ = nil
  589.     end
  590.    
  591.     self.nearestFriend = targ
  592.    
  593. end
  594.  
  595.  
  596. function Player:checkCollision()
  597.     local x, y
  598.     local sqrt = math.sqrt
  599.    
  600.     -- set collision point in front of player
  601.     local deltaX = self.model.x + 15*math.cos(self.direction)
  602.     local deltaY = self.model.y + 15*math.sin(self.direction)
  603.    
  604.     -- test collision on opposing player
  605.     x = deltaX - self.target.model.x
  606.     y = deltaY - self.target.model.y
  607.     if sqrt(x*x + y*y) < 15 then
  608.         return true
  609.     end
  610.    
  611.     -- test collision on enemy minions
  612.     for i=1, 5 do
  613.         local minion = self.target.summons[i]
  614.         if minion then
  615.             if not (minion.despawning or minion.spawning or minion.fighting) then
  616.                 x = deltaX - minion.model.x
  617.                 y = deltaY - minion.model.y
  618.    
  619.                 if sqrt(x*x + y*y) < 15 then
  620.                     return true
  621.                 end
  622.             end
  623.         end
  624.     end
  625.    
  626.     return false
  627.    
  628. end
  629.  
  630. --# Summon
  631. Summon = class()
  632.  
  633. function Summon:init(mdl, x, y, target, id)
  634.     self.id = id
  635.    
  636.     -- numerical life and power
  637.     self.life = 1+math.floor(math.random(3))
  638.     self.power = 1
  639.     -- update format of life and power
  640.     self:modLife(0)
  641.     self:modPower(0)
  642.    
  643.     self.spawnTime = 1
  644.    
  645.     self.combat = nil
  646.    
  647.     -- model, position, scale, direction, spawn point and speed of minion
  648.     self.model = Cube(mdl, x, y, 12)
  649.     self.direction = math.atan2(target.model.y - self.model.y, target.model.x - self.model.x)
  650.     self.spawn = vec2(x, y)
  651.     self.speed = 1 + math.random()
  652.    
  653.     -- current player target
  654.     self.target = target
  655.    
  656.     self.dead = false
  657.    
  658.     self.spawning = true
  659.     self.dying = false
  660.     self.despawning = false
  661.     self.fighting = false
  662.     self.attackingPlayer = false
  663.    
  664.     self.timer = 0
  665. end
  666.  
  667. function Summon:modLife(val)
  668.     self.life = self.life + val
  669.     self.lifeText = self:setStat(self.life)
  670. end
  671.  
  672. function Summon:modPower(val)
  673.     self.power = self.power + val
  674.     self.powerText = self:setStat(self.power)
  675. end
  676.  
  677. -- convert numeral stats to graphics so it can be displayed
  678. function Summon:setStat(val)
  679.     local txt = ""
  680.     for i=1, val do
  681.         txt = txt.."|"
  682.     end
  683.     return txt
  684. end
  685.  
  686. function Summon:draw()
  687.     if self.life <= 0 then
  688.         self.dying = true
  689.     end
  690.    
  691.     local pos = self.model
  692.     local target = self.target.model
  693.    
  694.    
  695.     -- draw minion in correct direction
  696.     if self.dying then
  697.         pushMatrix()
  698.         translate(0, 0, -self.timer*50)
  699.         pos:draw(self.direction, false)
  700.         popMatrix()
  701.     elseif self.spawning then
  702.         if self.timer>self.spawnTime/2 then
  703.             pos:draw(self.direction, false)
  704.         end
  705.     elseif self.despawning then
  706.         if self.timer<.5 then
  707.             pos:draw(self.direction, false)
  708.         end
  709.     else
  710.         pos:draw(self.direction, not (self.fighting or self.attackingPlayer))
  711.     end
  712.    
  713.  
  714.     -- check if engaged in combat
  715.     if self.combat then
  716.         self.combat:doCombat()
  717.         if not self.combat.inCombat then
  718.             self.combat = nil
  719.         end
  720.         return
  721.     end
  722.        
  723.     -- stop movement until poping is done
  724.     if self.spawning then
  725.         self.direction = self.timer*(4*math.pi/self.spawnTime)
  726.         self.timer = self.timer + DeltaTime
  727.         if self.timer > self.spawnTime then
  728.             self.spawning = false
  729.             self.timer = 0
  730.         end
  731.         return
  732.     end
  733.    
  734.     -- stop movement until poping is done
  735.     if self.despawning then
  736.         self.direction = self.timer*(4*math.pi/self.spawnTime)
  737.         self.timer = self.timer + DeltaTime
  738.         if self.timer > 1 then
  739.             self.despawning = false
  740.             self.spawning = true
  741.             self.timer = 0
  742.             pos.x = self.spawn.x
  743.             pos.y = self.spawn.y
  744.         end
  745.         return
  746.     end
  747.  
  748.     -- stop movement then die
  749.     if self.dying then
  750.         self.timer = self.timer + DeltaTime
  751.         if self.timer > 1 then
  752.             self.dying = false
  753.             self.timer = 0
  754.             self.dead = true
  755.         end
  756.         return
  757.     end
  758.  
  759.  
  760.     -- stop movement until attack to player is done, then respawn
  761.     if self.attackingPlayer then
  762.         if self.target.attacking and not self.target.hasHit then
  763.             self:modLife(-1)
  764.             self.target.hasHit = true
  765.         end
  766.         self.direction = math.atan2(target.y - pos.y, target.x - pos.x) + math.sin(self.timer*math.pi*2)
  767.         self.timer = self.timer + DeltaTime
  768.         if self.timer > .7 then
  769.             if self.target.shielding then
  770.                 self.target:modLife(-math.floor(self.power/2))
  771.             else
  772.                 self.target:modLife(-self.power)
  773.             end
  774.             self.attackingPlayer = false
  775.             self.despawning = true
  776.             self.timer = 0
  777.         end
  778.         return
  779.     end
  780.    
  781.     if not self.fighting then
  782.         -- check distance to target
  783.         local x = pos.x - target.x
  784.         local y = pos.y - target.y
  785.         local dist = math.sqrt(x*x + y*y)
  786.         -- attack player when in range
  787.         if not self.attackingPlayer and dist < 50 then
  788.             self.attackingPlayer = true
  789.             self.timer = 0
  790.             return
  791.         end
  792.        
  793.         -- face target at all times
  794.         self.direction = math.atan2(target.y - pos.y, target.x - pos.x)
  795.         if not self:checkCollision() then
  796.             pos.x = pos.x + math.cos(self.direction)*self.speed*60*DeltaTime
  797.             pos.y = pos.y + math.sin(self.direction)*self.speed*60*DeltaTime
  798.         end
  799.     end
  800.    
  801.    
  802.  
  803. end
  804.  
  805. function Summon:checkCollision()
  806.     local x, y, deltaX, deltaY, friend, enemy
  807.    
  808.     local sqrt = math.sqrt
  809.  
  810.     local dist
  811.     for i=1, 5 do
  812.      
  813.     -- check collision vs enemy minions and start fighting
  814.         enemy = self.target.summons[i]
  815.         if enemy and not (enemy.attackingPlayer or enemy.despawning or enemy.spawning or enemy.fighting) then
  816.             x = self.model.x - enemy.model.x
  817.             y = self.model.y - enemy.model.y
  818.             dist = sqrt(x*x + y*y)
  819.             if dist < 45 then
  820.                 self.combat = Combat(self, enemy, dist)
  821.                 return true
  822.             end
  823.         end
  824.        
  825.     -- check collision vs friendly minions
  826.         friend = self.target.target.summons[i]
  827.         if friend and (friend.id ~= self.id) and not (friend.despawning or friend.spawning or friend.fighting) then
  828.             -- set collision point in front of minion
  829.             deltaX = self.model.x + 16*math.cos(self.direction)
  830.             deltaY = self.model.y + 16*math.sin(self.direction)
  831.             x = deltaX - friend.model.x
  832.             y = deltaY - friend.model.y
  833.                
  834.             if sqrt(x*x + y*y) < 15 then
  835.                 return true
  836.             end
  837.         end
  838.     end
  839.    
  840.     return false
  841.    
  842. end
  843.  
  844.  
  845. --# Cube
  846. Cube = class()
  847.  
  848.  
  849. function Cube:init(mdl, x, y, s)
  850.     self.x = x
  851.     self.y = y
  852.    
  853.     self.size = s
  854.  
  855.     -- 3D model to be used
  856.     self.mdl = mdl
  857.  
  858.    
  859. end
  860.  
  861. function Cube:draw(dir, moving)
  862.     local direction = dir or 0
  863.     direction = direction/math.pi*180
  864.  
  865.     pushMatrix()
  866.  
  867.     -- position 3D model
  868.     translate(self.x,self.y, self.size/2+20)
  869.    
  870.     -- animate 3D model
  871.     if moving then
  872.         rotate(math.sin(ElapsedTime*20)*5, 1, 1, 1)
  873.     else
  874.         rotate(math.sin(ElapsedTime*5)*1, 1, 1, 1)
  875.     end
  876.    
  877.     -- set 3D model orientation
  878.     rotate(direction, 0, 0, 1)
  879.     scale(self.size,self.size,self.size)
  880.     if self.mdl.shader then
  881.         self.mdl.shader.camera = Camera
  882.         self.mdl.shader.light = Light
  883.     end
  884.     self.mdl:draw()
  885.  
  886.  
  887.  
  888.     popMatrix()
  889. end
  890.  
  891.  
  892. --# Stick
  893. Stick = class()
  894.  
  895. function Stick:init()
  896.     self.direction = 0
  897.     self.dist = 0
  898.    
  899.     self.active = false
  900.     self.origin = vec2(150, 150)
  901.     self.center = self.origin
  902.     self.pos = self.origin
  903.    
  904.     stroke(127, 127, 127, 127)
  905.     strokeWidth(10)
  906.     noFill()
  907.     self.stick_bg = image(128, 128)
  908.     setContext(self.stick_bg)
  909.     ellipse(64, 64, 128)
  910.    
  911.     noStroke()
  912.     fill(192, 192, 192, 127)
  913.     self.stick = image(96, 96)
  914.     setContext(self.stick)
  915.     ellipse(48, 48, 96)
  916.    
  917. end
  918.  
  919. function Stick:draw()
  920.     sprite(self.stick_bg, self.center.x, self.center.y)
  921.     sprite(self.stick, self.pos.x, self.pos.y)
  922. end
  923.  
  924. function Stick:touched(touch)
  925.     if touch.state == BEGAN then
  926.         self.center = vec2(touch.x, touch.y)
  927.         self.active = true
  928.     end
  929.    
  930.     self.pos = vec2(touch.x, touch.y)
  931.     self.direction = math.atan2(self.pos.y - self.center.y, self.pos.x - self.center.x)
  932.    
  933.     self.dist = math.min(2, self.pos:dist(self.center)/32)
  934.    
  935.     if touch.state == ENDED then
  936.         self.center = self.origin
  937.         self.pos = self.center
  938.         self.active = false
  939.     end
  940.    
  941.    
  942. end
  943.  
  944. --# Buttons
  945. Buttons = class()
  946.  
  947. function Buttons:init(type, x, y)
  948.     self.type = type
  949.     self.x = x
  950.     self.y = y
  951. end
  952.  
  953. function Buttons:draw()
  954.     if self.type == "summon" then
  955.         sprite(graphics.buttonSummon, self.x, self.y)
  956.     elseif self.type == "attack" then
  957.         sprite(graphics.buttonAttack, self.x, self.y)
  958.     elseif self.type == "shield" then
  959.         sprite(graphics.buttonShield, self.x, self.y)
  960.     elseif self.type == "fire" then
  961.         sprite(graphics.buttonFire, self.x, self.y)
  962.     elseif self.type == "buff" then
  963.         sprite(graphics.buttonBuff, self.x, self.y)
  964.     elseif self.type == "unsummon" then
  965.         sprite(graphics.buttonUnsummon, self.x, self.y)
  966.     end    
  967.        
  968.        
  969. end
  970.  
  971. function Buttons:touched(touch)
  972.     if touch.x > self.x - 48 and touch.x < self.x + 48 then
  973.         if touch.y > self.y - 48 and touch.y < self.y + 48 then
  974.             return self.type
  975.         end
  976.     end
  977.     return false
  978. end
  979.  
  980. --# ModelLoader
  981. --Model = class()
  982.    
  983. function Model(mdl, texture)
  984.     local img = readImage(mdl)
  985.     local width, height = spriteSize(mdl)
  986.    
  987.  
  988.    
  989.     local verts = {}
  990.     local normals = {}
  991.     local colors = {}
  992.     local coords = {}
  993.    
  994.     local a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, x, y, z, X, Y, n, size
  995.     local strToChar = string.char
  996.     local ins = table.insert
  997.    
  998.    
  999.     cnt = 0
  1000.     X = 1
  1001.     Y = height
  1002.    
  1003.     n = 1
  1004.     a1, b1, c1 = img:get(X,Y)
  1005.     X, Y = nextPixel(X, Y, width)
  1006.     d1 = img:get(X,Y)
  1007.     X, Y = nextPixel(X, Y, width)
  1008.     size = bytesToFloat(strToChar(a1, b1, c1, d1))
  1009.    
  1010.     cnt = 0
  1011. -- vertices
  1012.     while n<=size do
  1013.         a1, b1, c1 = img:get(X,Y)
  1014.         X, Y = nextPixel(X, Y, width)
  1015.        
  1016.         d1, a2, b2 = img:get(X,Y)
  1017.         X, Y = nextPixel(X, Y, width)
  1018.        
  1019.         c2, d2, a3 = img:get(X,Y)
  1020.         X, Y = nextPixel(X, Y, width)
  1021.        
  1022.         b3, c3, d3 = img:get(X,Y)
  1023.         X, Y = nextPixel(X, Y, width)
  1024.        
  1025.         x = bytesToFloat(strToChar(a1, b1, c1, d1))
  1026.         y = bytesToFloat(strToChar(a2, b2, c2, d2))
  1027.         z = bytesToFloat(strToChar(a3, b3, c3, d3))
  1028.        
  1029.         ins(verts, vec3(x, y, z))
  1030.         n = n + 1
  1031.     end
  1032.     print(cnt.." for "..size.." vertices")
  1033.     cnt = 0
  1034. -- normals
  1035.     n = 1
  1036.     while n<=size do
  1037.         a1, b1, c1 = img:get(X,Y)
  1038.         X, Y = nextPixel(X, Y, width)
  1039.        
  1040.         d1, a2, b2 = img:get(X,Y)
  1041.         X, Y = nextPixel(X, Y, width)
  1042.        
  1043.         c2, d2, a3 = img:get(X,Y)
  1044.         X, Y = nextPixel(X, Y, width)
  1045.        
  1046.         b3, c3, d3 = img:get(X,Y)
  1047.         X, Y = nextPixel(X, Y, width)
  1048.        
  1049.         x = bytesToFloat(strToChar(a1, b1, c1, d1))
  1050.         y = bytesToFloat(strToChar(a2, b2, c2, d2))
  1051.         z = bytesToFloat(strToChar(a3, b3, c3, d3))
  1052.        
  1053.         ins(normals, vec3(x, y, z))
  1054.         n = n + 1
  1055.     end
  1056.     print(cnt.." for "..size.." normals")
  1057.     cnt = 0
  1058. -- colors
  1059.     n = 1
  1060.     while n<=size do
  1061.         a1, b1, c1 = img:get(X,Y)
  1062.         X, Y = nextPixel(X, Y, width)
  1063.        
  1064.         d1, a2, b2 = img:get(X,Y)
  1065.         X, Y = nextPixel(X, Y, width)
  1066.        
  1067.         c2, d2, a3 = img:get(X,Y)
  1068.         X, Y = nextPixel(X, Y, width)
  1069.        
  1070.         b3, c3, d3 = img:get(X,Y)
  1071.         X, Y = nextPixel(X, Y, width)
  1072.        
  1073.         x = bytesToFloat(strToChar(a1, b1, c1, d1))*255
  1074.         y = bytesToFloat(strToChar(a2, b2, c2, d2))*255
  1075.         z = bytesToFloat(strToChar(a3, b3, c3, d3))*255
  1076.        
  1077.        
  1078.         ins(colors, color(x, y, z, 255))
  1079.         n = n + 1
  1080.     end
  1081.     print(cnt.." for "..size.." colors")
  1082.     cnt = 0
  1083.    
  1084. -- texture coordinates
  1085.     if texture then
  1086.         n = 1
  1087.         while n<=size do
  1088.             a1, b1, c1 = img:get(X,Y)
  1089.             X, Y = nextPixel(X, Y, width)
  1090.            
  1091.             d1, a2, b2 = img:get(X,Y)
  1092.             X, Y = nextPixel(X, Y, width)
  1093.            
  1094.             c2, d2, a3 = img:get(X,Y)
  1095.             X, Y = nextPixel(X, Y, width)
  1096.            
  1097.             x = bytesToFloat(strToChar(a1, b1, c1, d1))
  1098.             y = bytesToFloat(strToChar(a2, b2, c2, d2))
  1099.            
  1100.             ins(coords, vec2(x,y))
  1101.             n = n + 1
  1102.         end
  1103.     end
  1104.    
  1105.     local total = 3*(size*4)+(size*3)+2
  1106.     print(cnt.." for "..size.." texture coords")
  1107.     print("total:"..total.." pixels, for a model of "..(size/3).." polygons")
  1108.    
  1109.     local min = math.ceil(math.sqrt(total))
  1110.     print("min img size:"..min.."x"..min)
  1111.     cnt = 0
  1112.    
  1113.     local data = mesh()
  1114.     data.vertices = verts
  1115.     data.colors = colors
  1116.     data.normals = normals
  1117.    
  1118.     if texture then
  1119.         data.texture = texture
  1120.         data.texCoords = coords
  1121.         data.shader = shader("Documents:cellShadingTextured")
  1122.     else
  1123.         data.shader = shader("Documents:cellShading")
  1124.     end
  1125.    
  1126.     data.shader.light = vec3(100,-100,100):normalize()
  1127.     data.shader.thickness = 0.1
  1128.    
  1129.     verts = nil
  1130.     coords = nil
  1131.     colors = nil
  1132.     normals = nil
  1133.     img = nil
  1134.    
  1135.     return data
  1136.    
  1137. end
  1138.  
  1139.  
  1140.  
  1141. -- Converts a string of 4 bytes to a float
  1142. function bytesToFloat(x)
  1143.     local byte = string.byte
  1144.     local ldexp = math.ldexp
  1145.     local sign = 1
  1146.     local mantissa = byte(x, 3) % 128
  1147.     for i = 2, 1, -1 do
  1148.         mantissa = mantissa * 256 + byte(x, i)
  1149.     end
  1150.     if byte(x, 4) > 127 then
  1151.         sign = -1
  1152.     end
  1153.     local exponent = (byte(x, 4) % 128) * 2 + math.floor(byte(x, 3) / 128)
  1154.     if exponent == 0 then
  1155.         return 0
  1156.     end
  1157.     mantissa = (ldexp(mantissa, -23) + 1) * sign
  1158.     return ldexp(mantissa, exponent - 127)
  1159. end
  1160.  
  1161. -- Goes to next available pixel
  1162. function nextPixel(x, y, max)
  1163.     cnt = cnt + 1
  1164.     x = x + 1
  1165.     if x>max then
  1166.         x = 1
  1167.         y = y - 1
  1168.     end
  1169.     return x, y
  1170. end
  1171.  
  1172. --# Graphics
  1173. Graphics = class()
  1174.  
  1175. function Graphics:init()
  1176.     self.players = nil
  1177.    
  1178.    
  1179.    
  1180.     -- 2D graphics
  1181.     self.shadow = readImage("Documents:Shadow")
  1182.     self.spawn = readImage("Documents:Spawn")
  1183.     self.BG = readImage("Dropbox:background2")
  1184.     self.mask = readImage("Dropbox:mask")
  1185.     self.swirl = readImage("Dropbox:swirl")
  1186.     self.bolt = readImage("Dropbox:bolt2")
  1187.     self.blast = readImage("Dropbox:blast2")
  1188.    
  1189.     self.buttonShield = readImage("Dropbox:shield")
  1190.     self.buttonAttack = readImage("Dropbox:sword")
  1191.    
  1192.     self.buttonSummon = readImage("Dropbox:Summon")
  1193.     self.buttonUnsummon = readImage("Dropbox:Unsummon")
  1194.     self.buttonBuff = readImage("Dropbox:Buff")
  1195.     self.buttonFire = readImage("Dropbox:Fire")
  1196.    
  1197.    
  1198.     -- 3D graphics
  1199.     if bnw then
  1200.         self.toon = Model("Dropbox:model")
  1201.     else
  1202.         self.toon = Model("Dropbox:model", "Dropbox:texture2")
  1203.     end
  1204.    -- self.toon:setColors(128, 128, 128, 255)
  1205.    
  1206.     self.shield = Model("Dropbox:model2") --,"Dropbox:shieldBubble")
  1207.     self.shield:setColors(64, 225, 255, 128)
  1208.    
  1209.     self.world = Model("Dropbox:worldModel")
  1210.     if bnw then
  1211.         self.world:setColors(255, 255, 255, 255)
  1212.     end
  1213.     self.sky = mesh()
  1214.     self.skyId = self.sky:addRect(0, 0, 880, 880)
  1215.     self.sky.texture = "Dropbox:sky"
  1216.     self.sky:setColors(128, 128, 128, 100)
  1217.    
  1218.     local rnd = math.random
  1219.     local ins = table.insert
  1220.     self.randoms = {}
  1221.     for i=1, 10 do
  1222.         ins(self.randoms, rnd())
  1223.     end
  1224. end
  1225.  
  1226.  
  1227. function Graphics:draw()
  1228.     local playerModel, minionModel
  1229.    
  1230.     local shadow = self.shadow
  1231.     local spawn = self.spawn
  1232.     pushStyle()
  1233.     pushMatrix()
  1234.     fontSize(8)
  1235.    
  1236.    
  1237.    
  1238.    
  1239.     for _, player in ipairs(self.players) do
  1240.         playerModel = player.model
  1241.         -- draw player shadow
  1242.         translate(0,0,.2)
  1243.         sprite(shadow, playerModel.x-12, playerModel.y, 40)
  1244.    
  1245.         -- draw player life and mana
  1246.         translate(0,0,.2)
  1247.         fill(0, 255, 0, 255)
  1248.         text(player.life.." "..player.lifeText, playerModel.x, playerModel.y - 20)
  1249.         fill(0, 0, 255, 255)
  1250.         text(player.manaText, playerModel.x, playerModel.y - 30)
  1251.        
  1252.         for i=1, 5 do
  1253.             minion = player.summons[i]
  1254.             if minion then
  1255.                 minionModel = minion.model
  1256.                
  1257.                 -- draw minion spawn point and shadow
  1258.                 translate(0,0,.2)
  1259.                 sprite(spawn, minion.spawn.x, minion.spawn.y)
  1260.                 translate(0,0,.2)
  1261.                 sprite(shadow, minionModel.x-12, minionModel.y, 40)
  1262.                
  1263.                 -- draw minion life and power
  1264.                 translate(0,0,.2)
  1265.                 fill(0, 255, 0, 255)
  1266.                 text(minion.lifeText, minionModel.x, minionModel.y - 15)
  1267.                 fill(255, 0, 0, 255)
  1268.                 text(minion.powerText, minionModel.x, minionModel.y - 25)
  1269.             end
  1270.         end
  1271.     end
  1272.    
  1273.  for _, player in ipairs(self.players) do
  1274.         if player.shielding then
  1275.             self:drawShield(player)
  1276.         end
  1277.        
  1278.         translate(0,0,.2)
  1279.         if player.fire then
  1280.             pushMatrix()
  1281.             translate(player.nearestEnemy.model.x,player.nearestEnemy.model.y,0)
  1282.             local n = math.cos(player.timer*4.5)
  1283.             scale(n,n,1)
  1284.             if player.timer>.5 then
  1285.             sprite("Dropbox:blast4", 0, 0, 50)
  1286.            
  1287.             translate(0,0,35)
  1288.             sprite("Dropbox:blast2", 0, 0, 100)
  1289.            
  1290.             translate(0,0,35)
  1291.             sprite("Dropbox:blast4", 0, 0, 75)
  1292.             end
  1293.             translate(0,0,260)
  1294.             rotate(90, 1,0,0)
  1295.             rotate((player.timer)*720, 0,1,0)
  1296.             sprite(graphics.bolt, 0,0, 100-math.sin(player.timer*2)*100, 512)
  1297.         --    rotate(math.pi/2+(player.timer)*math.pi/2, 0,1,0)
  1298.       --      sprite(graphics.bolt, 0,0, 100-math.sin(player.timer*2)*100, 512)
  1299.             popMatrix()
  1300.            
  1301.  
  1302.         end
  1303.     end
  1304.    
  1305.     local delta
  1306.     for _, player in ipairs(self.players) do
  1307.         playerModel = player.model
  1308.         for i=1, 5 do
  1309.             minion = player.summons[i]
  1310.             if minion then
  1311.                 minionModel = minion.model
  1312.                 if minion.spawning or minion.despawning or minion.dying then
  1313.                     local rnd = math.random
  1314.                     if minion.spawning then
  1315.                         delta = 1/minion.spawnTime
  1316.                     else
  1317.                         delta = 1
  1318.                     end
  1319.                    
  1320.                     tint(255, 255, 255, 255-minion.timer*delta*255)
  1321.                    
  1322.                     for i=1, 5 do
  1323.                         translate(0,0,.2)
  1324.                         local n = 180 + self.randoms[i]*360
  1325.                         pushMatrix()
  1326.                        
  1327.                         translate(minionModel.x,minionModel.y,i*15)
  1328.                         scale(delta*minion.timer*n/540, delta*minion.timer*n/540, delta*minion.timer*n/540)
  1329.                         rotate(n+math.sin(minion.timer)*n, 0,0,1)
  1330.                         sprite(graphics.swirl, 0,0, 130)
  1331.                         popMatrix()
  1332.                        
  1333.                     end
  1334.                 end
  1335.             end
  1336.         end
  1337.     end
  1338.    
  1339.     popStyle()
  1340.     popMatrix()
  1341. end
  1342.  
  1343. function Graphics:drawShield(player)
  1344.     moving = true
  1345.     local direction = player.timer*1800
  1346.    
  1347.     local pos = player.model
  1348.     pushMatrix()
  1349.  
  1350.     -- position 3D model
  1351.     translate(pos.x,pos.y, pos.size/2+20)
  1352.    
  1353.     self.shield:setColors(0,0,255,64*math.abs(math.sin(player.timer*10)))
  1354.    
  1355.     -- animate 3D model
  1356.     if moving then
  1357.         rotate(math.sin(ElapsedTime*20)*5, 1, 1, 1)
  1358.     else
  1359.         rotate(math.sin(ElapsedTime*5)*1, 1, 1, 1)
  1360.     end
  1361.    
  1362.     -- set 3D model orientation
  1363.     rotate(direction, 0, 0, 1)
  1364.     scale(pos.size,pos.size,pos.size)
  1365.  
  1366.     self.shield:draw()
  1367.  
  1368.     popMatrix()
  1369. end
  1370.    
  1371. function Graphics:drawWorld()
  1372.  
  1373.  
  1374.     pushMatrix()
  1375.  
  1376.     -- position 3D model
  1377. --    translate(pos.x,pos.y, pos.size/2+20)
  1378.    
  1379.    
  1380.     -- animate 3D model
  1381.  
  1382.    
  1383.     -- set 3D model orientation
  1384.   --  translate(0, 30, 0)
  1385.     scale(40, 40, 40)
  1386.  
  1387.     if self.world.shader then
  1388.         self.world.shader.camera = Camera
  1389.         self.world.shader.light = Light
  1390.     end
  1391.  
  1392.     self.world:draw()
  1393.  
  1394.     popMatrix()
  1395. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement