Created
December 19, 2015 21:14
-
-
Save jonbro/509b44703420e74658b2 to your computer and use it in GitHub Desktop.
lua code that starts running slowly
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 middleclass = { | |
| _VERSION = 'middleclass v3.2.0', | |
| _DESCRIPTION = 'Object Orientation for Lua', | |
| _URL = 'https://github.com/kikito/middleclass', | |
| _LICENSE = [[ | |
| MIT LICENSE | |
| Copyright (c) 2011 Enrique García Cota | |
| Permission is hereby granted, free of charge, to any person obtaining a | |
| copy of this software and associated documentation files (the | |
| "Software"), to deal in the Software without restriction, including | |
| without limitation the rights to use, copy, modify, merge, publish, | |
| distribute, sublicense, and/or sell copies of the Software, and to | |
| permit persons to whom the Software is furnished to do so, subject to | |
| the following conditions: | |
| The above copyright notice and this permission notice shall be included | |
| in all copies or substantial portions of the Software. | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| ]] | |
| } | |
| local _metamethods = {} | |
| for m in ([[ add band bor bxor bnot call concat div eq | |
| gc ipairs idiv le len lt metatable mod mode | |
| mul pairs pow shl shr sub tostring unm ]]):gmatch("%S+") do | |
| _metamethods['__' .. m] = true | |
| end | |
| local function _setClassDictionariesMetatables(aClass) | |
| local dict = aClass.__instanceDict | |
| dict.__index = dict | |
| local super = aClass.super | |
| if super then | |
| local superStatic = super.static | |
| setmetatable(dict, { __index = super.__instanceDict }) | |
| setmetatable(aClass.static, { __index = function(_,k) return rawget(dict,k) or superStatic[k] end }) | |
| else | |
| setmetatable(aClass.static, { __index = function(_,k) return dict[k] end }) | |
| end | |
| end | |
| local function _propagateMetamethod(aClass, name, f) | |
| for subclass in pairs(aClass.subclasses) do | |
| if not subclass.__metamethods[name] then | |
| subclass.__instanceDict[name] = f | |
| _propagateMetamethod(subclass, name, f) | |
| end | |
| end | |
| end | |
| local function _updateClassDict(aClass, key, value) | |
| if _metamethods[key] then | |
| if value == nil then | |
| aClass.__metamethods[key] = nil | |
| if aClass.super then | |
| value = aClass.super.__instanceDict[key] | |
| end | |
| else | |
| aClass.__metamethods[key] = true | |
| end | |
| _propagateMetamethod(aClass, key, value) | |
| end | |
| aClass.__instanceDict[key] = value | |
| end | |
| local function _setClassMetatable(aClass) | |
| setmetatable(aClass, { | |
| __tostring = function() return "class " .. aClass.name end, | |
| __index = aClass.static, | |
| __newindex = _updateClassDict, | |
| __call = function(self, ...) return self:new(...) end | |
| }) | |
| end | |
| local function _createClass(name, super) | |
| local aClass = { name = name, super = super, static = {}, __mixins = {}, __instanceDict = {}, __metamethods = {} } | |
| aClass.subclasses = setmetatable({}, {__mode = "k"}) | |
| _setClassDictionariesMetatables(aClass) | |
| _setClassMetatable(aClass) | |
| return aClass | |
| end | |
| local function _setSubclassMetamethods(aClass, subclass) | |
| for m in pairs(_metamethods) do | |
| subclass.__instanceDict[m] = aClass.__instanceDict[m] | |
| end | |
| end | |
| local function _setDefaultInitializeMethod(aClass, super) | |
| aClass.initialize = function(instance, ...) | |
| return super.initialize(instance, ...) | |
| end | |
| end | |
| local function _includeMixin(aClass, mixin) | |
| assert(type(mixin)=='table', "mixin must be a table") | |
| for name,method in pairs(mixin) do | |
| if name ~= "included" and name ~= "static" then aClass[name] = method end | |
| end | |
| if mixin.static then | |
| for name,method in pairs(mixin.static) do | |
| aClass.static[name] = method | |
| end | |
| end | |
| if type(mixin.included)=="function" then mixin:included(aClass) end | |
| aClass.__mixins[mixin] = true | |
| end | |
| local Object = _createClass("Object", nil) | |
| function Object.static:allocate() | |
| assert(type(self) == 'table', "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'") | |
| return setmetatable({ class = self }, self.__instanceDict) | |
| end | |
| function Object.static:new(...) | |
| local instance = self:allocate() | |
| instance:initialize(...) | |
| return instance | |
| end | |
| function Object.static:subclass(name) | |
| assert(type(self) == 'table', "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'") | |
| assert(type(name) == "string", "You must provide a name(string) for your class") | |
| local subclass = _createClass(name, self) | |
| _setSubclassMetamethods(self, subclass) | |
| _setDefaultInitializeMethod(subclass, self) | |
| self.subclasses[subclass] = true | |
| self:subclassed(subclass) | |
| return subclass | |
| end | |
| function Object.static:subclassed(other) end | |
| function Object.static:isSubclassOf(other) | |
| return type(other) == 'table' and | |
| type(self) == 'table' and | |
| type(self.super) == 'table' and | |
| ( self.super == other or | |
| type(self.super.isSubclassOf) == 'function' and | |
| self.super:isSubclassOf(other) | |
| ) | |
| end | |
| function Object.static:include( ... ) | |
| assert(type(self) == 'table', "Make sure you that you are using 'Class:include' instead of 'Class.include'") | |
| for _,mixin in ipairs({...}) do _includeMixin(self, mixin) end | |
| return self | |
| end | |
| function Object.static:includes(mixin) | |
| return type(mixin) == 'table' and | |
| type(self) == 'table' and | |
| type(self.__mixins) == 'table' and | |
| ( self.__mixins[mixin] or | |
| type(self.super) == 'table' and | |
| type(self.super.includes) == 'function' and | |
| self.super:includes(mixin) | |
| ) | |
| end | |
| function Object:initialize() end | |
| function Object:__tostring() return "instance of " .. tostring(self.class) end | |
| function Object:isInstanceOf(aClass) | |
| return type(self) == 'table' and | |
| type(self.class) == 'table' and | |
| type(aClass) == 'table' and | |
| ( aClass == self.class or | |
| type(aClass.isSubclassOf) == 'function' and | |
| self.class:isSubclassOf(aClass) | |
| ) | |
| end | |
| function middleclass.class(name, super, ...) | |
| super = super or Object | |
| return super:subclass(name, ...) | |
| end | |
| middleclass.Object = Object | |
| setmetatable(middleclass, { __call = function(_, ...) return middleclass.class(...) end }) | |
| local random = function() | |
| return js.global:Random() | |
| end | |
| local abs = function(n) | |
| return js.global:abs(n) | |
| end | |
| local floor = function(n) | |
| return js.global:floor(n) | |
| end | |
| local PI = js.global:PI() | |
| local cos = function(n) return js.global:cos(n) end | |
| local sin = function(n) return js.global:sin(n) end | |
| local atan2 = function(a,b) return js.global:atan2(a,b) end | |
| local Screen = {width=480, height=480} | |
| local class = middleclass | |
| local Vector = class('Vector') | |
| function Vector:initialize(_x, _y) | |
| self.x = _x or 0 | |
| self.y = _y or 0 | |
| end | |
| local drawRect = function(r,g,b,x,y,w,h) | |
| js.global:drawRect(r, g, b, x*Screen.width, y*Screen.height, Screen.width*w, Screen.height*w) | |
| end | |
| function Vector:set(v) | |
| if not v then return end | |
| self.x = v.x | |
| self.y = v.y | |
| end | |
| function Vector:addDirection(degrees, speed) | |
| local s = speed or 100 | |
| local rad = degrees * js.global:PI()/180 | |
| self.x = self.x + js.global:sin(rad)*s | |
| self.y = self.y - js.global:cos(rad)*s | |
| end | |
| function Vector:directionTo(v) | |
| return atan2(v.x - self.x, -(v.y - self.y)) * 180 / PI | |
| end | |
| function Vector:add(v) | |
| self.x = self.x + v.x | |
| self.y = self.y + v.y | |
| return self | |
| end | |
| function Vector:div(n) | |
| if n == 0 then return self; end | |
| self.x = self.x / n | |
| self.y = self.y / n | |
| return self | |
| end | |
| function Vector:onScreen() | |
| return self.x >= 0 and self.x <= 1 and self.y >= 0 and self.y <= 1 | |
| end | |
| function Vector:rotate(amt) | |
| if amt == 0 then return; end | |
| amt = amt * PI / 180 | |
| local ox = self.x | |
| self.x = self.x*cos(amt) - self.y * sin(amt) | |
| self.y = ox*sin(amt) + self.y * cos(amt) | |
| end | |
| local Color = class('Color') | |
| function Color:initialize(_r,_g,_b) | |
| self.r = _r or 0 | |
| self.g = _g or 0 | |
| self.b = _b or 0 | |
| end | |
| function Color:copy() | |
| return Color:new(self.r, self.g, self.b) | |
| end | |
| function Color:set(r,g,b) | |
| self.r = r | |
| self.g = g | |
| self.b = b | |
| end | |
| Color.static.white = Color:new(1,1,1) | |
| Color.static.red = Color:new(1,0,0) | |
| local DrawingRect = class('DrawingRect') | |
| function DrawingRect:initialize(_color, offset, _size) | |
| self.color = _color or Color:new() | |
| self.offset = offset or Vector:new() | |
| self.size = _size or Vector:new() | |
| self.currentPosition = Vector:new() | |
| end | |
| function DrawingRect:draw(drawing) | |
| self:updateState(drawing) | |
| local xPos = Screen.width*(self.currentPosition.x) | |
| local yPos = Screen.height*(self.currentPosition.y) | |
| js.global:drawRect(self.color.r, self.color.g, self.color.b, xPos, yPos, Screen.width*self.size.x, Screen.height*self.size.y) | |
| end | |
| function DrawingRect:updateState(drawing) | |
| -- copy out the information that we need to draw with | |
| self.currentPosition:set(self.offset) | |
| self.currentPosition:rotate(drawing.rotation) | |
| self.currentPosition:add(drawing.position) | |
| end | |
| function DrawingRect:isOverlapping(rect) | |
| return | |
| abs(self.currentPosition.x - rect.currentPosition.x) < | |
| (self.size.x + rect.size.x) / 2 and | |
| abs(self.currentPosition.y - rect.currentPosition.y) < | |
| (self.size.y + rect.size.y) / 2 | |
| end | |
| local Drawing = class('Drawing'); | |
| function Drawing:initialize() | |
| self.color = Color:new(1,1,1); | |
| self.rects = {} | |
| self.position = Vector:new() | |
| self.rotation = 0 | |
| end | |
| function Drawing:setColor(r, g, b) | |
| self.color:set(r,g,b) | |
| return self | |
| end | |
| function Drawing:addRect(_x,_y,_w,_h) | |
| table.insert(self.rects, DrawingRect:new(self.color:copy(), Vector:new(_x,_y), Vector:new(_w, _h))) | |
| return self | |
| end | |
| -- generates a set of rects that can look like a rotated square | |
| function Drawing:addRects(width, height) | |
| local directionAmount = 0 | |
| local ox = 0 | |
| local oy = 0 | |
| if width > height then | |
| directionAmount = directionAmount + PI / 2 | |
| local tw = width | |
| width = height | |
| height = tw | |
| end | |
| local n = floor(height / width) | |
| local o = -width * (n - 1) / 2 | |
| local vo = width | |
| width = width * 1.05 | |
| for i=1,n do | |
| local rp = Vector:new(sin(directionAmount) * o + ox, cos(directionAmount) * o + oy) | |
| table.insert(self.rects, DrawingRect:new( | |
| self.color:copy(), | |
| rp, | |
| Vector:new(width, width) | |
| )) | |
| o = o + vo | |
| end | |
| return self | |
| end | |
| function Drawing:draw() | |
| for i,v in ipairs(self.rects) do | |
| v:draw(self) | |
| end | |
| end | |
| function Drawing:setPosition(position) | |
| self.position:set(position) | |
| return self | |
| end | |
| function Drawing:setRotation(rotation) | |
| self.rotation = rotation | |
| return self | |
| end | |
| function Drawing:isOverlapping(otherDrawing) | |
| for i,ourRect in ipairs(self.rects) do | |
| for j,otherRect in ipairs(otherDrawing.rects) do | |
| if ourRect:isOverlapping(otherRect) then return true end | |
| end | |
| end | |
| return false | |
| end | |
| local Fiber = class('Fiber') | |
| Fiber.static.fibers = {} | |
| Fiber.static.update = function() | |
| for i,v in ipairs(Fiber.fibers) do | |
| v:update() | |
| end | |
| end | |
| function Fiber:initialize(fiberGroup) | |
| self.functions = {} | |
| self.functionCount = 0 | |
| self.currentFunction = 1 | |
| self.waitTicks = 0 | |
| fiberGroup = fiberGroup or Fiber.fibers | |
| table.insert(fiberGroup, self) | |
| end | |
| function Fiber:doOnce(func) | |
| table.insert(self.functions, function() | |
| func() | |
| self:gotoNext() | |
| end) | |
| self.functionCount = self.functionCount + 1 | |
| return self | |
| end | |
| function Fiber:doRepeat(func) | |
| table.insert(self.functions, func) | |
| self.functionCount = self.functionCount + 1 | |
| return self | |
| end | |
| function Fiber:gotoNext() | |
| self.currentFunction = self.currentFunction + 1 | |
| if self.currentFunction > self.functionCount then | |
| self.currentFunction = 1 | |
| end | |
| end | |
| function Fiber:wait(ticks) | |
| table.insert(self.functions, function() | |
| self.waitTicks = ticks | |
| self:gotoNext() | |
| end) | |
| self.functionCount = self.functionCount + 1 | |
| return self | |
| end | |
| function Fiber:update() | |
| if self.functionCount == 0 then | |
| return | |
| end | |
| if self.waitTicks > 0 then | |
| self.waitTicks = self.waitTicks - 1 | |
| return | |
| end | |
| self.functions[self.currentFunction]() | |
| end | |
| local Actor = class('Actor') | |
| Actor.static.groups = {} | |
| Actor.static.number = 10 | |
| Actor.static.update = function() | |
| Actor.static.number = 0 | |
| for i,group in ipairs(Actor.groups) do | |
| for j, actor in ipairs(group.contents) do | |
| Actor.static.number = Actor.static.number + 1 | |
| actor:preupdate() | |
| actor:update() | |
| actor:draw() | |
| end | |
| end | |
| end | |
| Actor.static.scroll = function(GroupName, ox, oy, minX, minY, maxX, maxY) | |
| for i,group in ipairs(Actor.groups) do | |
| if group.groupName == GroupName then | |
| for j, actor in ipairs(group.contents) do | |
| if actor.position.x < minX then | |
| actor.position.x = maxX | |
| end | |
| if actor.position.y < minY then | |
| actor.position.y = maxY | |
| end | |
| if actor.position.x > maxX then | |
| actor.position.x = minX | |
| end | |
| if actor.position.y > maxY then | |
| actor.position.y = minY | |
| end | |
| actor.position.x = actor.position.x + ox | |
| actor.position.y = actor.position.y + oy | |
| end | |
| break; | |
| end | |
| end | |
| end | |
| function Actor:initialize(...) | |
| arg = {...} | |
| local myClass = self.class.name | |
| for i,v in pairs(Actor.groups) do | |
| if v.groupName == myClass then | |
| self.group = v.contents | |
| end | |
| end | |
| if not self.group then | |
| local tempGroup = {groupName = myClass, contents={}} | |
| table.insert(Actor.groups, tempGroup) | |
| self.group = tempGroup.contents | |
| end | |
| self.fibers = {} | |
| self.position = Vector:new(0.5,0.5) | |
| self.velocity = Vector:new(0,0) | |
| self.drawing = Drawing:new() | |
| self.rotation = 0 | |
| self.ticks = 0 | |
| table.insert(self.group, self) | |
| if self.init then | |
| if ... then | |
| self:init(unpack(arg)) | |
| else | |
| self:init() | |
| end | |
| end | |
| end | |
| function Actor:newFiber() | |
| return Fiber:new(self.fibers) | |
| end | |
| function Actor:draw() | |
| self.drawing:draw(self.position) | |
| end | |
| function Actor:preupdate() | |
| self.ticks = self.ticks + 1 | |
| self.position:add(self.velocity) | |
| self.drawing:setPosition(self.position):setRotation(self.rotation); | |
| -- update the objects that are attached to this actor | |
| for i,v in pairs(self.fibers) do | |
| v:update() | |
| end | |
| end | |
| function Actor:update() | |
| end | |
| function Actor:remove() | |
| for i,v in ipairs(self.group) do | |
| if v == self then | |
| table.remove(self.group, i) | |
| break; | |
| end | |
| end | |
| end | |
| function Actor:onCollision(otherClass, callback) | |
| -- get the group we are colliding with | |
| for i,group in ipairs(Actor.groups) do | |
| if group.groupName == otherClass then | |
| for j,actor in ipairs(group.contents) do | |
| if self.drawing:isOverlapping(actor.drawing) then | |
| -- if not callback then return true end | |
| if not callback then | |
| return true; | |
| else | |
| end | |
| end | |
| end | |
| return false; | |
| end | |
| end | |
| end | |
| local ParticleActor = class('ParticleActor', Actor) | |
| function ParticleActor:init() | |
| self.duration = 2 | |
| self.color = Color:new(1,1,1) | |
| self.size = Vector:new(0.01, 0.01) | |
| end | |
| function ParticleActor:update() | |
| -- if this particle is requesting a spawn | |
| if self.particleSpawner then | |
| local spawner = self.particleSpawner | |
| self:remove() | |
| if spawner.number < 1 then return end | |
| for i=1,spawner.number do | |
| -- generate all the particles we need | |
| local pActor = ParticleActor:new() | |
| pActor.position:set(spawner.position) | |
| pActor.size = Vector:new(spawner.size, spawner.size) | |
| -- calculate velocity based on direction | |
| local d = spawner.direction + (random()*spawner.directionSpread)-(spawner.directionSpread*0.5) | |
| pActor.velocity:addDirection(d, spawner.speed) | |
| pActor.duration = spawner.duration | |
| pActor.color = spawner.color | |
| end | |
| return | |
| end | |
| -- otherwise, just update the particle | |
| -- we have to manually draw, since particles don't have graphics attached to them | |
| local xPos = Screen.width*(self.position.x) | |
| local yPos = Screen.height*(self.position.y) | |
| js.global:drawRect(self.color.r, self.color.g, self.color.b, xPos, yPos, Screen.width*self.size.x, Screen.height*self.size.y) | |
| if self.ticks >= self.duration then | |
| self:remove() | |
| end | |
| end | |
| local Particle = class('Particle') | |
| function Particle:initialize() | |
| self.actor = ParticleActor:new() | |
| self.actor.particleSpawner = self | |
| self.duration = 10 | |
| self.direction = 0 | |
| self.size = 0.02 | |
| self.directionSpread = 360 | |
| self.speed = 0.01 | |
| self.number = 5 | |
| self.position = Vector:new() | |
| self.color = Color:new() | |
| end | |
| function Particle:setNumber(count) | |
| self.number = count | |
| return self | |
| end | |
| function Particle:duration(time) | |
| self.duration = time | |
| return self | |
| end | |
| function Particle:setPosition(position) | |
| self.position:set(position) | |
| return self | |
| end | |
| function Particle:setDirection(direction, spread) | |
| self.direction = direction | |
| self.directionSpread = spread or 30 | |
| return self | |
| end | |
| function Particle:setSpeed(speed) | |
| self.speed = speed | |
| return self | |
| end | |
| function Particle:setColor(r,g,b) | |
| self.color:set(r,g,b) | |
| return self | |
| end | |
| function Actor:newParticle() | |
| return Particle:new():setPosition(self.position) | |
| end | |
| local Mouse = class('Mouse') | |
| Mouse.static.position = Vector:new() | |
| function mouseMove(x,y) | |
| Mouse.position.x = x | |
| Mouse.position.y = y | |
| end | |
| local Letter = class('Letter') | |
| Letter.static.dots = {} | |
| Letter.static.drawDots = function(letter, x,y,color,size) | |
| if not Letter.dots[letter] then | |
| Letter.dots[letter] = {} | |
| local letterBitCount = js.global:getDotCountForLetter(letter) | |
| for i=0,letterBitCount-1 do | |
| local px = js.global:getDotPositionForLetter(letter,i,0) | |
| local py = js.global:getDotPositionForLetter(letter,i,1) | |
| table.insert(Letter.dots[letter], {x = px, y=py}) | |
| end | |
| end | |
| for i,v in ipairs(Letter.dots[letter]) do | |
| drawRect(color.r, color.b, color.g, | |
| x + v.x * size, | |
| y + v.y * size, | |
| size, | |
| size) | |
| end | |
| end | |
| Letter.static.draw = function(text, x,y, color, scale) | |
| local letterWidth = scale * 5 | |
| local tx = x | |
| local ty = y | |
| for i=1,#text do | |
| local c = text:sub(i,i) | |
| Letter.drawDots(c, tx, ty, color, scale) | |
| tx = tx+letterWidth | |
| end | |
| end | |
| local TextActor = class('TextActor', Actor) | |
| function TextActor:init(text) | |
| self.text = text | |
| self.duration = 1 | |
| self.size = 0.02 | |
| end | |
| function TextActor:draw() | |
| if self.ticks == 0 then | |
| self.velocity:div(self.duration) | |
| end | |
| Letter.draw(self.text, self.position.x, self.position.y, self.color, self.size) | |
| if self.ticks >= self.duration then | |
| self:remove() | |
| end | |
| end | |
| -- END STDLIB | |
| -- this is the thing that runs the whole game | |
| function drawFrame() | |
| js.global:drawRect(0,0,0,240,240,480,480) | |
| Actor.update() | |
| Fiber.update() | |
| Actor.scroll('Star', 0,0, 0,0, 1,1) | |
| print(Actor.number) | |
| Letter.draw("ACTORS: " .. Actor.static.number, 0,0,Color.white, 0.005) | |
| -- Letter.draw("BRO", 0.5, 0.5, Color.red, 0.02) | |
| -- we are just going to force draw a letter now, just for fun | |
| end | |
| local Star = class('Star', Actor) | |
| function Star:init() | |
| self.position.x = js.global:Random() | |
| self.position.y = js.global:Random() | |
| local c = js.global:Random() | |
| self.speed = c*0.005 | |
| self.drawing:setColor(c*1.5,c*1.5,c*1.5):addRect(0,0, 0.01*c, 0.01*c) | |
| end | |
| function Star:update() | |
| self.position.y = self.position.y+self.speed | |
| end | |
| local Shot = class('Shot', Actor) | |
| function Shot:initialize(...) | |
| Actor.initialize(self, ...) -- invoking the superclass' initializer | |
| end | |
| function Shot:init(position) | |
| self.drawing:setColor(1, 0,0) | |
| :addRect(-0.02, 0.02, 0.02, 0.04) | |
| :addRect(0.02, 0.02, 0.02, 0.04) | |
| self.position:set(position) | |
| self.velocity = Vector:new(0,-0.03) | |
| end | |
| function Shot:update() | |
| if not self.position:onScreen() then | |
| self:remove() | |
| end | |
| end | |
| local Ship = class('Ship', Actor) | |
| function Ship:init() | |
| self.position.x = 0.5 | |
| self.position.y = 0.8 | |
| self.drawing:setColor(1, 0,0) | |
| :addRect(-0.02, 0.02, 0.02, 0.04) | |
| :addRect(0.02, 0.02, 0.02, 0.04) | |
| :setColor(1, 1, 1) | |
| :addRect(0,0, 0.02, 0.05) | |
| self:newFiber() | |
| :doOnce(function() | |
| Shot:new(self.position) | |
| self:addMuzzleFlash(-0.02) | |
| self:addMuzzleFlash(0.02) | |
| end) | |
| :wait(3) | |
| end | |
| function Ship:addMuzzleFlash(offsetX) | |
| self:newParticle() | |
| :setPosition(Vector:new(self.position.x+offsetX, self.position.y)) | |
| :setNumber(3) | |
| :setDirection(0, 30) | |
| :setSpeed(0.02) | |
| :setColor(1, 0, 0) | |
| end | |
| function Ship:update() | |
| -- self.position.y = self.position.y + 0.01 | |
| self.position.x = Mouse.position.x | |
| self.position.y = Mouse.position.y | |
| end | |
| for i=0,30 do | |
| local s = Star:new() | |
| end | |
| local ship = Ship:new() | |
| local Bullet = class('Bullet', Actor) | |
| function Bullet:init(position) | |
| self.position:set(position) | |
| local angle = self.position:directionTo(ship.position) | |
| self.velocity:addDirection(angle, 0.015) | |
| self.drawing:setColor(1,1,1) | |
| :addRects(0.02, 0.04) | |
| :addRects(0.04, 0.02) | |
| end | |
| function Bullet:update() | |
| self.rotation = self.rotation + 3 | |
| if not self.position:onScreen() then self:remove() end | |
| end | |
| local Enemy = class('Enemy', Actor) | |
| function Enemy:init() | |
| self.position.x = js.global:Random() | |
| self.position.y = 0 | |
| self.drawing:setColor(1, 1,0) | |
| :addRect(-0.02, -0.02, 0.02, 0.04) | |
| :addRect(0.02, -0.02, 0.02, 0.04) | |
| :addRect(0,0, 0.02, 0.05) | |
| self:newFiber() | |
| :doOnce(function() | |
| Bullet:new(self.position) | |
| end) | |
| :wait(30) | |
| end | |
| function Enemy:update() | |
| self.position.y = self.position.y + 0.01 | |
| if self.position.y > 1 then | |
| self:remove() | |
| end | |
| if self:onCollision('Shot') then | |
| local ta = TextActor:new("+1") | |
| ta.color = Color:new(1,1,1) | |
| ta.duration = 30 | |
| ta.size = 0.005 | |
| ta.position:set(self.position) | |
| ta.velocity:set(Vector:new(0,-0.01)) | |
| self:remove() | |
| self:newParticle() | |
| :setColor(1,1,0) | |
| :setNumber(5) | |
| end | |
| end | |
| Fiber:new() | |
| :doOnce(function() | |
| Enemy:new() | |
| end) | |
| :wait(30) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment