From 47b297719162b184f6e8bd83b037d086dcfc7b91 Mon Sep 17 00:00:00 2001 From: dsc Date: Sat, 26 Mar 2011 06:36:49 -0700 Subject: [PATCH] Adds ShieldGenerator item. --- data/types/items.yaml | 8 +- data/types/levels.yaml | 4 +- data/types/loots.yaml | 3 +- src/tanks/index.js | 1 + src/tanks/inventory/bag.cjs | 2 +- src/tanks/inventory/inventory.cjs | 2 +- src/tanks/inventory/loot.cjs | 2 +- src/tanks/item/index.cjs | 8 ++ src/tanks/item/item.cjs | 239 +++++++++++++++++++++++++++++++++++++ src/tanks/item/shieldgen.cjs | 81 +++++++++++++ src/tanks/map/level.cjs | 2 +- src/tanks/mixins/inventoried.cjs | 2 +- src/tanks/thing/index.cjs | 2 - src/tanks/thing/item.cjs | 239 ------------------------------------- src/tanks/thing/player.cjs | 15 --- src/tanks/thing/shield.cjs | 2 +- 16 files changed, 346 insertions(+), 266 deletions(-) create mode 100644 src/tanks/item/index.cjs create mode 100644 src/tanks/item/item.cjs create mode 100644 src/tanks/item/shieldgen.cjs delete mode 100644 src/tanks/thing/item.cjs diff --git a/data/types/items.yaml b/data/types/items.yaml index df1816b..b11c909 100644 --- a/data/types/items.yaml +++ b/data/types/items.yaml @@ -1,6 +1,6 @@ name: items defaults: - symbol: tanks/thing/item.Item + symbol: tanks/item/item.Item desc: '' # projectile: 'normal' passives: [] @@ -50,3 +50,9 @@ types: art: map_icon: '/img/items/rockets-bg-25x25.png' inv_icon: '/img/items/rockets-50x50.png' + shield_gen: + name: Shield Generator + desc: 'Generates four rotating shield spheres, each of which absorbs one impact.' + tags: [ 'armor' ] + symbol: tanks/item/shieldgen.ShieldGenerator + diff --git a/data/types/levels.yaml b/data/types/levels.yaml index 537e832..c970003 100644 --- a/data/types/levels.yaml +++ b/data/types/levels.yaml @@ -143,8 +143,8 @@ types: align: 2 loc: [775,325] items: - # - type: rockets # right next to start - # loc: [325,475] + - type: shield_gen # right next to start + loc: [325,475] - type: rockets loc: [75,275] - type: nitro diff --git a/data/types/loots.yaml b/data/types/loots.yaml index ae7c9fe..7c7f835 100644 --- a/data/types/loots.yaml +++ b/data/types/loots.yaml @@ -4,6 +4,7 @@ defaults: types: rich: items: + - 0.2 shield_gen - 0.1 super_armor - - 0.2 rockets - 0.3 nitro + - 0.1 rockets diff --git a/src/tanks/index.js b/src/tanks/index.js index 45a6a5d..c33e71e 100644 --- a/src/tanks/index.js +++ b/src/tanks/index.js @@ -15,6 +15,7 @@ tanks = { 'fx' : require('tanks/fx'), 'mixins' : require('tanks/mixins'), 'inventory' : require('tanks/inventory'), + 'item' : require('tanks/item'), 'map' : require('tanks/map'), 'thing' : require('tanks/thing'), 'ui' : require('tanks/ui'), diff --git a/src/tanks/inventory/bag.cjs b/src/tanks/inventory/bag.cjs index f7ff703..87ad289 100644 --- a/src/tanks/inventory/bag.cjs +++ b/src/tanks/inventory/bag.cjs @@ -2,7 +2,7 @@ var Y = require('Y').Y , evt = require('evt') -, Item = require('tanks/thing/item').Item +, Item = require('tanks/item/item').Item , Container = require('tanks/inventory/container').Container , ContainerUI = require('tanks/ui/containerui').ContainerUI , diff --git a/src/tanks/inventory/inventory.cjs b/src/tanks/inventory/inventory.cjs index c772d34..335dc3a 100644 --- a/src/tanks/inventory/inventory.cjs +++ b/src/tanks/inventory/inventory.cjs @@ -7,7 +7,7 @@ var Y = require('Y').Y , Container = container.Container , ContainerItem = container.ContainerItem , ContainerMeta = container.ContainerMeta -, Item = require('tanks/thing/item').Item +, Item = require('tanks/item/item').Item , Bag = require('tanks/inventory/bag').Bag , BagBag = require('tanks/inventory/bagbag').BagBag , EquipSlot = require('tanks/inventory/equipslot').EquipSlot diff --git a/src/tanks/inventory/loot.cjs b/src/tanks/inventory/loot.cjs index c1dd74d..35bdebf 100644 --- a/src/tanks/inventory/loot.cjs +++ b/src/tanks/inventory/loot.cjs @@ -1,7 +1,7 @@ var Y = require('Y').Y , evt = require('evt') , Speciated = require('ezl/mixins/speciated').Speciated -, Item = require('tanks/thing/item').Item +, Item = require('tanks/item/item').Item , /** diff --git a/src/tanks/item/index.cjs b/src/tanks/item/index.cjs new file mode 100644 index 0000000..36ed43c --- /dev/null +++ b/src/tanks/item/index.cjs @@ -0,0 +1,8 @@ +var Y = require('Y').Y +, item = require('tanks/item/item') +, sg = require('tanks/item/shieldgen') +; +Y.core.extend(exports, { + 'Item' : item.Item, + 'ShieldGenerator' : sg.ShieldGenerator +}); diff --git a/src/tanks/item/item.cjs b/src/tanks/item/item.cjs new file mode 100644 index 0000000..b967801 --- /dev/null +++ b/src/tanks/item/item.cjs @@ -0,0 +1,239 @@ +var Y = require('Y').Y +, op = require('Y/op') +, Event = require('Y/modules/y.event').Event + +, Rect = require('ezl/shape').Rect +, HtmlLayer = require('ezl/layer/html').HtmlLayer +, CooldownGauge = require('ezl/widget').CooldownGauge + +, BoundsType = require('tanks/constants').BoundsType +, Buff = require('tanks/effects/buff').Buff +, Thing = require('tanks/thing/thing').Thing +, Bullet = require('tanks/thing/bullet').Bullet +, ContainerMeta = require('tanks/inventory/container').ContainerMeta + +, ITEM_SIZE = REF_SIZE * 0.5 +, kNull = op.K(null) +, + + +Item = +exports['Item'] = +Thing.subclass('Item', { + // __mixins__ : [ ], + __bind__ : [ 'equip', 'unequip', 'onCollide', 'onAcquired', 'onLost', 'onBuffDeath' ], + isItem : true, + + align : 0, // 0 reserved for neutral units + + blocking : BoundsType.ZONE, + width : ITEM_SIZE, + height : ITEM_SIZE, + + // indestructable + stats : { hp:Infinity, move:0, power:0, speed:0 }, + dealDamage : op.nop, + + // inactive in the event loop + active : false, + + /// Instance Properties /// + name : 'Dummy', // {String} Display name + icon_inv : '', // {String} URL to inventory icon file (TODO) + icon_map : '', // {String} URL to map icon file (TODO) + + projectile : null, // {Class} Bullet species to grant on equip + + // {Buff...} Passive effects (triggered on equip) + passives : Y([]), + + // {Buff...} Active effects (triggered on activation) + effects : Y([]), + + owner : null, // {Unit} Owner when picked up. + currentBuffs : null, // {Buff...} Buffs applied to owner + inv : null, // {ContainerMeta} Inventory Bookkeeping + + isEquipped : false, + + + init : function initItem(){ + Thing.init.call(this, 0); + + this.effects = this.effects.clone(); + this.passives = this.passives.clone(); + + this.currentBuffs = new Y.YArray(); + this.currentActive = new Y.YArray(); + this.currentPassive = new Y.YArray(); + + this.inv = new ContainerMeta(); + if (this.cooldowns.activate) + this.activateGauge = new CooldownGauge(this.cooldowns.activate, REF_SIZE+1,REF_SIZE+1); + + this.on('collide', this.onCollide); + this.on('item.acquire', this.onAcquired); + this.on('item.lose', this.onLost); + this.on('item.equip', this.equip); + this.on('item.unequip', this.unequip); + }, + + activate : function activate(){ + // console.log(this+' activated!'); + + if ( this.owner && this.cooldowns.activate && this.cooldowns.activate.activate() ) { + var buffs = this.currentBuffs + , active = this.currentActive + ; + if ( active.length ) + active.invoke('die', 'item.reactivated'); + + var activated = this.effects.invoke('instantiate', this.owner); + activated.invoke('on', 'buff.die', this.onBuffDeath); + buffs.extend(activated); + active.extend(activated); + } + return this; + }, + + removeFromMap : function removeFromMap(){ + this.remove(); // removes map object + this.game.map.removeBlocker(this); // remove map zone + }, + + /** + * Equips this item to owner or given unit. Does not manipulate inventory, but does remove from map if newly acquired. + * @param {Tank} [unit=this.owner] Unit to equip. If omitted, uses this.owner; if unowned, does nothing. + * @return {this} + */ + equip : function equip(unit){ + if (unit instanceof Event && unit.data) { + var evt = unit; + unit = evt.data.unit; + } + if (unit && unit.isUnit) { + this.owner = unit; + this.removeFromMap(); + } + + if (!this.owner) + return this; + + this.isEquipped = true; + if ( this.currentPassive.length ) + this.currentPassive.invoke('die', 'item.reequipped'); + + var equipped = this.passives.invoke('instantiate', this.owner); + equipped.invoke('on', 'buff.die', this.onBuffDeath); + this.currentBuffs.extend(equipped); + this.currentPassive.extend(equipped); + + if (this.projectile) + this.owner.projectile = this.projectile; + + return this; + }, + + /** + * Unequips item from owner. + * @return {this} + */ + unequip : function unequip(){ + this.isEquipped = false; + var owner = this.owner + , proj = this.projectile; + if ( owner ) { + this.currentPassive.invoke('die', 'item.unequipped'); + if (proj && proj === owner.projectile) // only reset projectile if it's mine + owner.projectile = owner.defaultProjectile; + } + + return this; + }, + + /// Event Handlers /// + + onCollide : function onCollide(evt){ + var unit = evt.data.unit + , inv = unit.inventory + if ( inv && inv.canAddItem(this) ) { + inv.equipItem(this); + if ( !this.isEquipped ) + inv.addItem(this); // fires 'item.acquire' if successful + } + // TODO: else ignore for this traversal + }, + + onAcquired : function onAcquired(evt, container){ + this.owner = evt.data.unit; + this.removeFromMap(); + }, + + onLost : function onLost(evt){ + var lostItem = evt.data.item + , current = this.currentBuffs + , unit = this.owner + ; + // Bags are Items AND Containers, and are thus sent notifications when + // their contents change. + if (lostItem !== this) + return; + + if ( current.length ) + current.invoke('die', 'item.lost'); + + // console.log(unit+' lost '+this+'!'); + this.owner = null; + + if ( /\blost\.drop\b/.test(evt.type) ) + unit.game.addUnit(this, unit.loc); // TODO: stop item from being instantly picked up, heh. + }, + + onBuffDeath : function onBuffDeath(evt, buff){ + this.currentBuffs.remove(buff); + this.currentActive.remove(buff); + this.currentPassive.remove(buff); + }, + + + /// UI /// + + render : function render(parent){ + this.remove(); + var loc = this.loc + , icon = (this.art||{}).map_icon + ; + + if ( icon ) + this.shape = new HtmlLayer(null, null, '') + .size(this.width, this.height); + else + this.shape = new Rect(this.width, this.height) + .fill('#83BB32') + .stroke('#1C625B', 5.0); + + this.shape + .origin('50%', '50%') + .position(loc.x, loc.y) + .appendTo( parent ); + this.shape.layer.attr('title', ''+loc); + + return this; + }, + + toString : function(){ + return this.className+'(id='+this.id+', owner='+this.owner+')'; + } +}); + +Item.on('speciate', + function onItemSpeciate(evt){ + var NewItem = evt.data.species + , proto = NewItem.fn + ; + proto.passives = Y(proto.passives.map(Buff.lookupOrSpeciate, Buff)); + proto.effects = Y(proto.effects.map(Buff.lookupOrSpeciate, Buff)); + if (proto.projectile) + proto.projectile = Bullet.lookupOrSpeciate(proto.projectile); + }); + diff --git a/src/tanks/item/shieldgen.cjs b/src/tanks/item/shieldgen.cjs new file mode 100644 index 0000000..0911bd6 --- /dev/null +++ b/src/tanks/item/shieldgen.cjs @@ -0,0 +1,81 @@ +var Y = require('Y').Y +, Rect = require('ezl/shape').Rect +, Circle = require('ezl/shape').Circle +, HtmlLayer = require('ezl/layer/html').HtmlLayer + +, Item = require('tanks/item/item').Item +, Shield = require('tanks/thing/shield').Shield + +, SQRT_TWO = Math.sqrt(2) +, TWO_PI = 2 * Math.PI +, + +ShieldGenerator = +exports['ShieldGenerator'] = +Item.subclass('ShieldGenerator', { + colors: { + bg : '#FF6458', + body : '#0A9CFF', + shine : '#195FBC' + }, + + spheres: 4, + + + init : function initShieldGenerator(){ + Item.init.call(this); + this.colors = Y.extend({}, this.colors); + + }, + + onAcquired : function onAcquired(evt, container){ + Item.fn.onAcquired.call(this, evt, container); + + for (var i=0, di = 1/this.spheres; i<1; i += di) { + // Component.init will add it to the owner's bookkeeping + Shield.create('shield', this.owner, i * TWO_PI); + } + }, + + render : function render(parent){ + this.remove(); + var loc = this.loc + , icon = (this.art||{}).map_icon + , d = this.width, r = d * 0.4 + ; + + if ( icon ) + this.shape = new HtmlLayer(null, null, '') + .size(this.width, this.height); + else { + this.shape = new Rect(this.width, this.height) + .fill(this.colors.bg) + // .stroke('#1C625B', 5.0) + ; + + this.body = new Circle(r) + .appendTo( this.shape ) + .origin('50%', '50%') + // .position(0, 0) + .position('50%', '50%') + .fill(this.colors.body) + ; + + // this.shine = new Circle(r) + // .position(r,r) + // .fill(this.colors.shine) + // .eraseCircle(r*0.2,-r*1.5, 1.1*d*SQRT_TWO) + // .appendTo( this.body ); + } + + this.shape + .origin('50%', '50%') + .position(loc.x, loc.y) + .appendTo( parent ); + this.shape.layer.attr('title', ''+loc); + + return this; + } + +}) +; diff --git a/src/tanks/map/level.cjs b/src/tanks/map/level.cjs index 05c8f79..a0e0b53 100644 --- a/src/tanks/map/level.cjs +++ b/src/tanks/map/level.cjs @@ -12,7 +12,7 @@ var Y = require('Y').Y , Map = require('tanks/map/pathing/map').Map , Thing = require('tanks/thing/thing').Thing , Tank = require('tanks/thing/tank').Tank -, Item = require('tanks/thing/item').Item +, Item = require('tanks/item/item').Item , Player = require('tanks/thing/player').Player , Wall = require('tanks/map/wall').Wall , diff --git a/src/tanks/mixins/inventoried.cjs b/src/tanks/mixins/inventoried.cjs index 80f784c..103477d 100644 --- a/src/tanks/mixins/inventoried.cjs +++ b/src/tanks/mixins/inventoried.cjs @@ -3,7 +3,7 @@ var Y = require('Y').Y , deepcopy = require('Y/types/object').deepcopy , Mixin = require('evt').Mixin -, Item = require('tanks/thing/item').Item +, Item = require('tanks/item/item').Item , kNull = op.K(null) , diff --git a/src/tanks/thing/index.cjs b/src/tanks/thing/index.cjs index 004c378..e1b534d 100644 --- a/src/tanks/thing/index.cjs +++ b/src/tanks/thing/index.cjs @@ -1,7 +1,6 @@ var Y = require('Y').Y , bullet = require('tanks/thing/bullet') , component = require('tanks/thing/component') -, item = require('tanks/thing/item') , player = require('tanks/thing/player') , shield = require('tanks/thing/shield') , tank = require('tanks/thing/tank') @@ -10,7 +9,6 @@ var Y = require('Y').Y Y.core.extend(exports, { 'Bullet' : bullet.Bullet, 'Component' : component.Component, - 'Item' : item.Item, 'Player' : player.Player, 'Shield' : shield.Shield, 'Tank' : tank.Tank, diff --git a/src/tanks/thing/item.cjs b/src/tanks/thing/item.cjs deleted file mode 100644 index b967801..0000000 --- a/src/tanks/thing/item.cjs +++ /dev/null @@ -1,239 +0,0 @@ -var Y = require('Y').Y -, op = require('Y/op') -, Event = require('Y/modules/y.event').Event - -, Rect = require('ezl/shape').Rect -, HtmlLayer = require('ezl/layer/html').HtmlLayer -, CooldownGauge = require('ezl/widget').CooldownGauge - -, BoundsType = require('tanks/constants').BoundsType -, Buff = require('tanks/effects/buff').Buff -, Thing = require('tanks/thing/thing').Thing -, Bullet = require('tanks/thing/bullet').Bullet -, ContainerMeta = require('tanks/inventory/container').ContainerMeta - -, ITEM_SIZE = REF_SIZE * 0.5 -, kNull = op.K(null) -, - - -Item = -exports['Item'] = -Thing.subclass('Item', { - // __mixins__ : [ ], - __bind__ : [ 'equip', 'unequip', 'onCollide', 'onAcquired', 'onLost', 'onBuffDeath' ], - isItem : true, - - align : 0, // 0 reserved for neutral units - - blocking : BoundsType.ZONE, - width : ITEM_SIZE, - height : ITEM_SIZE, - - // indestructable - stats : { hp:Infinity, move:0, power:0, speed:0 }, - dealDamage : op.nop, - - // inactive in the event loop - active : false, - - /// Instance Properties /// - name : 'Dummy', // {String} Display name - icon_inv : '', // {String} URL to inventory icon file (TODO) - icon_map : '', // {String} URL to map icon file (TODO) - - projectile : null, // {Class} Bullet species to grant on equip - - // {Buff...} Passive effects (triggered on equip) - passives : Y([]), - - // {Buff...} Active effects (triggered on activation) - effects : Y([]), - - owner : null, // {Unit} Owner when picked up. - currentBuffs : null, // {Buff...} Buffs applied to owner - inv : null, // {ContainerMeta} Inventory Bookkeeping - - isEquipped : false, - - - init : function initItem(){ - Thing.init.call(this, 0); - - this.effects = this.effects.clone(); - this.passives = this.passives.clone(); - - this.currentBuffs = new Y.YArray(); - this.currentActive = new Y.YArray(); - this.currentPassive = new Y.YArray(); - - this.inv = new ContainerMeta(); - if (this.cooldowns.activate) - this.activateGauge = new CooldownGauge(this.cooldowns.activate, REF_SIZE+1,REF_SIZE+1); - - this.on('collide', this.onCollide); - this.on('item.acquire', this.onAcquired); - this.on('item.lose', this.onLost); - this.on('item.equip', this.equip); - this.on('item.unequip', this.unequip); - }, - - activate : function activate(){ - // console.log(this+' activated!'); - - if ( this.owner && this.cooldowns.activate && this.cooldowns.activate.activate() ) { - var buffs = this.currentBuffs - , active = this.currentActive - ; - if ( active.length ) - active.invoke('die', 'item.reactivated'); - - var activated = this.effects.invoke('instantiate', this.owner); - activated.invoke('on', 'buff.die', this.onBuffDeath); - buffs.extend(activated); - active.extend(activated); - } - return this; - }, - - removeFromMap : function removeFromMap(){ - this.remove(); // removes map object - this.game.map.removeBlocker(this); // remove map zone - }, - - /** - * Equips this item to owner or given unit. Does not manipulate inventory, but does remove from map if newly acquired. - * @param {Tank} [unit=this.owner] Unit to equip. If omitted, uses this.owner; if unowned, does nothing. - * @return {this} - */ - equip : function equip(unit){ - if (unit instanceof Event && unit.data) { - var evt = unit; - unit = evt.data.unit; - } - if (unit && unit.isUnit) { - this.owner = unit; - this.removeFromMap(); - } - - if (!this.owner) - return this; - - this.isEquipped = true; - if ( this.currentPassive.length ) - this.currentPassive.invoke('die', 'item.reequipped'); - - var equipped = this.passives.invoke('instantiate', this.owner); - equipped.invoke('on', 'buff.die', this.onBuffDeath); - this.currentBuffs.extend(equipped); - this.currentPassive.extend(equipped); - - if (this.projectile) - this.owner.projectile = this.projectile; - - return this; - }, - - /** - * Unequips item from owner. - * @return {this} - */ - unequip : function unequip(){ - this.isEquipped = false; - var owner = this.owner - , proj = this.projectile; - if ( owner ) { - this.currentPassive.invoke('die', 'item.unequipped'); - if (proj && proj === owner.projectile) // only reset projectile if it's mine - owner.projectile = owner.defaultProjectile; - } - - return this; - }, - - /// Event Handlers /// - - onCollide : function onCollide(evt){ - var unit = evt.data.unit - , inv = unit.inventory - if ( inv && inv.canAddItem(this) ) { - inv.equipItem(this); - if ( !this.isEquipped ) - inv.addItem(this); // fires 'item.acquire' if successful - } - // TODO: else ignore for this traversal - }, - - onAcquired : function onAcquired(evt, container){ - this.owner = evt.data.unit; - this.removeFromMap(); - }, - - onLost : function onLost(evt){ - var lostItem = evt.data.item - , current = this.currentBuffs - , unit = this.owner - ; - // Bags are Items AND Containers, and are thus sent notifications when - // their contents change. - if (lostItem !== this) - return; - - if ( current.length ) - current.invoke('die', 'item.lost'); - - // console.log(unit+' lost '+this+'!'); - this.owner = null; - - if ( /\blost\.drop\b/.test(evt.type) ) - unit.game.addUnit(this, unit.loc); // TODO: stop item from being instantly picked up, heh. - }, - - onBuffDeath : function onBuffDeath(evt, buff){ - this.currentBuffs.remove(buff); - this.currentActive.remove(buff); - this.currentPassive.remove(buff); - }, - - - /// UI /// - - render : function render(parent){ - this.remove(); - var loc = this.loc - , icon = (this.art||{}).map_icon - ; - - if ( icon ) - this.shape = new HtmlLayer(null, null, '') - .size(this.width, this.height); - else - this.shape = new Rect(this.width, this.height) - .fill('#83BB32') - .stroke('#1C625B', 5.0); - - this.shape - .origin('50%', '50%') - .position(loc.x, loc.y) - .appendTo( parent ); - this.shape.layer.attr('title', ''+loc); - - return this; - }, - - toString : function(){ - return this.className+'(id='+this.id+', owner='+this.owner+')'; - } -}); - -Item.on('speciate', - function onItemSpeciate(evt){ - var NewItem = evt.data.species - , proto = NewItem.fn - ; - proto.passives = Y(proto.passives.map(Buff.lookupOrSpeciate, Buff)); - proto.effects = Y(proto.effects.map(Buff.lookupOrSpeciate, Buff)); - if (proto.projectile) - proto.projectile = Bullet.lookupOrSpeciate(proto.projectile); - }); - diff --git a/src/tanks/thing/player.cjs b/src/tanks/thing/player.cjs index aefeea3..af6c56d 100644 --- a/src/tanks/thing/player.cjs +++ b/src/tanks/thing/player.cjs @@ -8,7 +8,6 @@ var Y = require('Y').Y , Tank = require('tanks/thing/tank').Tank , Inventory = require('tanks/inventory/inventory').Inventory , Inventoried = require('tanks/mixins/inventoried').Inventoried -, Shield = require('tanks/thing/shield').Shield , @@ -51,14 +50,6 @@ Tank.subclass('Player', { $('#viewport') .bind('mousedown', this.mousedown) .bind('mouseup', this.mouseup); - - var self = this; - this.game.on('ready', function(){ - for (var i=0; i<1; i += 0.25) { - // Component.init will add it to the owner's bookkeeping - Shield.create('shield', self, i * 2*Math.PI); - } - }); }, destroy : function destroy(){ @@ -72,12 +63,6 @@ Tank.subclass('Player', { return Tank.fn.destroy.call(this); }, - setReplay : function setReplay(replay){ - this.replayMode = true; - this.replay = replay - this.nextMove = replay.shift(); - }, - activeKeys : null, shift : false, ctrl : false, meta : false, alt : false, leftMouse : false, middleMouse : false, rightMouse : false, diff --git a/src/tanks/thing/shield.cjs b/src/tanks/thing/shield.cjs index 3a74f7d..7d3ed53 100644 --- a/src/tanks/thing/shield.cjs +++ b/src/tanks/thing/shield.cjs @@ -91,9 +91,9 @@ Component.subclass('Shield', { this.shine = new Circle(r) .position(r,r) .fill(this.colors.shine) - // .eraseCircle(-r,-r, d*SQRT_TWO) .eraseCircle(r*0.2,-r*1.5, 1.1*d*SQRT_TWO) .appendTo( this.shape ); + return this; } }) -- 1.7.0.4