diff --git a/cherry/engine/camera.lua b/cherry/engine/camera.lua deleted file mode 100644 index 59ab810..0000000 --- a/cherry/engine/camera.lua +++ /dev/null @@ -1,127 +0,0 @@ --------------------------------------------------------------------------------- - -local _ = require 'cherry.libs.underscore' - -local Camera = { - options = {}, - display = display.newGroup(), - zoom = 1 -} - --------------------------------------------------------------------------------- - -local INIT_X = display.contentWidth * 0.5 -local INIT_Y = display.contentHeight * 0.5 - --------------------------------------------------------------------------------- - -local xShake = 16 -local yShake = 8 -local shakePeriod = 2 - --------------------------------------------------------------------------------- - -function Camera:insert(stuff) - self.display:insert(stuff) -end - -function Camera:localToContent(x, y) - self.display:localToContent(x, y) -end - --------------------------------------------------------------------------------- - -function Camera:empty() - display.remove(self.display) - self.display = display.newGroup() -end - --------------------------------------------------------------------------------- - -function Camera:resetZoom() - self.zoom = 1 -end - --------------------------------------------------------------------------------- - -function Camera:toHUD(vector) - local alpha = math.rad(Camera.display.rotation) - local cameraX = vector.x * Camera.zoom - local cameraY = vector.y * Camera.zoom - - local x = cameraX * math.cos(alpha) - cameraY * math.sin(alpha) - local y = cameraX * math.sin(alpha) + cameraY * math.cos(alpha) - - return x + Camera.display.x, y + Camera.display.y -end - --------------------------------------------------------------------------------- - --- INIT_X,Y should be defined by the current level offset from level[0,0] --- default for Doors : not offset = the center of the screen = level[0,0] -function Camera:center() - self.display.x = INIT_X - self.display.y = INIT_Y - - -- reset then apply - self.display.xScale = 1 - self.display.yScale = 1 - self.display:scale(self.zoom, self.zoom) -end - --------------------------------------------------------------------------------- - -function Camera:start(options) - self.options = _.extend(self.options, options) - transition.cancel(self.display) - self.display.alpha = 1 - App.hud:toFront() - - self.moveDisplay = function() - if (self.shakeCount % shakePeriod == 0) then - self.display.x = self.display.x0 + math.random(-xShake, xShake) - self.display.y = self.display.y0 + math.random(-yShake, yShake) - end - self.shakeCount = self.shakeCount + 1 - end - - self.startShake = function() - self.display.x0 = self.display.x - self.display.y0 = self.display.y - self.shakeCount = 0 - Runtime:addEventListener('enterFrame', self.moveDisplay) - end - - self.stopShake = function() - Runtime:removeEventListener('enterFrame', self.moveDisplay) - self.display.x = INIT_X - self.display.y = INIT_Y - self.shaking = false - end -end - -function Camera:shake() - if (self.shaking) then - timer.cancel(self.shaking) - self.stopShake() - end - - self.startShake() - self.shaking = timer.performWithDelay(250, self.stopShake) -end - -function Camera:stop() - transition.to( - self.display, - { - alpha = 0, - time = 500, - xScale = 0.01, - yScale = 0.01 - } - ) -end - --------------------------------------------------------------------------------- - -return Camera diff --git a/cherry/engine/effects.lua b/cherry/engine/effects.lua deleted file mode 100644 index 3f40368..0000000 --- a/cherry/engine/effects.lua +++ /dev/null @@ -1,166 +0,0 @@ --------------------------------------------------------------------------------- - -local Effects = { - effects = {}, -} - -local nbDestroyed = 0 -local nbRunning = 0 - --------------------------------------------------------------------------------- - -function Effects:start() - self:startAllEffects() -end - -function Effects:pause() - -- Runtime:removeEventListener( 'enterFrame', refreshEffects ) -end - -function Effects:stop(now) - self:pause() - - if(self.effects) then - while #self.effects > 0 do - self:destroyEffect(self.effects[1]) - end - end - - self.effects = {} - nbDestroyed = 0 - nbRunning = 0 -end - -function Effects:restart() - self:pause(true) - self:start() -end - --------------------------------------------------------------------------------- --- for static views : no refresh required -function Effects:startAllEffects() - if(self.effects) then - for i=1,#self.effects do - self:startEffect(self.effects[i]) - end - end -end - --------------------------------------------------------------------------------- - -function Effects:registerNewEffect( effect ) - effect.num = #self.effects+1 - self.effects[effect.num] = effect -end - --------------------------------------------------------------------------------- - -function Effects:startEffect( effect ) - if(not effect.started) then - effect:start() - effect.started = true - - --- debug - nbRunning = nbRunning + 1 - end -end - --------------------------------------------------------------------------------- - -function Effects:stopEffect( effect ) - effect:stop() - effect.started = false - - --- debug - nbRunning = nbRunning - 1 -end - --------------------------------------------------------------------------------- - -function Effects:destroyEffect( effect, now ) - table.removeObject(self.effects, effect) - effect:destroy() - - nbDestroyed = nbDestroyed + 1 -end - --------------------------------------------------------------------------------- - -function Effects:destroyObjectWithEffect(body) - if(body.effect) then - return self:destroyEffect(body.effect) - else - return false - end -end - --------------------------------------------------------------------------------- ---- Menu Atmospheres --------------------------------------------------------------------------------- - -function Effects:atmosphere(parent, x, y, scale) - local effect = CBE.newVent({ - preset = 'wisps', - emitX = x, - emitY = y - }) - - self:registerNewEffect(effect) - parent:insert(effect) - return effect -end - ------------------------------------------------------------------------------ ---- Explosion ------------------------------------------------------------------------------ - -function Effects:explosion(parent, x, y) - local vent = CBE.newVent({ - preset = 'wisps', - title = 'explosion', - scale = 1.7, - positionType = 'inRadius', - color = {{1, 1, 0}, {1, 0.5, 0}, {0.2, 0.2, 0.2}}, - particleProperties = {blendMode = 'add'}, - emitX = x, - emitY = y, - - emissionNum = 3, - emitDelay = 15, - perEmit = 2, - - inTime = 100, - lifeTime = 0, - outTime = 200, - - onCreation = function(particle) - particle:changeColor({ - color = {0.1, 0.1, 0.1}, - time = 500 - }) - end, - - onUpdate = function(particle) - particle:setCBEProperty(' scaleRateX' , particle:getCBEProperty('scaleRateX' ) * 0.998) - particle:setCBEProperty(' scaleRateY' , particle:getCBEProperty('scaleRateY' ) * 0.998) - end, - - physics = { - velocity = 0, - gravityY = -0.035, - scaleRateX = 1, - scaleRateY = 1, - autoCalculateAngles = true, - angles = {{60, 120}, {120, 60}}, -- Add angles in form of 60-120-60 - cycleAngle = true - } - }) - - self:registerNewEffect(vent) - parent:insert(vent) - self:restart() -end - --------------------------------------------------------------------------------- - -return Effects diff --git a/cherry/engine/game.lua b/cherry/engine/game.lua index bb797f2..37596d8 100644 --- a/cherry/engine/game.lua +++ b/cherry/engine/game.lua @@ -2,7 +2,6 @@ local Background = require 'cherry.components.background' local Screen = require 'cherry.components.screen' -local Effects = require 'cherry.engine.effects' local colorize = require 'cherry.libs.colorize' local _ = require 'cherry.libs.underscore' @@ -18,6 +17,7 @@ function Game:new(extension) extension, { isRunning = false, + camera = nil, preset = {}, -- may be used to set a preset data during `resetState` state = {}, elements = {} @@ -29,18 +29,66 @@ function Game:new(extension) end -------------------------------------------------------------------------------- +-- these should be implemented by extension function Game:initialState() return {} end + function Game:resetState() self.state = self:initialState() end + +function Game:resetElements() + self.elements = {} +end + +-------------------------------------------------------------------------------- + function Game:getState() return self.state end -function Game:resetElements() - self.elements = {} + +-------------------------------------------------------------------------------- + +function Game:resetCamera() + if (self.camera) then + display.remove(self.camera) + end + + self.camera = display.newGroup() + App.reorderLayers() +end + +function Game:removeCamera() + transition.to( + self.camera, + { + alpha = 0, + time = 500, + xScale = 0.01, + yScale = 0.01, + x = W / 2, + y = H / 2, + onComplete = function() + display.remove(self.camera) + end + } + ) +end + +function Game:growCamera() + transition.from( + self.camera, + { + alpha = 0, + time = 500, + xScale = 0.01, + yScale = 0.01, + x = W / 2, + y = H / 2 + } + ) end -------------------------------------------------------------------------------- @@ -48,20 +96,20 @@ end -------------------------------------------------------------------------------- function Game:reset() - display.remove(App.hud) - App.hud = display.newGroup() - if (self.onReset) then self:onReset() end -- from extension - Camera:empty() self:resetState() self:resetElements() + self:resetCamera() + App.score:reset() self.preset = {} -- by now preset should have been used to init state and can be reset end +-------------------------------------------------------------------------------- + function Game:run() self.isRunning = true @@ -71,19 +119,13 @@ function Game:run() _G.physics.setGravity(App.xGravity, App.yGravity) end - Camera:resetZoom() - Camera:center() - Camera:start() - + self:growCamera() Background:darken() if (self.onRun) then self:onRun() end -- from extension - if (_G.CBE) then - Effects:restart() - end print('Game runs.') end @@ -140,12 +182,8 @@ function Game:stop(noScore) ------------------------------------------ + self:removeCamera() Background:lighten() - if (_G.CBE) then - Effects:stop(true) - end - - Camera:stop() end -------------------------------------------------------------------------------- diff --git a/cherry/main.lua b/cherry/main.lua index 41b5ca2..7efc905 100644 --- a/cherry/main.lua +++ b/cherry/main.lua @@ -1,5 +1,5 @@ -------------------------------------------------------------------------------- -_G.CHERRY_VERSION = '3.1.0' +_G.CHERRY_VERSION = '3.2.0' -------------------------------------------------------------------------------- -- debug require 'cherry.libs.logger' @@ -19,8 +19,6 @@ _G.App = require 'cherry.core.app' _G.Router = require 'cherry.core.router' -- engine -_G.Camera = require 'cherry.engine.camera' -_G.Effects = require 'cherry.engine.effects' _G.Game = require 'cherry.engine.game' _G.Sound = require 'cherry.engine.sound' diff --git a/docs/camera-shaking.md b/docs/camera-shaking.md new file mode 100644 index 0000000..92dadd9 --- /dev/null +++ b/docs/camera-shaking.md @@ -0,0 +1,43 @@ +backup camera shaking. + +```lua +function Camera:start(options) + _G.log('🔴 Camera is DEPRECATED! use App.game.camera instead.') + self.options = _.extend(self.options, options) + transition.cancel(self.display) + self.display.alpha = 1 + App.hud:toFront() + + self.moveDisplay = function() + if (self.shakeCount % shakePeriod == 0) then + self.display.x = self.display.x0 + math.random(-xShake, xShake) + self.display.y = self.display.y0 + math.random(-yShake, yShake) + end + self.shakeCount = self.shakeCount + 1 + end + + self.startShake = function() + self.display.x0 = self.display.x + self.display.y0 = self.display.y + self.shakeCount = 0 + Runtime:addEventListener('enterFrame', self.moveDisplay) + end + + self.stopShake = function() + Runtime:removeEventListener('enterFrame', self.moveDisplay) + self.display.x = INIT_X + self.display.y = INIT_Y + self.shaking = false + end +end + +function Camera:shake() + if (self.shaking) then + timer.cancel(self.shaking) + self.stopShake() + end + + self.startShake() + self.shaking = timer.performWithDelay(250, self.stopShake) +end +``` diff --git a/readme.md b/readme.md index d7bc7a0..aa8f830 100644 --- a/readme.md +++ b/readme.md @@ -98,6 +98,17 @@ A typical tree should be : ## Using Cherry +### Layers + +from back to front: + +- `Background`: global to the app, not reset by Router +- `App.transversalBackLayer`: global to the app, not reset by Router +- `self.view`: local to current composer view +- `App.transversalFrontLayer`: global to the app, not reset by Router +- `App.hud`: local to each view, reset by Router + Game.elements use `App.hud` as parent, and allow cross callbacks. + ### Adding a new Screen A `Screen` implements the [Composer](https://docs.coronalabs.com/daily/api/library/composer/index.html) library.