From 05b6972f7dc59daad8858e2e455422d586cc43d4 Mon Sep 17 00:00:00 2001 From: Sven Slootweg Date: Sun, 4 May 2014 19:42:07 +0200 Subject: [PATCH] Initial commit for CoffeeScript rewrite --- build-games.sh | 7 + compiled/radium.js | 894 +++++++++++++++++++++ gemswap.html | 14 + gemswap/assets/images/diamond.png | Bin 0 -> 3891 bytes gemswap/assets/images/diamond_inverted.png | Bin 0 -> 3886 bytes gemswap/assets/images/diamond_shimmer.png | Bin 0 -> 5430 bytes gemswap/core.coffee | 94 +++ gemswap/gemswap.css | 12 + gemswap/gemswap.js | 85 ++ gemswap/source/diamond.svg | 349 ++++++++ gemswap/source/diamond_inverted.svg | 416 ++++++++++ gemswap/source/diamond_shimmer.svg | 347 ++++++++ radium/000_prepare.coffee | 0 radium/base.coffee | 0 radium/engine.coffee | 106 +++ radium/engine.draw.coffee | 113 +++ radium/engine.random.coffee | 13 + radium/object.coffee | 35 + radium/resource-manager.coffee | 63 ++ radium/scene.coffee | 72 ++ radium/sound.coffee | 1 + radium/sprite.coffee | 12 + radium/tileset.coffee | 30 + radium/util.coffee | 6 + radium/zzz_exports.coffee | 2 + watch.sh | 3 + 26 files changed, 2674 insertions(+) create mode 100755 build-games.sh create mode 100644 compiled/radium.js create mode 100644 gemswap.html create mode 100644 gemswap/assets/images/diamond.png create mode 100644 gemswap/assets/images/diamond_inverted.png create mode 100644 gemswap/assets/images/diamond_shimmer.png create mode 100644 gemswap/core.coffee create mode 100644 gemswap/gemswap.css create mode 100644 gemswap/gemswap.js create mode 100644 gemswap/source/diamond.svg create mode 100644 gemswap/source/diamond_inverted.svg create mode 100644 gemswap/source/diamond_shimmer.svg create mode 100644 radium/000_prepare.coffee create mode 100644 radium/base.coffee create mode 100644 radium/engine.coffee create mode 100644 radium/engine.draw.coffee create mode 100644 radium/engine.random.coffee create mode 100644 radium/object.coffee create mode 100644 radium/resource-manager.coffee create mode 100644 radium/scene.coffee create mode 100644 radium/sound.coffee create mode 100644 radium/sprite.coffee create mode 100644 radium/tileset.coffee create mode 100644 radium/util.coffee create mode 100644 radium/zzz_exports.coffee create mode 100755 watch.sh diff --git a/build-games.sh b/build-games.sh new file mode 100755 index 0000000..341b0e9 --- /dev/null +++ b/build-games.sh @@ -0,0 +1,7 @@ +for f in gemswap/source/*.svg +do + name=${f%%.*} + name=${name##*/} + echo "Processing $f..." + inkscape --export-png=gemswap/assets/images/$name.png $f +done diff --git a/compiled/radium.js b/compiled/radium.js new file mode 100644 index 0000000..259a884 --- /dev/null +++ b/compiled/radium.js @@ -0,0 +1,894 @@ +// Generated by CoffeeScript 1.7.1 +(function() { + var Engine, Object, ResourceManager, Scene, Sound, Sprite, Tileset, TilesetTile, util, + __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __slice = [].slice; + + window.pass = void 0; + + Engine = (function() { + function Engine(resource_manager) { + this.resource_manager = resource_manager; + this.getTileset = __bind(this.getTileset, this); + this.getSprite = __bind(this.getSprite, this); + this.getSound = __bind(this.getSound, this); + this.getObject = __bind(this.getObject, this); + this.getScene = __bind(this.getScene, this); + this.createTileset = __bind(this.createTileset, this); + this.createSprite = __bind(this.createSprite, this); + this.createSound = __bind(this.createSound, this); + this.createObject = __bind(this.createObject, this); + this.createScene = __bind(this.createScene, this); + this.setPreloadScene = __bind(this.setPreloadScene, this); + this.setInitialScene = __bind(this.setInitialScene, this); + this.iteration = __bind(this.iteration, this); + this.loop = __bind(this.loop, this); + this.start = __bind(this.start, this); + this.updateCanvasSize = __bind(this.updateCanvasSize, this); + this.getSurface = __bind(this.getSurface, this); + this.createSurface = __bind(this.createSurface, this); + this.addCanvas = __bind(this.addCanvas, this); + this.canvases = {}; + this.fps = 45; + this.last_frameskip_collection = Math.floor(Date.now()); + this.frameskip = 0; + this.current_frameskip = 0; + this.scenes = {}; + this.objects = {}; + this.sounds = {}; + this.sprites = {}; + this.tilesets = {}; + } + + Engine.prototype.addCanvas = function(canvas, label) { + if (label == null) { + label = ""; + } + return this.canvases[label] = util.unpackElement(canvas); + }; + + Engine.prototype.createSurface = function(label) { + return this.canvases[label] = document.createElement("canvas"); + }; + + Engine.prototype.getSurface = function(label) { + var _ref; + if (typeof label === "string") { + return (_ref = this.canvases[label]) != null ? _ref.getContext("2d") : void 0; + } else if (label.tagName === "CANVAS") { + return label.getContext("2d"); + } else { + return label; + } + }; + + Engine.prototype.updateCanvasSize = function(canvas, w, h) { + canvas.width = w; + canvas.height = h; + canvas.style.width = "" + w + "px"; + return canvas.style.height = "" + h + "px"; + }; + + Engine.prototype.start = function() { + this.initial_scene.addTargetSurface(this.canvases[""]); + return this.loop(); + }; + + Engine.prototype.loop = function() { + return this.iteration(); + }; + + Engine.prototype.iteration = function() { + var belated_timeout, current_frame, frame_interval, name, next_frame, overtime, scene, _ref; + frame_interval = 1000 / this.fps; + current_frame = Date.now(); + next_frame = current_frame + frame_interval; + if (Math.floor(current_frame) > this.last_frameskip_collection) { + this.frameskip = this.current_frameskip; + this.current_frameskip = 0; + this.last_frameskip_collection = Math.floor(current_frame); + } + _ref = this.scenes; + for (name in _ref) { + scene = _ref[name]; + if (scene.active) { + scene.iteration(); + } + } + if (Date.now() < next_frame) { + return setTimeout(this.iteration, next_frame - Date.now()); + } else { + overtime = Date.now() - next_frame; + this.current_frameskip += Math.floor(overtime / frame_interval); + belated_timeout = overtime % frame_interval; + return setTimeout(this.iteration, belated_timeout); + } + }; + + Engine.prototype.setInitialScene = function(scene) { + return this.initial_scene = scene; + }; + + Engine.prototype.setPreloadScene = function(scene) { + return this.preload_scene = scene; + }; + + Engine.prototype.createScene = function(name) { + var scene; + scene = new Scene(this, name); + if (this.initial_scene == null) { + this.initial_scene = scene; + } + return this.scenes[name] = scene; + }; + + Engine.prototype.createObject = function(name) { + return this.objects[name] = new Object(this, name); + }; + + Engine.prototype.createSound = function(name, sound) { + return this.sounds[name] = new Sound(this, name, this.resource_manager.getSound(sound)); + }; + + Engine.prototype.createSprite = function(name, image) { + console.log("gget", this.resource_manager.getImage(image)); + return this.sprites[name] = new Sprite(this, name, this.resource_manager.getImage(image)); + }; + + Engine.prototype.createTileset = function(name, image, tile_width, tile_height) { + return this.tilesets[name] = new Tileset(this, name, this.resource_manager.getImage(image), tile_width, tile_height); + }; + + Engine.prototype.getScene = function(name) { + if (typeof name === "string") { + return this.scenes[name]; + } else { + return name; + } + }; + + Engine.prototype.getObject = function(name) { + if (typeof name === "string") { + return this.objects[name]; + } else { + return name; + } + }; + + Engine.prototype.getSound = function(name) { + if (typeof name === "string") { + return this.sounds[name]; + } else { + return name; + } + }; + + Engine.prototype.getSprite = function(name) { + if (typeof name === "string") { + return this.sprites[name]; + } else { + return name; + } + }; + + Engine.prototype.getTileset = function(name) { + if (typeof name === "string") { + return this.tilesets[name]; + } else { + return name; + } + }; + + return Engine; + + })(); + + Engine.prototype.draw = { + _startPath: (function(_this) { + return function(surface, options) { + var _ref; + surface = _this.getSurface(surface); + if ((_ref = !options._is_text) != null ? _ref : false) { + surface.beginPath(); + } + return surface; + }; + })(this), + _finishPath: (function(_this) { + return function(surface, options) { + var _ref, _ref1, _ref10, _ref11, _ref12, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9; + if ((_ref = options.stroke) != null ? _ref : true) { + surface.lineWidth = (_ref1 = (_ref2 = options.lineWidth) != null ? _ref2 : (_ref3 = options.pen) != null ? _ref3.lineWidth : void 0) != null ? _ref1 : 1; + surface.strokeStyle = (_ref4 = (_ref5 = options.lineColor) != null ? _ref5 : (_ref6 = options.pen) != null ? _ref6.lineColor : void 0) != null ? _ref4 : "black"; + if ((_ref7 = options._is_text) != null ? _ref7 : false) { + surface.strokeText(options.text, options.x, options.y); + } else { + surface.stroke(); + } + } + if ((_ref8 = options.fill) != null ? _ref8 : false) { + surface.fillStyle = (_ref9 = (_ref10 = options.fillColor) != null ? _ref10 : (_ref11 = options.pen) != null ? _ref11.fillColor : void 0) != null ? _ref9 : "white"; + if ((_ref12 = options._is_text) != null ? _ref12 : false) { + return surface.fillText(options.text, options.x, options.y); + } else { + return surface.fill(); + } + } + }; + })(this), + _getTextWidth: (function(_this) { + return function(surface, text, options) { + var width; + _this._applyTextContext(surface, options); + width = surface.measureText(text).width; + surface.restore(); + return width; + }; + })(this), + _applyTextContext: (function(_this) { + return function(surface, options) { + var font_family, font_size, font_style, font_weight, scale, _ref, _ref1, _ref2, _ref3, _ref4, _ref5; + font_family = (_ref = options.font) != null ? _ref : "sans-serif"; + font_size = (_ref1 = options.size) != null ? _ref1 : 16; + font_weight = (_ref2 = options.weight) != null ? _ref2 : "normal"; + font_style = (_ref3 = options.style) != null ? _ref3 : "normal"; + scale = (_ref4 = options.scale) != null ? _ref4 : 1; + surface.save(); + surface.font = "" + font_weight + " " + font_style + " " + font_size + "px '" + font_family + "'"; + surface.globalAlpha = (_ref5 = options.alpha) != null ? _ref5 : 1; + return surface.scale(scale, scale); + }; + })(this), + line: (function(_this) { + return function(x1, y1, x2, y2, options, surface) { + if (options == null) { + options = {}; + } + if (surface == null) { + surface = ""; + } + surface = _this._startPath(surface, options); + surface.moveTo(x1, y1); + surface.lineTo(x2, y2); + return _this._finishPath(surface, options); + }; + })(this), + rectangle: (function(_this) { + return function(x1, y1, x2, y2, options, surface) { + if (options == null) { + options = {}; + } + if (surface == null) { + surface = ""; + } + surface = _this._startPath(surface, options); + surface.rect(x1, y1, x2 - x1, y2 - y1); + return _this._finishPath(surface, options); + }; + })(this), + boxEllipse: (function(_this) { + return function(x1, y1, x2, y2, options, surface) { + var rx, ry, x, y; + if (options == null) { + options = {}; + } + if (surface == null) { + surface = ""; + } + x = (x1 + x2) / 2; + y = (y1 + y2) / 2; + rx = (x2 - x1) / 2; + ry = (y2 - y1) / 2; + return _this.radiusEllipse(x, y, rx, ry, options, surface); + }; + })(this), + radiusEllipse: (function(_this) { + return function(x, y, rx, ry, options, surface) { + var i, step, _i, _ref, _ref1; + if (options == null) { + options = {}; + } + if (surface == null) { + surface = ""; + } + surface = _this._startPath(surface, options); + step = (_ref = options.step) != null ? _ref : 0.1; + if (rx === ry) { + surface.arc(x, y, rx, 0, 2 * Math.PI, false); + } else { + surface.moveTo(x + rx, y); + for (i = _i = 0, _ref1 = Math.PI * 2 + step; 0 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 0 <= _ref1 ? ++_i : --_i) { + surface.lineTo(x + (Math.cos(i) * rx), y + (Math.sin(i) * ry)); + } + } + return _this._finishPath(surface, options); + }; + })(this), + boxPolygon: (function(_this) { + return function(x1, y1, x2, y2, sides, options, surface) { + if (options == null) { + options = {}; + } + if (surface == null) { + surface = ""; + } + return pass; + }; + })(this), + radiusPolygon: (function(_this) { + return function(x, y, r, sides, options, surface) { + if (options == null) { + options = {}; + } + if (surface == null) { + surface = ""; + } + return pass; + }; + })(this), + text: (function(_this) { + return function(x, y, text, options, surface) { + var text_width; + if (options == null) { + options = {}; + } + if (surface == null) { + surface = ""; + } + if (options.alignment == null) { + options.alignment = "left"; + } + if (options.scale == null) { + options.scale = 1; + } + options._is_text = true; + options.text = text; + options.y = y; + if (options.fill == null) { + options.fill = true; + } + if (options.fillColor == null) { + options.fillColor = "black"; + } + if (options.stroke == null) { + options.stroke = false; + } + if (alignment === "left") { + options.x = x; + } else { + text_width = _this._getTextWidth(text, options); + if (alignment === "center") { + options.x = x - ((text_width / 2) * scale * scale); + } else if (alignment === "right") { + options.x = x - text_width; + } + } + _this._startPath(surface, options); + _this._finishPath(surface, options); + return surface.restore(); + }; + })(this) + }; + + Engine.prototype.random = { + number: (function(_this) { + return function(min, max, precision) { + var base_number, rounding_factor, space; + base_number = Math.random(); + space = Math.abs(ceiling - floor); + rounding_factor = 1 / (precision != null ? precision : 0.00000001); + return Math.floor((min + (base_number * space)) * rounding_factor) / rounding_factor; + }; + })(this), + pick: (function(_this) { + return function() { + var options; + options = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return options[Math.floor(Math.random() * options.length)]; + }; + })(this), + string: (function(_this) { + return function(length, alphabet) { + var i; + if (alphabet == null) { + alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + } + return ((function() { + var _i, _ref, _results; + _results = []; + for (i = _i = 0, _ref = length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) { + _results.push(alphabet[Math.floor(Math.random() * alphabet.length)]); + } + return _results; + })()).join(""); + }; + })(this) + }; + + Object = (function() { + function Object(engine, name) { + this.engine = engine; + this.name = name; + this.checkPointCollision = __bind(this.checkPointCollision, this); + this.getBoundingBox = __bind(this.getBoundingBox, this); + this.drawSprite = __bind(this.drawSprite, this); + this.drawSelf = __bind(this.drawSelf, this); + this.callEvent = __bind(this.callEvent, this); + this.sprite = null; + this.x = 0; + this.y = 0; + } + + Object.prototype.callEvent = function(name, data) { + var _ref; + if (data == null) { + data = {}; + } + switch (name) { + case "create": + return typeof this.onCreate === "function" ? this.onCreate(data) : void 0; + case "step": + return typeof this.onStep === "function" ? this.onStep(data) : void 0; + case "draw": + this.drawSelf((_ref = data.surface) != null ? _ref : ""); + return typeof this.onDraw === "function" ? this.onDraw(data) : void 0; + } + }; + + Object.prototype.drawSelf = function(surface) { + return this.drawSprite(surface); + }; + + Object.prototype.drawSprite = function(surface) { + var _ref; + if (surface == null) { + surface = ""; + } + if ((this.sprite != null) && ((_ref = this.draw_sprite) != null ? _ref : "true")) { + return this.sprite.draw(this.x, this.y, {}, surface); + } + }; + + Object.prototype.getBoundingBox = function() { + var image_size, _ref; + image_size = (_ref = this.sprite) != null ? _ref.getSize() : void 0; + return { + x1: this.x, + x2: this.x + (image_size != null ? image_size.width : void 0), + y1: this.y, + y2: this.y + (image_size != null ? image_size.height : void 0) + }; + }; + + Object.prototype.checkPointCollision = function(x, y) { + var bounding_box; + bounding_box = this.getBoundingBox(); + return x >= (bounding_box != null ? bounding_box.x1 : void 0) && x <= (bounding_box != null ? bounding_box.x2 : void 0) && y >= (bounding_box != null ? bounding_box.y1 : void 0) && y <= (bounding_box != null ? bounding_box.y2 : void 0); + }; + + return Object; + + })(); + + ResourceManager = (function() { + function ResourceManager(base_path) { + this.base_path = base_path != null ? base_path : ""; + this.preload = __bind(this.preload, this); + this.prepare = __bind(this.prepare, this); + this.getImage = __bind(this.getImage, this); + this.addSounds = __bind(this.addSounds, this); + this.addScripts = __bind(this.addScripts, this); + this.addImages = __bind(this.addImages, this); + this.addScript = __bind(this.addScript, this); + this.addSound = __bind(this.addSound, this); + this.addImage = __bind(this.addImage, this); + this.joinPath = __bind(this.joinPath, this); + this.resources = { + stage1_images: [], + stage1_audio: [], + stage1_scripts: [], + images: [], + audio: [], + scripts: [] + }; + this.resource_objects = { + images: {}, + audio: {}, + scripts: {} + }; + } + + ResourceManager.prototype.joinPath = function(path) { + if (this.base_path === "") { + return path; + } else { + return util.stripRight(this.base_path, "/") + "/" + path; + } + }; + + ResourceManager.prototype.addImage = function(path, first_stage) { + if (first_stage == null) { + first_stage = false; + } + if (first_stage) { + return this.resources.stage1_images.push(this.joinPath(path)); + } else { + return this.resources.images.push(this.joinPath(path)); + } + }; + + ResourceManager.prototype.addSound = function(path, first_stage) { + if (first_stage == null) { + first_stage = false; + } + if (first_stage) { + return this.resources.stage1_audio.push(this.joinPath(path)); + } else { + return this.resources.audio.push(this.joinPath(path)); + } + }; + + ResourceManager.prototype.addScript = function(path, first_stage) { + if (first_stage == null) { + first_stage = false; + } + if (first_stage) { + return this.resources.stage1_scripts.push(this.joinPath(path)); + } else { + return this.resources.scripts.push(this.joinPath(path)); + } + }; + + ResourceManager.prototype.addImages = function(paths, first_stage) { + var path, _i, _len, _results; + if (first_stage == null) { + first_stage = false; + } + _results = []; + for (_i = 0, _len = paths.length; _i < _len; _i++) { + path = paths[_i]; + _results.push(this.addImage(path, first_stage)); + } + return _results; + }; + + ResourceManager.prototype.addScripts = function(paths, first_stage) { + var path, _i, _len, _results; + if (first_stage == null) { + first_stage = false; + } + _results = []; + for (_i = 0, _len = paths.length; _i < _len; _i++) { + path = paths[_i]; + _results.push(this.addScript(path, first_stage)); + } + return _results; + }; + + ResourceManager.prototype.addSounds = function(paths, first_stage) { + var path, _i, _len, _results; + if (first_stage == null) { + first_stage = false; + } + _results = []; + for (_i = 0, _len = paths.length; _i < _len; _i++) { + path = paths[_i]; + _results.push(this.addSound(path, first_stage)); + } + return _results; + }; + + ResourceManager.prototype.getImage = function(path) { + console.log("objs", this.resource_objects); + console.log("path", path); + return this.resource_objects.images[this.joinPath(path)]; + }; + + ResourceManager.prototype.prepare = function(finished_callback) { + if (finished_callback == null) { + finished_callback = (function() {}); + } + return pass; + }; + + ResourceManager.prototype.preload = function(progress_callback, finished_callback) { + var image, obj, _i, _len, _ref; + if (progress_callback == null) { + progress_callback = (function() {}); + } + if (finished_callback == null) { + finished_callback = (function() {}); + } + _ref = this.resources.images; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + image = _ref[_i]; + obj = document.createElement("img"); + obj.src = image; + this.resource_objects.images[image] = obj; + } + return finished_callback(); + }; + + return ResourceManager; + + })(); + + Scene = (function() { + function Scene(engine, name) { + this.engine = engine; + this.name = name; + this.changeScene = __bind(this.changeScene, this); + this.createInstance = __bind(this.createInstance, this); + this.checkMouseCollisions = __bind(this.checkMouseCollisions, this); + this.redraw = __bind(this.redraw, this); + this.iteration = __bind(this.iteration, this); + this.checkActive = __bind(this.checkActive, this); + this.removeTargetSurface = __bind(this.removeTargetSurface, this); + this.addTargetSurface = __bind(this.addTargetSurface, this); + this.instances = {}; + this.surfaces = []; + this.dirty = true; + this.last_instance_id = 100; + this.active = false; + this.width = 800; + this.height = 600; + this.last_width = 800; + this.last_height; + } + + Scene.prototype.addTargetSurface = function(surface) { + this.surfaces.push(surface); + this.engine.updateCanvasSize(surface, this.width, this.height); + $(surface).on("mousemove.radium", (function(_this) { + return function(event) { + var canvas_pos; + canvas_pos = surface.getBoundingClientRect(); + _this.mouse_x = Math.floor(event.clientX - canvas_pos.left); + _this.mouse_y = Math.floor(event.clientY - canvas_pos.top); + $("#debug").html("" + _this.mouse_x + " / " + _this.mouse_y); + return _this.checkMouseCollisions(); + }; + })(this)); + return this.checkActive(); + }; + + Scene.prototype.removeTargetSurface = function(surface) { + this.surfaces = this.surfaces.filter(function(obj) { + return obj !== surface; + }); + $(surface).off("mousemove.radium"); + return this.checkActive(); + }; + + Scene.prototype.checkActive = function() { + return this.active = this.surfaces.length > 0; + }; + + Scene.prototype.iteration = function() { + var id, instance, surface, _i, _len, _ref, _ref1, _ref2; + if (this.width !== this.last_width || this.height !== this.last_height) { + _ref = this.surfaces; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + surface = _ref[_i]; + this.engine.updateCanvasSize(surface, this.width, this.height); + } + _ref1 = [this.width, this.height], this.last_width = _ref1[0], this.last_height = _ref1[1]; + } + _ref2 = this.instances; + for (id in _ref2) { + instance = _ref2[id]; + if (instance.callEvent("step")) { + this.dirty = true; + } + } + if (this.dirty) { + this.redraw(); + return this.dirty = false; + } + }; + + Scene.prototype.redraw = function() { + var ctx, id, instance, surface, _i, _len, _ref, _results; + _ref = this.surfaces; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + surface = _ref[_i]; + ctx = this.engine.getSurface(surface); + ctx.clearRect(0, 0, surface.width, surface.height); + _results.push((function() { + var _ref1, _results1; + _ref1 = this.instances; + _results1 = []; + for (id in _ref1) { + instance = _ref1[id]; + _results1.push(instance.callEvent("draw", { + surface: surface + })); + } + return _results1; + }).call(this)); + } + return _results; + }; + + Scene.prototype.checkMouseCollisions = function() { + var id, instance, _ref, _results; + _ref = this.instances; + _results = []; + for (id in _ref) { + instance = _ref[id]; + if (instance.checkPointCollision(this.mouseX, this.mouseY)) { + _results.push(instance.callEvent("mouseover")); + } else { + _results.push(void 0); + } + } + return _results; + }; + + Scene.prototype.createInstance = function(object, x, y) { + var id, instance; + if (x == null) { + x = 0; + } + if (y == null) { + y = 0; + } + id = this.last_instance_id += 1; + instance = window.Object.create(this.engine.getObject(object)); + instance.x = x; + instance.y = y; + instance.id = id; + instance.scene = this; + this.instances[id] = instance; + instance.callEvent("create"); + return instance; + }; + + Scene.prototype.changeScene = function(scene) { + return pass; + }; + + return Scene; + + })(); + + Sound = (function() { + function Sound() {} + + return Sound; + + })(); + + Sprite = (function() { + function Sprite(engine, name, image) { + this.engine = engine; + this.name = name; + this.image = image; + this.getSize = __bind(this.getSize, this); + this.draw = __bind(this.draw, this); + pass; + } + + Sprite.prototype.draw = function(x, y, options, surface) { + var _ref; + if (options == null) { + options = {}; + } + if (surface == null) { + surface = ""; + } + surface = this.engine.getSurface(surface); + surface.globalAlpha = (_ref = options.alpha) != null ? _ref : 1; + return surface.drawImage(this.image, x, y); + }; + + Sprite.prototype.getSize = function() { + return { + width: this.image.width, + height: this.image.height + }; + }; + + return Sprite; + + })(); + + Tileset = (function() { + function Tileset(engine, name, image, tile_width, tile_height) { + this.engine = engine; + this.name = name; + this.image = image; + this.tile_width = tile_width; + this.tile_height = tile_height; + this.tile = __bind(this.tile, this); + this.tiles = {}; + } + + Tileset.prototype.tile = function(x, y, precise, w, h) { + var key, _ref; + if (precise == null) { + precise = false; + } + if (w == null) { + w = 0; + } + if (h == null) { + h = 0; + } + key = ("" + x + "/" + y + "/" + w + "/" + h + "/") + (precise ? 1 : 0); + return (_ref = this.tiles[key]) != null ? _ref : tiles[key] = new TilesetTile(this.engine, this, x, y, precise, w, h); + }; + + return Tileset; + + })(); + + TilesetTile = (function() { + function TilesetTile(engine, tileset, x, y, precise, w, h) { + this.engine = engine; + this.tileset = tileset; + this.x = x; + this.y = y; + this.precise = precise != null ? precise : false; + this.w = w != null ? w : 0; + this.h = h != null ? h : 0; + this.getSize = __bind(this.getSize, this); + this.draw = __bind(this.draw, this); + pass; + } + + TilesetTile.prototype.draw = function(x, y) { + var source_h, source_w, source_x, source_y, surface; + if (this.precise) { + source_x = this.x; + source_y = this.y; + source_w = this.w; + source_h = this.h; + } else { + source_x = this.x * this.tileset.tile_width; + source_y = this.y * this.tileset.tile_height; + source_w = this.tileset.tile_width; + source_h = this.tileset.tile_height; + } + surface = this.engine.getSurface(); + return surface.drawImage(source_x, source_y, source_width, source_height, x, y); + }; + + TilesetTile.prototype.getSize = function() { + if (this.precise) { + return { + width: this.w, + height: this.h + }; + } else { + return { + width: this.tileset.tile_width, + height: this.tileset.tile_height + }; + } + }; + + return TilesetTile; + + })(); + + util = { + stripRight: function(string, character) { + return string.replace(new RegExp(character + "*$", "g"), ""); + }, + unpackElement: function(element) { + console.log(element); + if (element instanceof jQuery) { + return element[0]; + } else { + return element; + } + } + }; + + window.ResourceManager = ResourceManager; + + window.Engine = Engine; + +}).call(this); diff --git a/gemswap.html b/gemswap.html new file mode 100644 index 0000000..925ef1a --- /dev/null +++ b/gemswap.html @@ -0,0 +1,14 @@ + + + + Gemswap + + + + + + + +
+ + \ No newline at end of file diff --git a/gemswap/assets/images/diamond.png b/gemswap/assets/images/diamond.png new file mode 100644 index 0000000000000000000000000000000000000000..85d244a46b12f50cbc0b19da0ecb3f842e015fb7 GIT binary patch literal 3891 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 literal 0 HcmV?d00001 diff --git a/gemswap/core.coffee b/gemswap/core.coffee new file mode 100644 index 0000000..672c23e --- /dev/null +++ b/gemswap/core.coffee @@ -0,0 +1,94 @@ +$(-> + manager = new ResourceManager("gemswap/assets") + engine = new Engine(manager) + + ### + # Configure pre-loading assets + manager.addImages([ + "images/loading_screen.png" + ], true) + ### + + # Configure game assets + manager.addImages([ + "images/diamond.png" + "images/diamond_inverted.png" + "images/diamond_shimmer.png" + ]) + + ### + manager.addSounds([ + "sfx/match.wav" + "sfx/swap.wav" + ]) + ### + + manager.prepare() + manager.preload(null, -> + engine.addCanvas($("#gamecanvas")); + + scene = engine.createScene("main") + + engine.createSprite("diamond", "images/diamond.png") + engine.createSprite("diamond_inverted", "images/diamond_inverted.png") + engine.createSprite("diamond_shimmer", "images/diamond_shimmer.png") + + diamond = engine.createObject("diamond") + diamond.sprite = engine.getSprite("diamond") + + diamond.onCreate = -> + @fade_step = 0.045 + @fade_current_step = @fade_step + @fade_value = 0 + @fade_decay_current = 9999 # Disable by default + @fade_decay_max = 8 + + @shimmer_step = 0.006 + @shimmer_current_step = @shimmer_step + @shimmer_value = 0 + + diamond.onStep = -> + if @fade_decay_current < Math.pow(2, @fade_decay_max) + @fade_value += @fade_current_step + + max = 1.5 / @fade_decay_current + + if @fade_value > Math.min(max, 1) + @fade_value = Math.min(max, 1) + @fade_current_step = -@fade_step + + if @fade_value <= 0 + @fade_value = 0 + @fade_decay_current *= 1.5 + @fade_current_step = @fade_step + + @shimmer_value += @shimmer_current_step + + if @shimmer_value > 0.7 + @shimmer_value = 0.7 + @shimmer_current_step = -@shimmer_step + + if @shimmer_value < 0 + @shimmer_value = 0 + @shimmer_current_step = @shimmer_step + + return true + + diamond.onDraw = -> + @engine.getSprite("diamond_inverted").draw(@x, @y, { + alpha: @fade_value + }) + + @engine.getSprite("diamond_shimmer").draw(@x - 14, @y - 14, { + alpha: @shimmer_value + }) + + diamond.onMouseOver = -> + console.log("mouseover") + @fade_decay_current = 1 + + scene.createInstance(diamond, 20, 20) + + engine.start() + ) +) \ No newline at end of file diff --git a/gemswap/gemswap.css b/gemswap/gemswap.css new file mode 100644 index 0000000..798b504 --- /dev/null +++ b/gemswap/gemswap.css @@ -0,0 +1,12 @@ +body +{ + text-align: center; + background-color: #000000; + color: white; +} + +#gamecanvas +{ + width: 800px; + height: 600px; +} \ No newline at end of file diff --git a/gemswap/gemswap.js b/gemswap/gemswap.js new file mode 100644 index 0000000..0bd32b2 --- /dev/null +++ b/gemswap/gemswap.js @@ -0,0 +1,85 @@ +// Generated by CoffeeScript 1.7.1 +(function() { + $(function() { + var engine, manager; + manager = new ResourceManager("gemswap/assets"); + engine = new Engine(manager); + + /* + * Configure pre-loading assets + manager.addImages([ + "images/loading_screen.png" + ], true) + */ + manager.addImages(["images/diamond.png", "images/diamond_inverted.png", "images/diamond_shimmer.png"]); + + /* + manager.addSounds([ + "sfx/match.wav" + "sfx/swap.wav" + ]) + */ + manager.prepare(); + return manager.preload(null, function() { + var diamond, scene; + engine.addCanvas($("#gamecanvas")); + scene = engine.createScene("main"); + engine.createSprite("diamond", "images/diamond.png"); + engine.createSprite("diamond_inverted", "images/diamond_inverted.png"); + engine.createSprite("diamond_shimmer", "images/diamond_shimmer.png"); + diamond = engine.createObject("diamond"); + diamond.sprite = engine.getSprite("diamond"); + diamond.onCreate = function() { + this.fade_step = 0.045; + this.fade_current_step = this.fade_step; + this.fade_value = 0; + this.fade_decay_current = 9999; + this.fade_decay_max = 8; + this.shimmer_step = 0.006; + this.shimmer_current_step = this.shimmer_step; + return this.shimmer_value = 0; + }; + diamond.onStep = function() { + var max; + if (this.fade_decay_current < Math.pow(2, this.fade_decay_max)) { + this.fade_value += this.fade_current_step; + max = 1.5 / this.fade_decay_current; + if (this.fade_value > Math.min(max, 1)) { + this.fade_value = Math.min(max, 1); + this.fade_current_step = -this.fade_step; + } + if (this.fade_value <= 0) { + this.fade_value = 0; + this.fade_decay_current *= 1.5; + this.fade_current_step = this.fade_step; + } + } + this.shimmer_value += this.shimmer_current_step; + if (this.shimmer_value > 0.7) { + this.shimmer_value = 0.7; + this.shimmer_current_step = -this.shimmer_step; + } + if (this.shimmer_value < 0) { + this.shimmer_value = 0; + this.shimmer_current_step = this.shimmer_step; + } + return true; + }; + diamond.onDraw = function() { + this.engine.getSprite("diamond_inverted").draw(this.x, this.y, { + alpha: this.fade_value + }); + return this.engine.getSprite("diamond_shimmer").draw(this.x - 14, this.y - 14, { + alpha: this.shimmer_value + }); + }; + diamond.onMouseOver = function() { + console.log("mouseover"); + return this.fade_decay_current = 1; + }; + scene.createInstance(diamond, 20, 20); + return engine.start(); + }); + }); + +}).call(this); diff --git a/gemswap/source/diamond.svg b/gemswap/source/diamond.svg new file mode 100644 index 0000000..7b2721f --- /dev/null +++ b/gemswap/source/diamond.svg @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gemswap/source/diamond_inverted.svg b/gemswap/source/diamond_inverted.svg new file mode 100644 index 0000000..9d705c1 --- /dev/null +++ b/gemswap/source/diamond_inverted.svg @@ -0,0 +1,416 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gemswap/source/diamond_shimmer.svg b/gemswap/source/diamond_shimmer.svg new file mode 100644 index 0000000..1b8a25f --- /dev/null +++ b/gemswap/source/diamond_shimmer.svg @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/radium/000_prepare.coffee b/radium/000_prepare.coffee new file mode 100644 index 0000000..e69de29 diff --git a/radium/base.coffee b/radium/base.coffee new file mode 100644 index 0000000..e69de29 diff --git a/radium/engine.coffee b/radium/engine.coffee new file mode 100644 index 0000000..025717a --- /dev/null +++ b/radium/engine.coffee @@ -0,0 +1,106 @@ +window.pass = undefined # This will give us Python-like noop calls + +class Engine + constructor: (@resource_manager) -> + @canvases = {} + @fps = 45 + @last_frameskip_collection = Math.floor(Date.now()) + @frameskip = 0 + @current_frameskip = 0 + + @scenes = {} + @objects = {} + @sounds = {} + @sprites = {} + @tilesets = {} + + addCanvas: (canvas, label = "") => + @canvases[label] = util.unpackElement(canvas) + + createSurface: (label) => + @canvases[label] = document.createElement("canvas") + + getSurface: (label) => + if typeof label == "string" + return @canvases[label]?.getContext("2d") + else if label.tagName == "CANVAS" + return label.getContext("2d") + else + return label + + updateCanvasSize: (canvas, w, h) => + canvas.width = w + canvas.height = h + canvas.style.width = "#{w}px" + canvas.style.height = "#{h}px" + + start: () => + @initial_scene.addTargetSurface(@canvases[""]) + @loop() + + loop: () => + @iteration() + + iteration: () => + # Calculation of next frame and frameskip collection check + frame_interval = (1000 / @fps) + + current_frame = Date.now() + next_frame = current_frame + frame_interval + + if Math.floor(current_frame) > @last_frameskip_collection + @frameskip = @current_frameskip + @current_frameskip = 0 + @last_frameskip_collection = Math.floor(current_frame) + + # Actual iteration code + scene.iteration() for name, scene of @scenes when scene.active + + # Frameskip check and triggering next iteration + if Date.now() < next_frame + setTimeout(@iteration, (next_frame - Date.now())) + else + # Frameskip! + overtime = Date.now() - next_frame + @current_frameskip += Math.floor(overtime / frame_interval) + belated_timeout = overtime % frame_interval + setTimeout(@iteration, belated_timeout) + + setInitialScene: (scene) => + @initial_scene = scene + + setPreloadScene: (scene) => + @preload_scene = scene + + createScene: (name) => + scene = new Scene(this, name) + @initial_scene ?= scene + @scenes[name] = scene + + createObject: (name) => + @objects[name] = new Object(this, name) + + createSound: (name, sound) => + @sounds[name] = new Sound(this, name, @resource_manager.getSound(sound)) + + createSprite: (name, image) => + console.log("gget", @resource_manager.getImage(image)) + @sprites[name] = new Sprite(this, name, @resource_manager.getImage(image)) + + createTileset: (name, image, tile_width, tile_height) => + @tilesets[name] = new Tileset(this, name, @resource_manager.getImage(image), tile_width, tile_height) + + getScene: (name) => + if typeof name == "string" then @scenes[name] else name + + getObject: (name) => + if typeof name == "string" then @objects[name] else name + + getSound: (name) => + if typeof name == "string" then @sounds[name] else name + + getSprite: (name) => + if typeof name == "string" then @sprites[name] else name + + getTileset: (name) => + if typeof name == "string" then @tilesets[name] else name \ No newline at end of file diff --git a/radium/engine.draw.coffee b/radium/engine.draw.coffee new file mode 100644 index 0000000..0f2a400 --- /dev/null +++ b/radium/engine.draw.coffee @@ -0,0 +1,113 @@ +Engine::draw = + _startPath: (surface, options) => + surface = @getSurface(surface) + + if not options._is_text ? false + surface.beginPath() + + return surface + + _finishPath: (surface, options) => + if options.stroke ? true + surface.lineWidth = options.lineWidth ? options.pen?.lineWidth ? 1 + surface.strokeStyle = options.lineColor ? options.pen?.lineColor ? "black" + + if options._is_text ? false + surface.strokeText(options.text, options.x, options.y) + else + surface.stroke() + + if options.fill ? false + surface.fillStyle = options.fillColor ? options.pen?.fillColor ? "white" + + if options._is_text ? false + surface.fillText(options.text, options.x, options.y) + else + surface.fill() + + _getTextWidth: (surface, text, options) => + @_applyTextContext(surface, options) + width = surface.measureText(text).width + surface.restore() + return width + + _applyTextContext: (surface, options) => + font_family = options.font ? "sans-serif" + font_size = options.size ? 16 + font_weight = options.weight ? "normal" + font_style = options.style ? "normal" + scale = options.scale ? 1 + + surface.save() + surface.font = "#{font_weight} #{font_style} #{font_size}px '#{font_family}'" + surface.globalAlpha = options.alpha ? 1 + surface.scale(scale, scale) + + line: (x1, y1, x2, y2, options = {}, surface = "") => + surface = @_startPath(surface, options) + surface.moveTo(x1, y1) + surface.lineTo(x2, y2) + @_finishPath(surface, options) + + rectangle: (x1, y1, x2, y2, options = {}, surface = "") => + surface = @_startPath(surface, options) + surface.rect(x1, y1, x2 - x1, y2 - y1) + @_finishPath(surface, options) + + boxEllipse: (x1, y1, x2, y2, options = {}, surface = "") => + x = (x1 + x2) / 2; + y = (y1 + y2) / 2; + rx = (x2 - x1) / 2; + ry = (y2 - y1) / 2; + @radiusEllipse(x, y, rx, ry, options, surface) + + radiusEllipse: (x, y, rx, ry, options = {}, surface = "") => + surface = @_startPath(surface, options) + + step = options.step ? 0.1 + + if rx == ry + surface.arc(x, y, rx, 0, 2 * Math.PI, false) + else + surface.moveTo(x + rx, y) + + for i in [0 .. (Math.PI * 2 + step)] + surface.lineTo(x + (Math.cos(i) * rx), y + (Math.sin(i) * ry)) + + @_finishPath(surface, options) + + boxPolygon: (x1, y1, x2, y2, sides, options = {}, surface = "") => + pass # TODO + + radiusPolygon: (x, y, r, sides, options = {}, surface = "") => + pass # TODO + + text: (x, y, text, options = {}, surface = "") => + # Defaults + options.alignment ?= "left" + options.scale ?= 1 + options._is_text = true + options.text = text + options.y = y + + # Text needs different default color settings from other shapes... + options.fill ?= true + options.fillColor ?= "black" + options.stroke ?= false + + # X coordinate will be calculated depending on alignment + if alignment == "left" + options.x = x + else + text_width = @_getTextWidth(text, options) + + if alignment == "center" + options.x = x - ((text_width / 2) * scale * scale) + else if alignment == "right" + options.x = x - text_width # FIXME: Possibly broken wrt scale? + + @_startPath(surface, options) + @_finishPath(surface, options) + + # This is to avoid scale from affecting anything else + surface.restore() \ No newline at end of file diff --git a/radium/engine.random.coffee b/radium/engine.random.coffee new file mode 100644 index 0000000..dd13486 --- /dev/null +++ b/radium/engine.random.coffee @@ -0,0 +1,13 @@ +Engine::random = + number: (min, max, precision) => + base_number = Math.random() + space = Math.abs(ceiling - floor) + rounding_factor = 1 / (precision ? 0.00000001) + return Math.floor((min + (base_number * space)) * rounding_factor) / rounding_factor + + pick: (options...) => + return options[Math.floor(Math.random() * options.length)] + + string: (length, alphabet) => + alphabet ?= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + return (alphabet[Math.floor(Math.random() * alphabet.length)] for i in [0 .. length - 1]).join("") \ No newline at end of file diff --git a/radium/object.coffee b/radium/object.coffee new file mode 100644 index 0000000..95ef082 --- /dev/null +++ b/radium/object.coffee @@ -0,0 +1,35 @@ +class Object + constructor: (@engine, @name) -> + @sprite = null + @x = 0 + @y = 0 + + callEvent: (name, data = {}) => + switch name + when "create" then @onCreate?(data) + when "step" then @onStep?(data) + when "draw" + @drawSelf(data.surface ? "") + @onDraw?(data) + + drawSelf: (surface) => + @drawSprite(surface) + + drawSprite: (surface = "") => + @sprite.draw(@x, @y, {}, surface) if @sprite? and (@draw_sprite ? "true") + + getBoundingBox: => + image_size = @sprite?.getSize() + + return { + x1: @x + x2: @x + image_size?.width + y1: @y + y2: @y + image_size?.height + } + + checkPointCollision: (x, y) => + # TODO: Precision collision matching! + bounding_box = @getBoundingBox() + + return x >= bounding_box?.x1 and x <= bounding_box?.x2 and y >= bounding_box?.y1 and y <= bounding_box?.y2 diff --git a/radium/resource-manager.coffee b/radium/resource-manager.coffee new file mode 100644 index 0000000..ebe90a7 --- /dev/null +++ b/radium/resource-manager.coffee @@ -0,0 +1,63 @@ +class ResourceManager + constructor: (@base_path = "") -> + @resources = + stage1_images: [] + stage1_audio: [] + stage1_scripts: [] + images: [] + audio: [] + scripts: [] + + @resource_objects = + images: {} + audio: {} + scripts: {} + + joinPath: (path) => + if @base_path == "" then path else util.stripRight(@base_path, "/") + "/" + path + + addImage: (path, first_stage = false) => + if first_stage + @resources.stage1_images.push(@joinPath(path)) + else + @resources.images.push(@joinPath(path)) + + addSound: (path, first_stage = false) => + if first_stage + @resources.stage1_audio.push(@joinPath(path)) + else + @resources.audio.push(@joinPath(path)) + + addScript: (path, first_stage = false) => + if first_stage + @resources.stage1_scripts.push(@joinPath(path)) + else + @resources.scripts.push(@joinPath(path)) + + addImages: (paths, first_stage = false) => + @addImage(path, first_stage) for path in paths + + addScripts: (paths, first_stage = false) => + @addScript(path, first_stage) for path in paths + + addSounds: (paths, first_stage = false) => + @addSound(path, first_stage) for path in paths + + getImage: (path) => + # FIXME: Do properly when PreloadJS is added + console.log("objs", @resource_objects) + console.log("path", path) + return @resource_objects.images[@joinPath(path)] + + prepare: (finished_callback = (->)) => + # This performs a stage 1 preload, loading the initial assets required for displaying the preload screen. + pass + + preload: (progress_callback = (->), finished_callback = (->)) => + # This performs the stage 2 preload; it will load the actual game assets. + for image in @resources.images + obj = document.createElement("img") + obj.src = image + @resource_objects.images[image] = obj + + finished_callback() \ No newline at end of file diff --git a/radium/scene.coffee b/radium/scene.coffee new file mode 100644 index 0000000..93972b7 --- /dev/null +++ b/radium/scene.coffee @@ -0,0 +1,72 @@ +class Scene + constructor: (@engine, @name) -> + @instances = {} + @surfaces = [] + @dirty = true # Triggers first draw + @last_instance_id = 100 + @active = false + @width = 800 + @height = 600 + @last_width = 800 + @last_height + + addTargetSurface: (surface) => + @surfaces.push(surface) + @engine.updateCanvasSize(surface, @width, @height) + $(surface).on("mousemove.radium", (event) => + canvas_pos = surface.getBoundingClientRect() + @mouse_x = Math.floor(event.clientX - canvas_pos.left) + @mouse_y = Math.floor(event.clientY - canvas_pos.top) + $("#debug").html("#{@mouse_x} / #{@mouse_y}") + @checkMouseCollisions() + ) + @checkActive() + + removeTargetSurface: (surface) => + @surfaces = @surfaces.filter (obj) -> obj isnt surface + $(surface).off("mousemove.radium") + @checkActive() + + checkActive: => + @active = (@surfaces.length > 0) + + iteration: => + if @width != @last_width or @height != @last_height + @engine.updateCanvasSize(surface, @width, @height) for surface in @surfaces + [@last_width, @last_height] = [@width, @height] + + for id, instance of @instances + if instance.callEvent("step") + @dirty = true + + if @dirty + @redraw() + @dirty = false + + redraw: => + for surface in @surfaces + ctx = @engine.getSurface(surface) + ctx.clearRect(0, 0, surface.width, surface.height); + instance.callEvent("draw", {surface: surface}) for id, instance of @instances + + checkMouseCollisions: => + for id, instance of @instances + instance.callEvent("mouseover") if instance.checkPointCollision(@mouseX, @mouseY) + + createInstance: (object, x = 0, y = 0) => + id = @last_instance_id += 1 + + instance = window.Object.create(@engine.getObject(object)) + instance.x = x + instance.y = y + instance.id = id + instance.scene = this + @instances[id] = instance + + instance.callEvent("create") + + return instance + + changeScene: (scene) => + # This will change to a different scene, but inherit the target surfaces + pass \ No newline at end of file diff --git a/radium/sound.coffee b/radium/sound.coffee new file mode 100644 index 0000000..e413191 --- /dev/null +++ b/radium/sound.coffee @@ -0,0 +1 @@ +class Sound \ No newline at end of file diff --git a/radium/sprite.coffee b/radium/sprite.coffee new file mode 100644 index 0000000..389d0ee --- /dev/null +++ b/radium/sprite.coffee @@ -0,0 +1,12 @@ +class Sprite + constructor: (@engine, @name, @image) -> + pass + + draw: (x, y, options = {}, surface = "") => + surface = @engine.getSurface(surface) + # TODO: Options. + surface.globalAlpha = options.alpha ? 1 + surface.drawImage(@image, x, y) + + getSize: => + return {width: @image.width, height: @image.height} \ No newline at end of file diff --git a/radium/tileset.coffee b/radium/tileset.coffee new file mode 100644 index 0000000..911149c --- /dev/null +++ b/radium/tileset.coffee @@ -0,0 +1,30 @@ +class Tileset + constructor: (@engine, @name, @image, @tile_width, @tile_height) -> + @tiles = {} + + tile: (x, y, precise = false, w = 0, h = 0) => + key = "#{x}/#{y}/#{w}/#{h}/" + if precise then 1 else 0 + @tiles[key] ? tiles[key] = new TilesetTile(@engine, this, x, y, precise, w, h) + +class TilesetTile + constructor: (@engine, @tileset, @x, @y, @precise = false, @w = 0, @h = 0) -> + pass + + draw: (x, y) => + if @precise + source_x = @x + source_y = @y + source_w = @w + source_h = @h + else + source_x = @x * @tileset.tile_width + source_y = @y * @tileset.tile_height + source_w = @tileset.tile_width + source_h = @tileset.tile_height + + surface = @engine.getSurface() + # TODO: Options. + surface.drawImage(source_x, source_y, source_width, source_height, x, y) + + getSize: => + return if @precise then {width: @w, height: @h} else {width: @tileset.tile_width, height: @tileset.tile_height} \ No newline at end of file diff --git a/radium/util.coffee b/radium/util.coffee new file mode 100644 index 0000000..119267b --- /dev/null +++ b/radium/util.coffee @@ -0,0 +1,6 @@ +util = + stripRight: (string, character) -> + string.replace(new RegExp(character + "*$", "g"), "") + unpackElement: (element) -> + console.log(element) + if element instanceof jQuery then element[0] else element \ No newline at end of file diff --git a/radium/zzz_exports.coffee b/radium/zzz_exports.coffee new file mode 100644 index 0000000..87c171d --- /dev/null +++ b/radium/zzz_exports.coffee @@ -0,0 +1,2 @@ +window.ResourceManager = ResourceManager +window.Engine = Engine \ No newline at end of file diff --git a/watch.sh b/watch.sh new file mode 100755 index 0000000..a0a3680 --- /dev/null +++ b/watch.sh @@ -0,0 +1,3 @@ +#!/bin/bash +coffee -w -c -j gemswap.coffee -o gemswap/ gemswap/*.coffee& +coffee -w -c -j radium.coffee -o compiled/ radium/*.coffee