Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial commit of CT

  • Loading branch information...
commit 54f22b84e42025b5981eebaf608ffed7e3cfe818 0 parents
@kirbysayshi authored
Showing with 2,272 additions and 0 deletions.
  1. +1 −0  .dropbox
  2. 0  Icon
  3. +3 −0  README
  4. +3 −0  database/Characters.js
  5. BIN  font/ct_all_text.png
  6. +93 −0 font/ct_en_mono.js
  7. BIN  font/ct_en_mono.png
  8. BIN  font/ct_en_mono.psd
  9. BIN  images/Crono.png
  10. BIN  images/Front View of Crono Walking.gif
  11. BIN  images/basetiles.png
  12. BIN  images/basetiles.psd
  13. BIN  images/chrono walk.psd
  14. BIN  images/chronotrigger_crono_sheet.png
  15. BIN  images/crono-horizontal.psd
  16. BIN  images/maps/flatpsd/eot.psd
  17. BIN  images/maps/flatpsd/eot_layered.psd
  18. BIN  images/maps/flatpsd/spekkio_layered.psd
  19. BIN  images/maps/flatpsd/spekkiosroom.png
  20. BIN  images/maps/flatpsd/spekkiosroom.psd
  21. BIN  images/maps/png/eot.png
  22. BIN  images/maps/png/eot_layered_lower.png
  23. BIN  images/maps/png/eot_layered_upper.png
  24. BIN  images/maps/png/spekkio_layered_lower.png
  25. BIN  images/maps/png/spekkio_layered_upper.png
  26. BIN  images/maps/png/spekkiosroom.png
  27. BIN  images/maps/rips/eot.png
  28. BIN  images/maps/rips/eot_lower.png
  29. BIN  images/maps/rips/eot_upper.png
  30. BIN  images/sprites/pillar_of_light.psd
  31. BIN  images/windows/ct_grey.png
  32. BIN  images/windows/ct_windows.png
  33. +108 −0 maps/EndOfTime.js
  34. +33 −0 maps/EndOfTimeSpekkio.js
  35. 0  maps/MasterMapList.js
  36. +1 −0  maps/PathToJSON.jsx
  37. +20 −0 maps/tiled/eot.tmx
  38. +104 −0 sprites/Crono.js
  39. BIN  sprites/Crono.png
  40. +25 −0 sprites/LightPillar.js
  41. BIN  sprites/crono-horizontal.png
  42. BIN  sprites/crono_all.png
  43. BIN  sprites/pillar_of_light.png
  44. +69 −0 src/AssetLoader.js
  45. +3 −0  src/Camera.js
  46. +6 −0 src/Character.js
  47. +6 −0 src/CharacterDatabase.js
  48. +82 −0 src/ComplexSprite.js
  49. +29 −0 src/Database.js
  50. +3 −0  src/Door.js
  51. +62 −0 src/Event.js
  52. +35 −0 src/FPSMonitor.js
  53. +192 −0 src/InputDetection.js
  54. +130 −0 src/Map.js
  55. +3 −0  src/MapLayer.js
  56. 0  src/Message.js
  57. +44 −0 src/MonoMenu.js
  58. +196 −0 src/MonoText.js
  59. +141 −0 src/MonoTextII.js
  60. +499 −0 src/RPG.js
  61. +55 −0 src/SimpleSprite.js
  62. +38 −0 src/Util.js
  63. +91 −0 tests/map.html
  64. +59 −0 tests/menu.html
  65. +40 −0 tests/pointpolygon.html
  66. +62 −0 tests/rpg.html
  67. +36 −0 tests/text.html
1  .dropbox
@@ -0,0 +1 @@
+4199398
0  Icon
No changes.
3  README
@@ -0,0 +1,3 @@
+A JavaScript RPG engine, for creating games in the style of Chrono Trigger. Everything is drawn using html5 canvas, and there is support for display lists, as in Flash.
+
+Clone the repo, and run the tests/rpg.html file in a browser...
3  database/Characters.js
@@ -0,0 +1,3 @@
+function Characters(){
+ this.startChar = new Crono();
+}
BIN  font/ct_all_text.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
93 font/ct_en_mono.js
@@ -0,0 +1,93 @@
+var kerning = {
+ 'A': { start: 1, end: 8 },
+ 'B': { start: 9, end: 16 },
+ 'C': { start: 17, end: 24 },
+ 'D': { start: 25, end: 32 },
+ 'E': { start: 33, end: 39 },
+ 'F': { start: 40, end: 46 },
+ 'G': { start: 47, end: 53 },
+ 'H': { start: 55, end: 62 },
+ 'I': { start: 63, end: 68 },
+ 'J': { start: 69, end: 76 },
+ 'K': { start: 77, end: 85 },
+ 'L': { start: 86, end: 92 },
+ 'M': { start: 93, end: 102 },
+ 'N': { start: 103, end: 111 },
+ 'O': { start: 112, end: 119 },
+ 'P': { start: 120, end: 127 },
+ 'Q': { start: 128, end: 135 },
+ 'R': { start: 136, end: 143 },
+ 'S': { start: 144, end: 150 },
+ 'T': { start: 151, end: 158 },
+ 'U': { start: 159, end: 166 },
+ 'V': { start: 167, end: 174 },
+ 'W': { start: 175, end: 186 },
+ 'X': { start: 187, end: 194 },
+ 'Y': { start: 195, end: 202 },
+ 'Z': { start: 203, end: 210 },
+
+ 'a': { start: 211, end: 218 },
+ 'b': { start: 219, end: 226 },
+ 'c': { start: 227, end: 233 },
+ 'd': { start: 234, end: 241 },
+ 'e': { start: 242, end: 249 },
+ 'f': { start: 250, end: 256 },
+ 'g': { start: 257, end: 264 },
+ 'h': { start: 265, end: 272 },
+ 'i': { start: 273, end: 276 },
+ 'j': { start: 277, end: 283 },
+ 'k': { start: 284, end: 291 },
+ 'l': { start: 292, end: 295 },
+ 'm': { start: 296, end: 307 },
+ 'n': { start: 308, end: 315 },
+ 'o': { start: 316, end: 323 },
+ 'p': { start: 324, end: 331 },
+ 'q': { start: 332, end: 339 },
+ 'r': { start: 340, end: 346 },
+ 's': { start: 347, end: 353 },
+ 't': { start: 354, end: 359 },
+ 'u': { start: 360, end: 367 },
+ 'v': { start: 368, end: 375 },
+ 'w': { start: 376, end: 387 },
+ 'x': { start: 388, end: 395 },
+ 'y': { start: 396, end: 403 },
+ 'z': { start: 404, end: 411 },
+
+ '0': { start: 412, end: 419 },
+ '1': { start: 420, end: 424 },
+ '2': { start: 425, end: 432 },
+ '3': { start: 433, end: 440 },
+ '4': { start: 441, end: 449 },
+ '5': { start: 450, end: 457 },
+ '6': { start: 458, end: 465 },
+ '7': { start: 466, end: 473 },
+ '8': { start: 474, end: 481 },
+ '9': { start: 482, end: 489 },
+
+ '!': { start: 490, end: 493 },
+ '?': { start: 494, end: 501 },
+ '/': { start: 502, end: 507 },
+ 'LQUOTES': { start: 508, end: 514 }, // left quotes
+ 'RQUOTES': { start: 515, end: 521 }, // right quotes
+ ':': { start: 522, end: 525 },
+ '&': { start: 526, end: 535 },
+ '(': { start: 536, end: 540 },
+ ')': { start: 541, end: 545 },
+ "'": { start: 546, end: 549 },
+ '.': { start: 550, end: 553 },
+ ',': { start: 554, end: 557 },
+ '=': { start: 558, end: 566 },
+ '-': { start: 567, end: 575 },
+ '+': { start: 576, end: 584 },
+ '%': { start: 585, end: 594 },
+ 'MUSIC': { start: 595, end: 603 },
+ 'HEART': { start: 604, end: 614 },
+ 'ELLIPSES': { start: 615, end: 623 },
+ 'INFINITY': { start: 624, end: 636 },
+ '#': { start: 637, end: 645 },
+ 'POINTLEFT': { start: 646, end: 661},
+ 'POINTRIGHT': { start: 662, end: 677},
+ 'POINTBLANK': { start: 678, end: 693},
+
+ ' ': { start: 678, end: 682 }
+};
BIN  font/ct_en_mono.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  font/ct_en_mono.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/Crono.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/Front View of Crono Walking.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/basetiles.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/basetiles.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/chrono walk.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/chronotrigger_crono_sheet.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/crono-horizontal.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/flatpsd/eot.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/flatpsd/eot_layered.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/flatpsd/spekkio_layered.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/flatpsd/spekkiosroom.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/flatpsd/spekkiosroom.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/png/eot.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/png/eot_layered_lower.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/png/eot_layered_upper.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/png/spekkio_layered_lower.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/png/spekkio_layered_upper.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/png/spekkiosroom.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/rips/eot.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/rips/eot_lower.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/maps/rips/eot_upper.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/sprites/pillar_of_light.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  images/windows/ct_grey.png
Diff not rendered
BIN  images/windows/ct_windows.png
Diff not rendered
108 maps/EndOfTime.js
@@ -0,0 +1,108 @@
+function EndOfTime(vwidth, vheight){
+
+ this.mapname = "End of Time";
+ //this.path = '../images/maps/png/eot.png';
+ this.vHeight = vheight;
+ this.vWidth = vwidth;
+ this.backgroundColor = "#0d0d0d";
+
+ // initialize parent..
+ Map.call(this, this.mapname, 'EndOfTime', this.vWidth, this.vHeight, this.backgroundColor);
+
+ // this should be the whole polygon...
+ this.walkable = [
+ { x: 176, y: 68 }, { x: 321, y: 141 }, { x: 302, y: 173 }, { x: 302, y: 180 },
+ { x: 347, y: 225 }, { x: 412, y: 257 }, { x: 420, y: 254 }, { x: 432, y: 228 },
+ { x: 492, y: 260 }, { x: 501, y: 245 }, { x: 509, y: 249 }, { x: 510, y: 271 },
+ { x: 519, y: 275 }, { x: 528, y: 273 }, { x: 535, y: 282 }, { x: 537, y: 304 },
+ { x: 544, y: 316 }, { x: 553, y: 324 }, { x: 556, y: 336 }, { x: 620, y: 369 },
+ { x: 637, y: 396 }, { x: 627, y: 415 }, { x: 612, y: 389 }, { x: 552, y: 358 },
+ { x: 541, y: 359 }, { x: 538, y: 374 }, { x: 510, y: 432 }, { x: 402, y: 379 },
+ { x: 402, y: 359 }, { x: 405, y: 349 }, { x: 409, y: 319 }, { x: 402, y: 285 },
+ { x: 336, y: 249 }, { x: 292, y: 205 }, { x: 283, y: 208 }, { x: 255, y: 271 },
+ { x: 110, y: 203 }, { x: 176, y: 68 }, // repeat first point
+
+ { x: 464, y: 302 }, { x: 480, y: 303 }, { x: 483, y: 335 }, { x: 472, y: 341 },
+ { x: 459, y: 336 }, { x: 464, y: 302 }, // repeat first point
+ ];
+
+ // these coordinates all all off since the map changed
+ this.events = [
+ // Day of Lavos, touch the bucket
+ new Event(Event.CHOICE, {x: 540, y: 295}, 30, {x: 550, y: 288},
+ Event.ACTIVATE, {
+ choices: [
+ {text: "Yes", payload: function(){
+ if(CURE.db.getMapFlag('bucket') == true)
+ console.log("yes!");
+ else{
+ console.log('bucket');
+ }
+ }},
+ {text: "No", payload: function(){ console.log("no"); }},
+ {text: "Secret Option 3", payload: function(){ console.log('opt3') }},
+ {text: "Secret Option 4", payload: function(){ console.log('opt4') }},
+ {text: "Secret Option 5", payload: function(){ console.log('opt5') }},
+ ],
+ prompt: "Go to the Day of Lavos, 1999 AD?",
+ payload: [
+ function(){
+ //CURE.mt.message("Go to the Day of Lavos, 1999 AD?");
+ }
+ ],
+ onComplete: function(me){
+ this.complete = true;
+ console.log("bucket event complete");
+ }
+ }),
+ new Event(Event.GENERIC, {x: 470, y: 333}, 20, {x: 470, y: 333},
+ Event.ACTIVATE, {
+ payload: [
+ function(){
+ CURE.db.setMapFlag('bucket', true);
+ CURE.mt.message("Old Man: Do you dare challenge Lavos? Do you dare to change what has been set in motion?");
+ },
+ function(){ CURE.mt.message("Old Man: If so, then touch the bucket."); }
+ ],
+ onComplete: function(me){
+ console.log('old man complete');
+ }
+ }),
+ new Event(Event.GENERIC, {x: 230, y: 135}, 8, {x: 230, y: 135},
+ Event.ACTIVATE, {
+ payload: [
+ function(){ CURE.mt.message('TEST: Make sure you send the message properly, ok?'); },
+ function(){ CURE.mt.message('DO YOU REALIZE: Yes, yes, I hope you do.'); },
+ function(){ CURE.mt.message('Please take notice: do not step on the portals! They are highly dangerous and trans-fluxative.'); }
+ ],
+ onComplete: function(me){
+ console.log("event complete");
+ }
+ }),
+ new Event(Event.GENERIC, {x: 502, y: 250}, 5, {x: 500, y: 260},
+ Event.PROXIMITY, {
+ onComplete: function(me){
+ console.log("teleport to spekkio's room");
+ CURE.switchMap('EndOfTimeSpekkio', 95, 217);
+ //CURE.map = new EndOfTimeSpekkio(CURE.width, CURE.height);
+ //CURE.hero.setPositionOnMap(82, 195);
+ }
+ })
+
+ ];
+
+ this.doors = [
+ new Door('EndOfTimeSpekkio', 82, 204)
+ ];
+
+ this.children = [
+ new LightPillar()
+ ];
+
+ this.children[0].setPositionOnMap(216, 171);
+ this.children[0].setSequence('stop_down');
+ CURE.addChild(this.children[0]);
+};
+
+EndOfTime.prototype = new Map();
+EndOfTime.prototype.constructor = EndOfTime;
33 maps/EndOfTimeSpekkio.js
@@ -0,0 +1,33 @@
+function EndOfTimeSpekkio(vwidth, vheight){
+
+ this.mapname = "Spekkio's Room";
+ this.vHeight = vheight;
+ this.vWidth = vwidth;
+
+ // initialize parent..
+ Map.call(this, this.mapname, 'EndOfTimeSpekkio', this.vWidth, this.vHeight);
+
+ // this should be the whole polygon...
+ this.walkable = [
+ { x: 15, y: 184 }, { x: 81, y: 55 }, { x: 223, y: 124 }, { x: 157, y: 253 },
+ { x: 100, y: 225 }, { x: 92, y: 241 }, { x: 84, y: 237 }, { x: 83, y: 217 },
+ { x: 15, y: 184 }, // repeat first point
+ ];
+
+ this.events = [
+ new Event(Event.GENERIC, {x: 89, y: 232}, 6, {x: 88, y: 235},
+ Event.PROXIMITY, {
+ onComplete: function(me){
+ console.log("teleport to end of time room");
+ CURE.switchMap('EndOfTime', 500, 264);
+ //CURE.map = new EndOfTime(CURE.width, CURE.height);
+ //CURE.hero.setPositionOnMap(500, 264);
+ //CURE.map.x = 268;
+ //CURE.map.y = 126;
+ }
+ })
+ ];
+}
+
+EndOfTimeSpekkio.prototype = new Map();
+EndOfTimeSpekkio.prototype.constructor = EndOfTimeSpekkio;
0  maps/MasterMapList.js
No changes.
1  maps/PathToJSON.jsx
@@ -0,0 +1 @@
+var p = activeDocument.pathItems[0];
20 maps/tiled/eot.tmx
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE map SYSTEM "http://mapeditor.org/dtd/1.0/map.dtd">
+<map version="1.0" orientation="orthogonal" width="68" height="54" tilewidth="8" tileheight="8">
+ <tileset name="eot" firstgid="1" tilewidth="8" tileheight="8">
+ <image source="../../images/maps/png/eot.png"/>
+ </tileset>
+ <tileset name="Untitled" firstgid="3605" tilewidth="8" tileheight="8">
+ <image source="../../images/basetiles.png"/>
+ </tileset>
+ <layer name="Layer 0" width="68" height="54">
+ <data encoding="base64" compression="gzip">
+ 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
+ </data>
+ </layer>
+ <layer name="Layer 1" width="68" height="54">
+ <data encoding="base64" compression="gzip">
+ H4sIAAAAAAAAAO3SMRLDIAxEUZ8gne9/1Uy6FA4BgfgLrGbUeSTtM/frum632+1O6k/RN6j0U9E3qXmcalJT9I1qHqfY9BR9u5rHbiYji86i5rG6S3bR+ZQ86GxKFvawxS4W9pjrsZrJzKKz2kTHpTRv9M0rmJTmZdyqbFI7q/f/ZzmPdInMiuad7RFx6ZlT+z3tEc0Tta3dRXvU/reR762lKI+nXFlvbiWP70wZ7211l9Fv7nSXjKIzqXms7GKPfA86kz00Heyxh8nMorOSHqX5dGbK4t8uOv8sl5Z9dPYZLq376NzZLpFddOZMl109Ijb0nWou9H1KJvRddNvjtwt9g9t9Wr8B7Tru6GA5AAA=
+ </data>
+ </layer>
+</map>
104 sprites/Crono.js
@@ -0,0 +1,104 @@
+function Crono(){
+ // this is not used yet... or ever?
+ this.tileSize = 8;
+
+ this.animationMetrics = {
+ stop_down: [
+ {xStart: 126, yStart: 0 , width: 16, height: 35, xHSOffset: 7, yHSOffset: 35, delay: 10}
+ ],
+ stop_left: [
+ {xStart: 167, yStart: 1 , width: 14, height: 34, xHSOffset: 7, yHSOffset: 34, delay: 10}
+ ],
+ stop_up: [
+ {xStart: 206, yStart: 1 , width: 16, height: 33, xHSOffset: 7, yHSOffset: 33, delay: 10}
+ ],
+ stop_right: [
+ {xStart: 247, yStart: 1 , width: 14, height: 34, xHSOffset: 7, yHSOffset: 34, delay: 10}
+ ],
+ walk_down: [
+ {xStart: 125, yStart: 600, width: 18, height: 35, xHSOffset: 9, yHSOffset: 35, delay: 2.3},
+ {xStart: 126, yStart: 641, width: 16, height: 34, xHSOffset: 8, yHSOffset: 34, delay: 2.3},
+ {xStart: 125, yStart: 682, width: 17, height: 32, xHSOffset: 8, yHSOffset: 32, delay: 2.3},
+ {xStart: 125, yStart: 720, width: 18, height: 35, xHSOffset: 8, yHSOffset: 35, delay: 2.3},
+ {xStart: 126, yStart: 761, width: 16, height: 34, xHSOffset: 7, yHSOffset: 34, delay: 2.3},
+ {xStart: 125, yStart: 802, width: 17, height: 32, xHSOffset: 8, yHSOffset: 32, delay: 2.3},
+ ],
+ walk_left: [
+ {xStart: 166, yStart: 601, width: 15, height: 34, xHSOffset: 7, yHSOffset: 34, delay: 2.3},
+ {xStart: 163, yStart: 642, width: 21, height: 32, xHSOffset: 9, yHSOffset: 32, delay: 2.3},
+ {xStart: 166, yStart: 681, width: 14, height: 33, xHSOffset: 7, yHSOffset: 33, delay: 2.3},
+ {xStart: 167, yStart: 721, width: 14, height: 34, xHSOffset: 7, yHSOffset: 34, delay: 2.3},
+ {xStart: 163, yStart: 762, width: 22, height: 32, xHSOffset: 10, yHSOffset: 32, delay: 2.3},
+ {xStart: 167, yStart: 801, width: 14, height: 33, xHSOffset: 7, yHSOffset: 33, delay: 2.3}
+ ],
+ walk_up: [
+ {xStart: 205, yStart: 601, width: 18, height: 33, xHSOffset: 8, yHSOffset: 33, delay: 2.3},
+ {xStart: 206, yStart: 640, width: 16, height: 35, xHSOffset: 6, yHSOffset: 36, delay: 2.3},
+ {xStart: 205, yStart: 682, width: 18, height: 32, xHSOffset: 8, yHSOffset: 32, delay: 2.3},
+ {xStart: 205, yStart: 721, width: 18, height: 33, xHSOffset: 8, yHSOffset: 33, delay: 2.3},
+ {xStart: 206, yStart: 760, width: 16, height: 35, xHSOffset: 8, yHSOffset: 36, delay: 2.3},
+ {xStart: 205, yStart: 802, width: 18, height: 32, xHSOffset: 8, yHSOffset: 32, delay: 2.3}
+ ],
+ walk_right: [
+ {xStart: 246, yStart: 601, width: 15, height: 34, xHSOffset: 8, yHSOffset: 34, delay: 2.3},
+ {xStart: 243, yStart: 642, width: 21, height: 32, xHSOffset: 11, yHSOffset: 32, delay: 2.3},
+ {xStart: 247, yStart: 681, width: 14, height: 33, xHSOffset: 7, yHSOffset: 33, delay: 2.3},
+ {xStart: 247, yStart: 721, width: 14, height: 34, xHSOffset: 7, yHSOffset: 34, delay: 2.3},
+ {xStart: 243, yStart: 762, width: 22, height: 32, xHSOffset: 11, yHSOffset: 32, delay: 2.3},
+ {xStart: 247, yStart: 801, width: 14, height: 33, xHSOffset: 7, yHSOffset: 33, delay: 2.3}
+ ],
+
+ run_down : [
+ {xStart: 125, yStart: 600, width: 18, height: 35, xHSOffset: 9, yHSOffset: 35, delay: 2.3},
+ {xStart: 125, yStart: 841, width: 18, height: 35, xHSOffset: 9, yHSOffset: 35, delay: 2.3}, //
+ {xStart: 125, yStart: 682, width: 17, height: 32, xHSOffset: 8, yHSOffset: 32, delay: 2.3},
+ {xStart: 125, yStart: 720, width: 18, height: 35, xHSOffset: 8, yHSOffset: 35, delay: 2.3},
+ {xStart: 125, yStart: 881, width: 18, height: 35, xHSOffset: 7, yHSOffset: 35, delay: 2.3}, //
+ {xStart: 125, yStart: 802, width: 17, height: 32, xHSOffset: 8, yHSOffset: 32, delay: 2.3},
+ ],
+ run_left: [
+ {xStart: 166, yStart: 601, width: 15, height: 34, xHSOffset: 7, yHSOffset: 34, delay: 2.3},
+ {xStart: 160, yStart: 882, width: 28, height: 32, xHSOffset: 11, yHSOffset: 32, delay: 2.3}, //
+ {xStart: 166, yStart: 681, width: 14, height: 33, xHSOffset: 7, yHSOffset: 33, delay: 2.3},
+ {xStart: 167, yStart: 721, width: 14, height: 34, xHSOffset: 7, yHSOffset: 34, delay: 2.3},
+ {xStart: 160, yStart: 842, width: 28, height: 32, xHSOffset: 11, yHSOffset: 32, delay: 2.3}, //
+ {xStart: 167, yStart: 801, width: 14, height: 33, xHSOffset: 7, yHSOffset: 33, delay: 2.3}
+ ],
+ run_up: [
+ {xStart: 205, yStart: 601, width: 18, height: 33, xHSOffset: 8, yHSOffset: 33, delay: 2.3},
+ {xStart: 205, yStart: 839, width: 17, height: 38, xHSOffset: 6, yHSOffset: 36, delay: 2.3}, //
+ {xStart: 205, yStart: 682, width: 18, height: 32, xHSOffset: 8, yHSOffset: 32, delay: 2.3},
+ {xStart: 205, yStart: 721, width: 18, height: 33, xHSOffset: 8, yHSOffset: 33, delay: 2.3},
+ {xStart: 205, yStart: 879, width: 17, height: 38, xHSOffset: 9, yHSOffset: 36, delay: 2.3}, //
+ {xStart: 205, yStart: 802, width: 18, height: 32, xHSOffset: 8, yHSOffset: 32, delay: 2.3}
+ ],
+ run_right: [
+ {xStart: 246, yStart: 601, width: 15, height: 34, xHSOffset: 8, yHSOffset: 34, delay: 2.3},
+ {xStart: 240, yStart: 882, width: 28, height: 32, xHSOffset: 17, yHSOffset: 32, delay: 2.3}, //
+ {xStart: 247, yStart: 681, width: 14, height: 33, xHSOffset: 7, yHSOffset: 33, delay: 2.3},
+ {xStart: 247, yStart: 721, width: 14, height: 34, xHSOffset: 7, yHSOffset: 34, delay: 2.3},
+ {xStart: 240, yStart: 842, width: 28, height: 32, xHSOffset: 17, yHSOffset: 32, delay: 2.3}, //
+ {xStart: 247, yStart: 801, width: 14, height: 33, xHSOffset: 7, yHSOffset: 33, delay: 2.3}
+ ],
+ };
+
+ //this.sheetSrc = "../sprites/Crono-Horizontal.png";
+ this.sheetSrc = 'Crono';
+
+ this.walkSpeed = 2;
+ this.runSpeed = 4;
+
+ this.isRunning = false;
+
+ // call parent constructor
+ ComplexSprite.call(this, this.sheetSrc, this.animationMetrics);
+}
+
+Crono.prototype = new ComplexSprite();
+Crono.prototype.constructor = Crono;
+Crono.prototype.getSpeed = function(){
+ if(this.isRunning === true)
+ return this.runSpeed;
+ else
+ return this.walkSpeed;
+}
BIN  sprites/Crono.png
Diff not rendered
25 sprites/LightPillar.js
@@ -0,0 +1,25 @@
+function LightPillar(){
+ this.animationMetrics = {
+ stop_down: [
+ //{xStart: 0, yStart: 0 , width: 16, height: 32, xHSOffset: 8, yHSOffset: 25, delay: 15},
+ {xStart: 16, yStart: 0 , width: 16, height: 32, xHSOffset: 8, yHSOffset: 25, delay: 2},
+ {xStart: 32, yStart: 0 , width: 16, height: 32, xHSOffset: 8, yHSOffset: 25, delay: 2},
+ {xStart: 48, yStart: 0 , width: 16, height: 32, xHSOffset: 8, yHSOffset: 25, delay: 2},
+ {xStart: 64, yStart: 0 , width: 16, height: 32, xHSOffset: 8, yHSOffset: 25, delay: 2},
+ {xStart: 80, yStart: 0 , width: 16, height: 32, xHSOffset: 8, yHSOffset: 25, delay: 2},
+ {xStart: 96, yStart: 0 , width: 16, height: 32, xHSOffset: 8, yHSOffset: 25, delay: 2},
+ {xStart: 112, yStart: 0 , width: 16, height: 32, xHSOffset: 8, yHSOffset: 25, delay: 2},
+ {xStart: 128, yStart: 0 , width: 16, height: 32, xHSOffset: 8, yHSOffset: 25, delay: 2},
+ {xStart: 144, yStart: 0 , width: 16, height: 32, xHSOffset: 8, yHSOffset: 25, delay: 2},
+ {xStart: 160, yStart: 0 , width: 16, height: 32, xHSOffset: 8, yHSOffset: 25, delay: 2},
+ {xStart: 176, yStart: 0 , width: 16, height: 32, xHSOffset: 8, yHSOffset: 25, delay: 2},
+ ]
+ }
+ this.sheetSrc = 'LightPillar';
+ // call parent constructor
+ ComplexSprite.call(this, this.sheetSrc, this.animationMetrics);
+ this.opacity = 0.5;
+}
+
+LightPillar.prototype = new ComplexSprite();
+LightPillar.prototype.constructor = LightPillar;
BIN  sprites/crono-horizontal.png
Diff not rendered
BIN  sprites/crono_all.png
Diff not rendered
BIN  sprites/pillar_of_light.png
Diff not rendered
69 src/AssetLoader.js
@@ -0,0 +1,69 @@
+function AssetLoader(onCompleteCallback){
+
+ this._db = {
+ images: [],
+ callbacks: {}
+ };
+ this.nLoaded = 0;
+ this.nTotal = 0;
+ this.callback = onCompleteCallback;
+}
+
+AssetLoader.prototype.queue = function(type, options){
+ if(type == 'image'){
+ this.nTotal++;
+ if(options.src !== undefined){
+ var i = new Image();
+ var me = this;
+ i.onload = function(e){
+ me.onLoad(e, me)
+ };
+ i.onerror = function(e){
+ me.onError(e, me);
+ }
+ //i.onabort = me.onAbort();
+ i.src = options.src;
+
+ if(options.name === undefined)
+ this._db.images['img_'+Math.random()] = i;
+ else
+ this._db.images[options.name] = i;
+ }
+ if(options.callback !== undefined){
+ this._db.callbacks[i] = callback;
+ }
+ }
+};
+
+AssetLoader.prototype.onLoad = function(e, me){
+ this.nLoaded++;
+ if(this._db.callbacks[me] !== undefined){
+ this._db.callbacks[me](); // this is completely untested
+ }
+ if(this.nLoaded == this.nTotal){
+ this.onComplete();
+ }
+}
+
+AssetLoader.prototype.onError = function(e, me){
+ console.log("ERROR: ", e);
+}
+
+AssetLoader.prototype.onComplete = function(){
+ this.callback();
+ console.log("all assets loaded");
+ console.log(this);
+}
+
+AssetLoader.prototype.getStatus = function(){
+ if(this._db.images.length > 0)
+ return { percent: this.nLoaded / this.nTotal, count: this.nLoaded +"/"+ this.nTotal };
+ else
+ return { percent: '0', count: '0/0'};
+}
+
+AssetLoader.prototype.getAsset = function(name){
+ if( this._db.images[name] !== undefined ){
+ return this._db.images[name];
+ }
+}
3  src/Camera.js
@@ -0,0 +1,3 @@
+function Camera(){
+
+}
6 src/Character.js
@@ -0,0 +1,6 @@
+function Character(){
+
+}
+
+Character.prototype = new ComplexSprite();
+Character.prototype.constructor = Character;
6 src/CharacterDatabase.js
@@ -0,0 +1,6 @@
+function CharacterDatabase(){
+
+}
+
+CharacterDatabase.prototype = new Database();
+CharacterDatabase.prototype.constructor = CharacterDatabase;
82 src/ComplexSprite.js
@@ -0,0 +1,82 @@
+/* Anything that needs complex user interaction, or multiple animations */
+
+function ComplexSprite(imgName, animationMetrics){
+ if(arguments.length > 0){
+ SimpleSprite.call(this);
+
+ this.sequences = {};
+ this.active = "walk_down";
+ this.lastFrame = 0;
+ this.delayCounter = 0;
+
+ this.tileSheet = CURE.as.getAsset(imgName);
+
+ for(var i in animationMetrics){
+ this.sequences[i] = animationMetrics[i];
+ }
+ }
+}
+
+ComplexSprite.prototype = new SimpleSprite();
+ComplexSprite.prototype.constructor = ComplexSprite;
+
+ // this doesn't do anything yet
+ComplexSprite.prototype.setSequence = function(sequenceName){
+ if( this.sequences[sequenceName] !== undefined ){
+ this.active = sequenceName;
+ }
+};
+// ctx: 2d context
+// mapX/Y: the xy of the map, relative to the canvas
+// spriteObject: this, basically
+ComplexSprite.prototype.draw = function(ctx, mapX, mapY, spriteObject){
+ if( spriteObject.animationMetrics[this.active] !== undefined ){
+
+ this.x = this.mapX - mapX;
+ this.y = this.mapY - mapY;
+
+ if(this.lastFrame >= spriteObject.animationMetrics[this.active].length){
+ this.lastFrame = 0;
+ }
+
+ ctx.globalAlpha = this.opacity;
+
+ ctx.drawImage(spriteObject.tileSheet,
+ spriteObject.animationMetrics[this.active][this.lastFrame]['xStart'],
+ spriteObject.animationMetrics[this.active][this.lastFrame]['yStart'],
+ spriteObject.animationMetrics[this.active][this.lastFrame]['width'],
+ spriteObject.animationMetrics[this.active][this.lastFrame]['height'],
+ this.x - spriteObject.animationMetrics[this.active][this.lastFrame]['xHSOffset'],
+ this.y - spriteObject.animationMetrics[this.active][this.lastFrame]['yHSOffset'],
+ spriteObject.animationMetrics[this.active][this.lastFrame]['width'],
+ spriteObject.animationMetrics[this.active][this.lastFrame]['height']);
+
+ ctx.globalAlpha = 1;
+
+ /*ctx.fillStyle = "rgb(200,0,0)";
+ ctx.fillRect (this.x, this.y, 2, 2);*/
+
+ /*ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
+ ctx.fillRect (30, 30, 55, 50);*/
+
+ if(this.delayCounter > spriteObject.animationMetrics[this.active][this.lastFrame]['delay']){
+ this.lastFrame++;
+ this.delayCounter = 0;
+ } else
+ this.delayCounter++;
+
+
+ }
+};
+ComplexSprite.prototype.moveRight = function(inc){
+ this.mapX += inc;
+};
+ComplexSprite.prototype.moveLeft = function(inc){
+ this.mapX -= inc;
+};
+ComplexSprite.prototype.moveUp = function(inc){
+ this.mapY -= inc;
+};
+ComplexSprite.prototype.moveDown = function(inc){
+ this.mapY += inc;
+};
29 src/Database.js
@@ -0,0 +1,29 @@
+/* this should be used as a catch-all db for mostly temporary
+ information, like event flags? */
+function Database(){
+ this._localToMap = {};
+ this._global = {};
+}
+
+Database.prototype = {
+ getMapFlag: function(key){
+ if(this._localToMap[key] !== undefined){
+ return this._localToMap[key];
+ } else {
+ return false;
+ }
+ },
+ setMapFlag: function(key, value){
+ this._localToMap[key] = value;
+ },
+ setGlobalFlag: function(key, value){
+ this._global.key = value;
+ },
+ getGlobalFlag: function(key){
+ if(this._global[key] !== undefined){
+ return this_global[key];
+ } else {
+ return false;
+ }
+ }
+};
3  src/Door.js
@@ -0,0 +1,3 @@
+function Door(triggerX, triggerY, destinationMap, destinationX, destinationY){
+
+}
62 src/Event.js
@@ -0,0 +1,62 @@
+function Event(type, location, radius, direction, trigger, options, repeatable){
+
+ if(arguments.length == 0)
+ return false;
+
+ this.type = type;
+ this.mapX = location.x;
+ this.mapY = location.y;
+ this.radius = radius;
+ this.facingX = direction.x;
+ this.facingY = direction.y;
+ this.trigger = trigger;
+ this.options = options;
+ this.complete = false;
+ this.repeatable = repeatable !== undefined ? repeatable : true;
+ this.enabled = true;
+ this.id = _id();
+ this.lastMessageNum = 0;
+ this.nextStep = 0;
+ this.selected = 0;
+ this.waiting = false;
+
+ function _id(){
+ return Math.floor(Math.random() * 100000000000000000);
+ }
+}
+
+Event.prototype = {
+ check: function(){
+
+ },
+ unload: function(){
+ this.enabled = false;
+ this.lastMessageNum = 0;
+ this.nextStep = 0;
+ this.complete = true;
+ this.selected = 0;
+ this.waiting = false;
+ if(this.options.onComplete !== undefined){
+ this.options.onComplete(this);
+ }
+ },
+ reload: function(){
+ this.enabled = true;
+ this.complete = false;
+ this.lastMessageNum = 0;
+ this.nextStep = 0;
+ this.selected = 0;
+ this.waiting = false;
+ }
+};
+
+// types of events
+Event.GENERIC = "GENERIC";
+Event.MESSAGE = 'MESSAGE';
+Event.BATTLE = 'BATTLE';
+Event.CHOICE = 'CHOICE'; // display list of options to the user?
+Event.COMPLEX = "COMPLEX"; // some sort of combo of animations, battle, messages, etc
+
+// event triggers
+Event.ACTIVATE = 'ACTIVATE'; // press the ACTIVATE key near the event
+Event.PROXIMITY = 'PROXIMITY';
35 src/FPSMonitor.js
@@ -0,0 +1,35 @@
+function FPSMonitor(){
+ this.startTime = new Date().getTime(),
+ this.time,
+ this.frameTime,
+ this.prevFrameTime = this.getTimer(),
+ this.secondTime,
+ this.prevSecondTime = this.getTimer(),
+ this.frames = 0,
+ this.fps = "...";
+}
+
+FPSMonitor.prototype = {
+ check: function(){
+ this.time = this.getTimer();
+
+ this.frameTime = this.time - this.prevFrameTime;
+ this.secondTime = this.time - this.prevSecondTime;
+
+ if(this.secondTime >= 1000) {
+ this.fps = this.frames.toString();
+ this.frames = 0;
+ this.prevSecondTime = this.time;
+ }
+ else
+ {
+ this.frames++;
+ }
+
+ this.prevFrameTime = this.time;
+ return ((this.fps + " FPS / ") + this.frameTime) + " MS";
+ },
+ getTimer: function(){
+ return new Date().getTime() - this.startTime;
+ }
+};
192 src/InputDetection.js
@@ -0,0 +1,192 @@
+function InputDetection(window, rpg){
+
+ this.delayed = [];
+ this.delayed[InputDetection.SPACE] = '300';
+ this.timers = [];
+ this.rpg = rpg;
+ this.listeners = {};
+
+ var me = this;
+
+ this.pressed = [];
+ this.lastkey = 0;
+ this.window = window;
+ this.window.addEventListener('keydown', function(e){
+ me._onKeyDown(e);
+ if(e.keyCode == InputDetection.CTRL && me.rpg.ref != null)
+ me.rpg.stop();
+ else if(e.keyCode == InputDetection.CTRL && me.rpg.ref == null)
+ me.rpg.start();
+ }, false);
+ this.window.addEventListener('keyup', function(e){
+ me._onKeyUp(e);
+ }, false);
+
+}
+
+InputDetection.prototype = {
+ _onKeyDown: function(e){
+ this.pressed[e.keyCode] = true;
+ },
+ _onKeyUp: function(e){
+ this.pressed[e.keyCode] = undefined;
+ this.lastkey = e.keyCode;
+ if(this.listeners[e.keyCode] !== undefined){
+ this.listeners[e.keyCode](e.keyCode, CURE); // run callback
+ }
+ },
+ isDown: function(key){
+ // key is registered as a delayed key
+ if(this.delayed[key] !== undefined && this._isReady(key) == true && this.pressed[key] == true){
+ return true;
+ } else if(this.delayed[key] === undefined && this.pressed[key] == true) {
+ return true;
+ } else {
+ return false;
+ }
+ },
+ isUp: function(key){
+ return this.pressed[key];
+ },
+ last: function(){
+ return this.lastkey;
+ },
+ _isReady: function(key){
+ // if a timer exists, it's been pushed and is not ready
+ if(this.timers[key] === undefined){
+ return true;
+ } else {
+ return false;
+ }
+ },
+ hit: function(key){
+ if(this.delayed[key] !== undefined && this.timers[key] === undefined){
+ this.timers[key] = new Date().getTime();
+ }
+ },
+ setReady: function(key){
+ this.timers.splice(key, 1);
+ },
+ ellapse: function(){
+ var now = new Date().getTime();
+ for(var key in this.timers){
+ // remove marker from timers if key is ready
+ if(now - this.timers[key] >= this.delayed[key]){
+ this.timers.splice(key, 1);
+ //console.log(this.timers);
+ console.log(key + " ready for hit");
+ }
+ }
+ },
+ addKeyListener: function(keyConst, callback){
+ this.listeners[keyConst] = callback;
+ },
+ removeKeyListener: function(keyConst){
+ this.listeners[keyConst] = undefined;
+ }
+};
+
+InputDetection.SPACE = 32 ;
+InputDetection.BACKSPACE = 8 ;
+InputDetection.TAB = 9 ;
+InputDetection.ENTER = 13 ;
+InputDetection.SHIFT = 16 ;
+InputDetection.CTRL = 17 ;
+InputDetection.ALT = 18 ;
+InputDetection.PAUSE_BREAK = 19 ;
+InputDetection.CAPS_LOCK = 20 ;
+InputDetection.ESCAPE = 27 ;
+InputDetection.PAGE_UP = 33 ;
+InputDetection.PAGE_DOWN = 34 ;
+InputDetection.END = 35 ;
+InputDetection.HOME = 36 ;
+InputDetection.LEFT_ARROW = 37 ;
+InputDetection.UP_ARROW = 38 ;
+InputDetection.RIGHT_ARROW = 39 ;
+InputDetection.DOWN_ARROW = 40 ;
+InputDetection.INSERT = 45 ;
+InputDetection.DELETE = 46 ;
+
+InputDetection.ZERO = 48 ;
+InputDetection.ONE = 49 ;
+InputDetection.TWO = 50 ;
+InputDetection.THREE = 51 ;
+InputDetection.FOUR = 52 ;
+InputDetection.FIVE = 53 ;
+InputDetection.SIX = 54 ;
+InputDetection.SEVEN = 55 ;
+InputDetection.EIGHT = 56 ;
+InputDetection.NINE = 57 ;
+
+InputDetection.A = 65 ;
+InputDetection.B = 66 ;
+InputDetection.C = 67 ;
+InputDetection.D = 68 ;
+InputDetection.E = 69 ;
+InputDetection.F = 70 ;
+InputDetection.G = 71 ;
+InputDetection.H = 72 ;
+InputDetection.I = 73 ;
+InputDetection.J = 74 ;
+InputDetection.K = 75 ;
+InputDetection.L = 76 ;
+InputDetection.M = 77 ;
+InputDetection.N = 78 ;
+InputDetection.O = 79 ;
+InputDetection.P = 80 ;
+InputDetection.Q = 81 ;
+InputDetection.R = 82 ;
+InputDetection.S = 83 ;
+InputDetection.T = 84 ;
+InputDetection.U = 85 ;
+InputDetection.V = 86 ;
+InputDetection.W = 87 ;
+InputDetection.X = 88 ;
+InputDetection.Y = 89 ;
+InputDetection.Z = 90 ;
+
+InputDetection.LEFT_WINDOWS = 91 ;
+InputDetection.RIGHT_WINDOWS = 92 ;
+
+InputDetection.NUMPAD0 = 96 ;
+InputDetection.NUMPAD1 = 97 ;
+InputDetection.NUMPAD2 = 98 ;
+InputDetection.NUMPAD3 = 99 ;
+InputDetection.NUMPAD4 = 100;
+InputDetection.NUMPAD5 = 101;
+InputDetection.NUMPAD6 = 102;
+InputDetection.NUMPAD7 = 103;
+InputDetection.NUMPAD8 = 104;
+InputDetection.NUMPAD9 = 105;
+
+InputDetection.MULTIPLY = 106;
+InputDetection.ADD = 107;
+InputDetection.SUBTRACT = 109;
+InputDetection.DECIMAL_POINT = 110;
+InputDetection.DIVIDE = 111;
+
+InputDetection.F1 = 112;
+InputDetection.F2 = 113;
+InputDetection.F3 = 114;
+InputDetection.F4 = 115;
+InputDetection.F5 = 116;
+InputDetection.F6 = 117;
+InputDetection.F7 = 118;
+InputDetection.F8 = 119;
+InputDetection.F9 = 120;
+InputDetection.F10 = 121;
+InputDetection.F11 = 122;
+InputDetection.F12 = 123;
+InputDetection.NUM_LOCK = 144;
+InputDetection.SCROLL_LOCK = 145;
+InputDetection.SEMICOLON = 186;
+InputDetection.EQUAL_SIGN = 187;
+InputDetection.COMMA = 188;
+InputDetection.DASH = 189;
+InputDetection.PERIOD = 190;
+InputDetection.FORWARD_SLASH = 191;
+InputDetection.GRAVE_ACCENT = 192;
+InputDetection.OPEN_BRACKET = 219;
+InputDetection.BACK_SLASH = 220;
+InputDetection.CLOSE_BRAKET = 221;
+InputDetection.SINGLE_QUOTE = 222;
130 src/Map.js
@@ -0,0 +1,130 @@
+function Map(name, assetName, vwidth, vheight, bgColor){
+
+ if(arguments.length == 0)
+ return false;
+
+ this.mapname = name;
+ this.assetName = assetName;
+ this.lower_visual = CURE.as.getAsset(assetName + "_lower");
+ this.upper_visual = CURE.as.getAsset(assetName + "_upper");
+
+ this.backgroundColor = bgColor;
+
+ this.vHeight = vheight;
+ this.vWidth = vwidth;
+
+ if(this.vWidth > this.lower_visual.width) this.vWidth = this.lower_visual.width;
+ if(this.vHeight > this.lower_visual.height) this.vHeight = this.lower_visual.height;
+
+ this.x = 0;
+ this.y = 0;
+
+ this.events,
+ //this.eventsToReload = [],
+ this.walkable, // says what's walkable and not (not visual)
+ //this.eventMap, // things you can interact with (NPCs?)
+ this.groundMap, // the bottom visual layer
+ this.overlays; // any number of visual layers that should be stacked
+}
+
+Map.prototype = {
+ drawBackground: function(ctx){
+ if(this.backgroundColor != ''){
+ ctx.fillStyle = "rgb(13,13,13)";
+ ctx.fillRect (0, 0, this.vWidth, this.vHeight);
+ }
+ },
+ drawUnderlays: function(ctx){
+ ctx.drawImage(this.lower_visual, this.x, this.y, this.vWidth, this.vHeight, 0, 0, this.vWidth, this.vHeight);
+ },
+ drawOverlays: function(ctx){
+ ctx.drawImage(this.upper_visual, this.x, this.y, this.vWidth, this.vHeight, 0, 0, this.vWidth, this.vHeight);
+ },
+ scrollRight: function(inc){
+ this.x += inc;
+ if(this.x > this.lower_visual.width - this.vWidth) this.x = this.lower_visual.width - this.vWidth;
+ },
+ scrollLeft: function(inc){
+ this.x -= inc;
+ if(this.x < 0) this.x = 0;
+ },
+ scrollUp: function(inc){
+ this.y -= inc;
+ if(this.y < 0) this.y = 0;
+ },
+ scrollDown: function(inc){
+ this.y += inc;
+ if(this.y > this.lower_visual.height - this.vHeight) this.y = this.lower_visual.height - this.vHeight;
+ },
+ // scrolls to a point on the map, but attempts to place the point in the center of the canvas
+ scrollToAndCenter: function(x, y){
+ this.x = x - (0.5 * this.vWidth);
+ this.y = y - (0.5 * this.vHeight);
+
+ if(this.x < 0) this.x = 0;
+ if(this.x > this.lower_visual.width - this.vWidth) this.x = this.lower_visual.width - this.vWidth;
+
+ if(this.y < 0) this.y = 0;
+ if(this.y > this.lower_visual.height - this.vHeight) this.y = this.lower_visual.height - this.vHeight;
+ },
+ getNearestPolyEdge: function(poly, pt){
+ var i = 0;
+ var len = poly.length;
+ var min = 99999999;
+ var tempLength = 0;
+ var polypt = 0;
+
+ for(i = 0; i < len-1; i++){
+ tempLength = this.dotLineLength(pt.x, pt.y, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y, true);
+ if(tempLength < min) {
+ min = tempLength;
+ polypt = i;
+ }
+ }
+ return {start: polypt, end: polypt+1};
+ },
+ getSlopeOfPolyEdge: function(poly1, poly2){
+ //return Util.slope(poly1.x, poly1.y, poly2);
+ },
+ //+ Jonas Raoni Soares Silva
+ //@ http://jsfromhell.com/math/is-point-in-poly [rev. #0]
+ // poly is an array of point objects: [{x: ##, y: ##}, {} ...]
+ // pt is the point object
+ isPointInPoly: function (poly, pt){
+ for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
+ ((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y))
+ && (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)
+ && (c = !c);
+ return c;
+ },
+ //+ Jonas Raoni Soares Silva
+ //@ http://jsfromhell.com/math/dot-line-intersection [rev. #1]
+ dotLineIntersection: function(x, y, x0, y0, x1, y1){
+ if(!(x1 - x0))
+ return {x: x0, y: y};
+ else if(!(y1 - y0))
+ return {x: x, y: y0};
+ var left, tg = -1 / ((y1 - y0) / (x1 - x0));
+ return {x: left = (x1 * (x * tg - y + y0) + x0 * (x * - tg + y - y1)) / (tg * (x1 - x0) + y0 - y1), y: tg * left - tg * x + y};
+ },
+ //+ Jonas Raoni Soares Silva
+ //@ http://jsfromhell.com/math/dot-line-length [rev. #1]
+ dotLineLength: function(x, y, x0, y0, x1, y1, o){
+ function lineLength(x, y, x0, y0){
+ return Math.sqrt((x -= x0) * x + (y -= y0) * y);
+ }
+ if(o && !(o = function(x, y, x0, y0, x1, y1){
+ if(!(x1 - x0)) return {x: x0, y: y};
+ else if(!(y1 - y0)) return {x: x, y: y0};
+ var left, tg = -1 / ((y1 - y0) / (x1 - x0));
+ return {x: left = (x1 * (x * tg - y + y0) + x0 * (x * - tg + y - y1)) / (tg * (x1 - x0) + y0 - y1), y: tg * left - tg * x + y};
+ }(x, y, x0, y0, x1, y1), o.x >= Math.min(x0, x1) && o.x <= Math.max(x0, x1) && o.y >= Math.min(y0, y1) && o.y <= Math.max(y0, y1))){
+ var l1 = lineLength(x, y, x0, y0), l2 = lineLength(x, y, x1, y1);
+ return l1 > l2 ? l2 : l1;
+ }
+ else {
+ var a = y0 - y1, b = x1 - x0, c = x0 * y1 - y0 * x1;
+ return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b);
+ }
+ }
+};
3  src/MapLayer.js
@@ -0,0 +1,3 @@
+function MapLayer(){
+
+}
0  src/Message.js
No changes.
44 src/MonoMenu.js
@@ -0,0 +1,44 @@
+function MonoMenu(vWidth, vHeight){
+ this.mt = new MonoText('ct_en_mono', 8, 9, 0);
+ this.vWidth = vWidth;
+ this.vHeight = vHeight;
+
+ this.choices = [
+ "Yes", "No"
+ ];
+
+ this.children = [];
+}
+
+MonoMenu.prototype = {
+ showMenu: function(something){
+ var a = this.children[0] || this.createMenuCanvas(0, 0, this.vWidth * 2, this.vHeight * 2);
+ this.printTextAt(a.getContext('2d'), 5, 5, 100, 20, "This is text!!!! WE continue on the trek to infinite sanity. " + something);
+ },
+ printTextAt: function(ctx, x, y, width, height, text){
+ this.mt.print(ctx, text, x, y, width, height);
+ },
+ clearAt: function(x, y, width, height){
+
+ },
+ setBackground: function(resource){
+
+ },
+ createMenuCanvas: function(x, y, width, height){
+ var c = document.createElement('canvas');
+ c.width = width;
+ c.height = height;
+ c.x = x;
+ x.y = y;
+ c.style.border = "1px solid black";
+ c.style.position = "absolute";
+ c.style.left = "0px";
+ c.style.top = "0px";
+ //c.getContext('2d').scale(2, 2);
+ document.getElementById('controlWrap').appendChild(c);
+ this.children.push(c);
+ return c;
+ }
+
+};
+
196 src/MonoText.js
@@ -0,0 +1,196 @@
+/*
+ * Creates a monospaced text message box control, automatically
+ * handling kerning, text wrap, line height, etc.
+ *
+ * MonoText assumes that the png containing the font is on a
+ * single line, with a line height of 12 pixels, and a single
+ * pixel between characters (which can be variable width).
+ *
+ * This is dependent on an accurate kerning file for the font,
+ * which should be named the same as the png file, except having
+ * a js extension.
+ *
+ * @author Andrew Petersen kirbysayshi@gmail.com
+ */
+function MonoText(name, canvas, width, height, showbox, boxHPadding, boxVPadding, dKerning){
+
+ this.messageShowing = false;
+
+ this.canvas = canvas || document.createElement('canvas');
+ this.cwidth = width;
+ this.cheight = height;
+ this.context = canvas.getContext('2d');
+ this.ipath = "../font/"+name+".png";
+ this.defaultKern = dKerning;
+
+ this.boxname = showbox == true ? 'ct_grey.png': false;
+ this.boximage = new Image();
+
+ if(this.boxname != false){
+ this.boximage.src = '../images/windows/ct_grey.png';
+ this.boxY = this.cheight - this.boximage.height;
+ this.boxX = 0;
+ this.boxHPadding = boxHPadding;
+ this.boxVPadding = boxVPadding;
+ }else {
+ // TODO: this needs to make the text in the middle of the screen...
+
+ }
+
+ // this is loaded from global context...
+ this.kerngrid = kerning;
+
+ this.fimage = new Image();
+ this.fimage.src = this.ipath;
+
+ // holds messages in the queue. each time this.draw() is called, one message is printed
+ this.mgs = [];
+
+ // holds last message, for box position swapping
+ this.previousMessage = '';
+
+ return this.init();
+}
+
+MonoText.prototype = {
+ init: function(){
+ return this;
+ },
+
+ // prints the next message in the queue to the screen
+ printNextMessage: function(){
+
+ if(this.mgs.length > 0){
+ this.previousMessage = this.mgs.shift();
+ } else {
+ this.previousMessage = '';
+ this.messageShowing = false;
+ return false;
+ }
+
+ return true;
+ },
+
+ draw: function(ctx){
+ if(this.messageShowing == true){
+ //console.log('show message');
+
+ // draw box
+ if(this.boxname != false){
+ ctx.drawImage(this.boximage,
+ 0, 0, this.boximage.width, this.boximage.height,
+ this.boxX, this.boxY,
+ this.boximage.width, this.boximage.height);
+ }
+
+ /*if(this.previousMessage != '')
+ console.log(this.previousMessage);*/
+
+ var words = this.previousMessage.split(' ');
+ var col = this.boxHPadding;
+ var row = this.boxY + this.boxVPadding;
+
+ var printedLeftQuotes = false;
+
+ for(var w in words){
+
+ // if the length of this word's chars * 10 *multiplier is > the width + padding....
+ if( col + words[w].length*5 > this.cwidth - (2*this.boxHPadding)){
+ row += 15;
+ col = 12 + this.boxHPadding;
+ }
+
+ // special keywords for special symbols
+ switch(words[w]){
+ case 'MUSIC':
+ col += this.printChar(ctx, 'MUSIC', col, row);
+ break;
+ case 'HEART':
+ col += this.printChar(ctx, 'HEART', col, row);
+ col += this.printChar(ctx, " ", col, row);
+ break;
+ case '...':
+ col += this.printChar(ctx, 'ELLIPSES', col, row);
+ col += this.printChar(ctx, " ", col, row);
+ break;
+ case 'INFINITY':
+ col += this.printChar(ctx, 'INFINITY', col, row);
+ break;
+ case '<>':
+ col = 12 + this.boxHPadding;
+ row += 15;
+ break;
+ case 'POINTRIGHT':
+ col += this.printChar(ctx, 'POINTRIGHT', col, row);
+ col += this.printChar(ctx, " ", col, row);
+ break;
+ case 'POINTLEFT':
+ col += this.printChar(ctx, 'POINTLEFT', col, row);
+ col += this.printChar(ctx, " ", col, row);
+ break;
+ case 'POINTBLANK':
+ col += this.printChar(ctx, 'POINTBLANK', col, row);
+ col += this.printChar(ctx, " ", col, row);
+ break;
+ default:
+ var split = words[w].split('');
+
+ for(var l in split){
+
+ if(split[l] == '"' && printedLeftQuotes == true){
+ // right quote
+ col += this.printChar(ctx, 'RQUOTES', col, row );
+ printedLeftQuotes = false;
+ }else if(split[l] == '"' && printedLeftQuotes == false){
+ // left quote
+ col += this.printChar(ctx, 'LQUOTES', col, row );
+ printedLeftQuotes = true;
+ }else if(this.kerngrid[split[l]] != undefined){
+ // typical char
+ col += this.printChar(ctx, split[l], col, row );
+ }else {
+ // unrecognized character
+ col += this.printChar(ctx, ' ', col, row);
+ }
+ }
+ col += this.printChar(ctx, " ", col, row);
+ }
+
+ }
+ }
+ },
+
+ // prints a single character to the screen at the specified coordinates
+ printChar: function(ctx, character, x, y){
+ var ki = this.kerngrid[character];
+ ctx.drawImage(this.fimage,
+ ki.start, 0, ki.end-ki.start, 12,
+ x, y,
+ ki.end-ki.start, 12);
+ return (ki.end - ki.start) + this.defaultKern; // 0.5 for slight space.
+ },
+
+ // adds a message to the message queue
+ message: function(txt){
+ this.mgs.push(txt);
+ this.messageShowing = true;
+ },
+
+ // swaps the position of the box from either the top of the screen or the bottom
+ swapPosition: function(){
+ if(this.boxY != 0)
+ this.boxY = 0;
+ else
+ this.boxY = this.cheight - this.boximage.height;
+
+ if( this.previousMessage != ''){
+ this.mgs.unshift(this.previousMessage);
+ this.printNextMessage();
+ }
+ },
+
+ // removes the box, in the event that no messages exist
+ clear: function(){
+ this.context.clearRect(0, 0, this.cwidth, this.cheight);
+ }
+};
141 src/MonoTextII.js
@@ -0,0 +1,141 @@
+/*
+ * Creates a monospaced text message box control, automatically
+ * handling kerning, text wrap, line height, etc.
+ *
+ * MonoText assumes that the png containing the font is on a
+ * single line, with a line height of 12 pixels, and a single
+ * pixel between characters (which can be variable width).
+ *
+ * This is dependent on an accurate kerning file for the font,
+ * which should be named the same as the png file, except having
+ * a js extension.
+ *
+ * @author Andrew Petersen kirbysayshi@gmail.com
+ */
+function MonoText(name, boxHPadding, boxVPadding, dKerning){
+
+ this.messageShowing = false;
+
+ this.ipath = "../font/"+name+".png";
+ this.defaultKern = dKerning;
+
+ // this is loaded from global context...
+ this.kerngrid = kerning;
+
+ this.fimage = new Image();
+ this.fimage.src = this.ipath;
+
+ // holds messages in the queue. each time this.draw() is called, one message is printed
+ this.mgs = [];
+
+ // holds last message, for box position swapping
+ this.previousMessage = '';
+
+ return this.init();
+}
+
+MonoText.prototype = {
+ init: function(){
+ return this;
+ },
+
+ print: function(ctx, text, startX, startY, width, height){
+
+ ctx.clearRect(0, 0, width, height);
+
+ var words = text.split(' ');
+ var col = startX;
+ var row = startY;
+
+ var printedLeftQuotes = false;
+
+ for(var w in words){
+
+ // if the length of this word's chars * 10 *multiplier is > the width + padding....
+ if( col + words[w].length*5 > width){
+ row += 15;
+ col = startX;
+ }
+
+ // special keywords for special symbols
+ switch(words[w]){
+ case 'MUSIC':
+ col += this.printChar(ctx, 'MUSIC', col, row);
+ break;
+ case 'HEART':
+ col += this.printChar(ctx, 'HEART', col, row);
+ col += this.printChar(ctx, " ", col, row);
+ break;
+ case '...':
+ col += this.printChar(ctx, 'ELLIPSES', col, row);
+ col += this.printChar(ctx, " ", col, row);
+ break;
+ case 'INFINITY':
+ col += this.printChar(ctx, 'INFINITY', col, row);
+ break;
+ case '<>':
+ col = 12 + this.boxHPadding;
+ row += 15;
+ break;
+ default:
+ var split = words[w].split('');
+
+ for(var l in split){
+
+ if(split[l] == '"' && printedLeftQuotes == true){
+ // right quote
+ col += this.printChar(ctx, 'RQUOTES', col, row );
+ printedLeftQuotes = false;
+ }else if(split[l] == '"' && printedLeftQuotes == false){
+ // left quote
+ col += this.printChar(ctx, 'LQUOTES', col, row );
+ printedLeftQuotes = true;
+ }else if(this.kerngrid[split[l]] != undefined){
+ // typical char
+ col += this.printChar(ctx, split[l], col, row );
+ }else {
+ // unrecognized character
+ col += this.printChar(ctx, ' ', col, row);
+ }
+ }
+ col += this.printChar(ctx, " ", col, row);
+ }
+
+ }
+
+ },
+
+ // prints a single character to the screen at the specified coordinates
+ printChar: function(ctx, character, x, y){
+ var ki = this.kerngrid[character];
+ ctx.drawImage(this.fimage,
+ ki.start, 0, ki.end-ki.start, 12,
+ x, y,
+ ki.end-ki.start, 12);
+ return (ki.end - ki.start) + this.defaultKern; // 0.5 for slight space.
+ },
+
+ // adds a message to the message queue
+ message: function(txt){
+ this.mgs.push(txt);
+ this.messageShowing = true;
+ },
+
+ // swaps the position of the box from either the top of the screen or the bottom
+ swapPosition: function(){
+ if(this.boxY != 0)
+ this.boxY = 0;
+ else
+ this.boxY = this.cheight - this.boximage.height;
+
+ if( this.previousMessage != ''){
+ this.mgs.unshift(this.previousMessage);
+ this.printNextMessage();
+ }
+ },
+
+ // removes the box, in the event that no messages exist
+ clear: function(){
+ this.context.clearRect(0, 0, this.cwidth, this.cheight);
+ }
+};
499 src/RPG.js
@@ -0,0 +1,499 @@
+// framerate is in frames per second...
+
+function RPG(window, canvas, frameRate, width, height){
+ this.window = window;
+ this.window.CURE = this;
+ this.canvas = canvas;
+ this.ctx = canvas.getContext('2d');
+ this.frameRate = frameRate;
+ this.frameInterval = 1000 / this.frameRate;
+ this.ref = null;
+ this.width = width;
+ this.height = height;
+
+ this.messageMaxLines = 4;
+
+ // populated by dev
+ this.assetList = {};
+ this.as = new AssetLoader(function(){
+ CURE.onPreloadComplete();
+ });
+
+ this.key = new InputDetection(this.window, this);
+ this.key.addKeyListener(InputDetection.DOWN_ARROW, CURE.checkMenuEvents);
+ this.key.addKeyListener(InputDetection.UP_ARROW, CURE.checkMenuEvents);
+ this.key.addKeyListener(InputDetection.LEFT_ARROW, CURE.checkMenuEvents);
+ this.key.addKeyListener(InputDetection.RIGHT_ARROW, CURE.checkMenuEvents);
+
+ this.mt = new MonoText('ct_en_mono', this.canvas, 256, 224, true, 8, 9, 0);
+
+ this.renderObjects = Array();
+ this.addedObjects = Array();
+
+ this.backBuffer = document.createElement('canvas');
+ this.backBuffer.width = this.canvas.width;
+ this.backBuffer.height = this.canvas.height;
+ this.backCtx = this.backBuffer.getContext('2d');
+
+ this.currentEvent = 0;
+
+ this.db = new Database();
+}
+
+RPG.prototype = {
+ preload: function(){
+ for(var a in this.assetList){
+ console.log(a);
+ this.as.queue( this.assetList[a][0], {src: this.assetList[a][1], name: a} );
+ }
+ },
+ onPreloadComplete: function(){
+
+ this.hero = new Crono();
+ this.hero.setPositionOnMap(215, 168);
+ this.hero.setSequence('stop_down');
+ this.addChild(this.hero);
+
+ this.map = new EndOfTime(this.width, this.height);
+ this.map.scrollRight(75);
+ this.map.scrollDown(80);
+
+ this.start();
+ },
+ start: function(){
+ var me = this;
+ me.ref = setInterval(function(){
+ me.main();
+ }, this.frameInterval);
+ },
+ stop: function(){
+ clearInterval(this.ref);
+ this.ref = null;
+ },
+ main: function(){
+ // default, will probably be overriden by developer
+ this.render();
+ this.checkInput();
+ this.key.ellapse();
+ this.checkProximityEvents();
+ },
+ addChild: function(obj){
+ this.addedObjects.push(obj);
+ },
+ _processNewChildren: function(){
+ if( this.addedObjects.length != 0){
+ for(var i = 0; i < this.addedObjects.length; i++){
+ this.renderObjects.push(this.addedObjects[i]);
+ }
+ this.addedObjects = new Array();
+ this._zSort();
+ }
+ },
+ _zSort: function(){
+ this.renderObjects.sort(function(a,b){return a.z - b.z;});
+ return this;
+ },
+ render: function(){
+ this.backCtx.clearRect(0, 0, this.backBuffer.width, this.backBuffer.height);
+ // process current map layers
+ this.map.drawBackground(this.backCtx);
+ this.map.drawUnderlays(this.backCtx);
+
+ // process display list
+ this._processNewChildren();
+ for(var i = 0; i < this.renderObjects.length; i++){
+ this.renderObjects[i].draw(this.backCtx, this.map.x, this.map.y, this.renderObjects[i]);
+ for(var c = 0; c < this.renderObjects[i].children.length; c++){
+ this.renderObjects[i].children[i].draw(this.backCtx, this.map.x, this.map.y, this.renderObjects[i].children[i]);
+ }
+ }
+
+ this.map.drawOverlays(this.backCtx);
+ this.mt.draw(this.backCtx);
+
+ this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+ this.ctx.drawImage(this.backBuffer, 0, 0);
+ },
+ // x,y: position of main char relative to VIEWPORT
+ scrollNeeded: function(direction, x, y){
+ //console.log(x - (this.map.vWidth * 0.5));
+ //console.log(y - (this.map.vHeight * 0.5));
+ var right = x - (this.map.vWidth * 0.5) > 0.1;
+ var left = x - (this.map.vWidth * 0.5) < -0.1;
+ var up = y - (this.map.vHeight * 0.5) < -0.1;
+ var down = y - (this.map.vHeight * 0.5) > 0.1;
+
+ if(direction == 'lowerright' && right && down){
+ return true;
+ } else if(direction == 'upperright' && right && up){
+ return true;
+ } else if(direction == 'lowerleft' && left && down){
+ return true;
+ } else if(direction == 'upperleft' && left && up){
+ return true;
+ } else if(direction == 'right' && right){
+ return true;
+ } else if(direction == 'left' && left){
+ return true;
+ } else if(direction == 'up' && up){
+ return true;
+ } else if(direction == 'down' && down){
+ return true;
+ } else
+ return false;
+ },
+ checkInput: function(){
+
+ // disable movement while a message is showing
+ if(this.mt.messageShowing == false){
+
+ if(this.key.lastkey == InputDetection.RIGHT_ARROW)
+ this.hero.setSequence('stop_right');
+ else if(this.key.lastkey == InputDetection.LEFT_ARROW)
+ this.hero.setSequence('stop_left');
+ else if(this.key.lastkey == InputDetection.UP_ARROW)
+ this.hero.setSequence('stop_up');
+ else if(this.key.lastkey == InputDetection.DOWN_ARROW)
+ this.hero.setSequence('stop_down');
+
+
+ var right = this.map.isPointInPoly(this.map.walkable, {
+ x: this.hero.mapX + this.hero.getSpeed(),
+ y: this.hero.mapY });
+
+ var left = this.map.isPointInPoly(this.map.walkable, {
+ x: this.hero.mapX - this.hero.getSpeed(),
+ y: this.hero.mapY });
+
+ var up = this.map.isPointInPoly(this.map.walkable, {
+ x: this.hero.mapX,
+ y: this.hero.mapY - this.hero.getSpeed()});
+
+ var down = this.map.isPointInPoly(this.map.walkable, {
+ x: this.hero.mapX,
+ y: this.hero.mapY + this.hero.getSpeed()});
+
+
+ var upperRight = this.map.isPointInPoly(this.map.walkable, {
+ x: this.hero.mapX + this.hero.getSpeed(),
+ y: this.hero.mapY - this.hero.getSpeed()});
+
+ var lowerRight = this.map.isPointInPoly(this.map.walkable, {
+ x: this.hero.mapX + this.hero.getSpeed(),
+ y: this.hero.mapY + this.hero.getSpeed()});
+
+ var upperLeft = this.map.isPointInPoly(this.map.walkable, {
+ x: this.hero.mapX - this.hero.getSpeed(),
+ y: this.hero.mapY - this.hero.getSpeed()});
+
+ var lowerLeft = this.map.isPointInPoly(this.map.walkable, {
+ x: this.hero.mapX - this.hero.getSpeed(),
+ y: this.hero.mapY + this.hero.getSpeed()});
+
+ // specific to if against a wall
+ var pt = this.map.getNearestPolyEdge(this.map.walkable, {x: this.hero.mapX, y: this.hero.mapY});
+ var slope = Util.slope( this.map.walkable[pt.start], this.map.walkable[pt.end] );
+ var mag = Util.magnitude(slope);
+ var A = {x: this.hero.mapX, y: this.hero.mapY};
+ var N = Util.normalize(slope, mag);
+ var posDestination = Util.addPointToVector(Util.multiplyVectorScalar(N, this.hero.getSpeed()), A);
+ posDestination.x = Math.round(posDestination.x);
+ posDestination.y = Math.round(posDestination.y);
+ var negDestination = Util.addPointToVector(Util.multiplyVectorScalar(N, -this.hero.getSpeed()), A);
+ negDestination.x = Math.round(negDestination.x);
+ negDestination.y = Math.round(negDestination.y);
+ var incPos = {x: Math.abs(posDestination.x - this.hero.mapX), y: Math.abs(posDestination.y - this.hero.mapY)};
+ var incNeg = {x: Math.abs(negDestination.x - this.hero.mapX), y: Math.abs(negDestination.y - this.hero.mapY)};
+ var incPosValid = this.map.isPointInPoly(this.map.walkable, posDestination);
+ var incNegValid = this.map.isPointInPoly(this.map.walkable, negDestination);
+
+
+ // MOVE RIGHT
+ if( this.key.isDown(InputDetection.RIGHT_ARROW) ) {
+
+ if(this.hero.isRunning == true)
+ this.hero.setSequence('run_right');
+ else
+ this.hero.setSequence('walk_right');
+
+ if(right){
+ this.hero.moveRight(this.hero.getSpeed());
+ if(this.scrollNeeded('right', this.hero.x, this.hero.y))
+ this.map.scrollRight(this.hero.getSpeed());
+
+ } else if(incPosValid){//if(lowerRight){
+
+ this.hero.setPositionOnMap(posDestination.x, posDestination.y);
+ if(this.scrollNeeded('lowerright', this.hero.x, this.hero.y)){
+ this.map.scrollRight(incPos.x);
+ this.map.scrollDown(incPos.y);
+ }
+ if(this.scrollNeeded('upperright', this.hero.x, this.hero.y)){
+ this.map.scrollRight(incPos.x);
+ this.map.scrollUp(incPos.y);
+ }
+ } else
+ this.hero.setSequence('stop_right');
+ }
+ // MOVE LEFT
+ if( this.key.isDown(InputDetection.LEFT_ARROW) ) {
+ //map.scrollLeft();
+
+ if(this.hero.isRunning == true)
+ this.hero.setSequence('run_left');
+ else
+ this.hero.setSequence('walk_left');
+
+ if(left){
+ this.hero.moveLeft(this.hero.getSpeed());
+ } else if(incNegValid){//if(lowerRight){
+
+ this.hero.setPositionOnMap(negDestination.x, negDestination.y);
+ if(this.scrollNeeded('lowerleft', this.hero.x, this.hero.y)){
+ this.map.scrollLeft(incNeg.x);
+ this.map.scrollDown(incNeg.y);
+ }
+ if(this.scrollNeeded('upperleft', this.hero.x, this.hero.y)){
+ this.map.scrollLeft(incNeg.x);
+ this.map.scrollUp(incNeg.y);
+ }
+ } else
+ this.hero.setSequence('stop_left');
+ if(this.scrollNeeded('left', this.hero.x, this.hero.y))
+ this.map.scrollLeft(this.hero.getSpeed());
+ }
+ // MOVE UP
+ if( this.key.isDown(InputDetection.UP_ARROW) ) {
+ //map.scrollUp();
+
+ if(this.hero.isRunning == true)
+ this.hero.setSequence('run_up');
+ else
+ this.hero.setSequence('walk_up');
+
+ if(up){
+ this.hero.moveUp(this.hero.getSpeed());
+ } else if(incNegValid){
+ if(slope > 0)
+ this.hero.setPositionOnMap(negDestination.x, negDestination.y);
+ if(slope < 0)
+ this.hero.setPositionOnMap(posDestination.x, posDestination.y);
+
+ if(this.scrollNeeded('upperright', this.hero.x, this.hero.y)){
+ this.map.scrollRight(incPos.x);
+ this.map.scrollUp(incPos.y);
+ }
+ if(this.scrollNeeded('upperleft', this.hero.x, this.hero.y)){
+ this.map.scrollLeft(incNeg.x);
+ this.map.scrollUp(incNeg.y);
+ }
+ } else
+ this.hero.setSequence('stop_up');
+ if(this.scrollNeeded('up', this.hero.x, this.hero.y))
+ this.map.scrollUp(this.hero.getSpeed());
+ }
+ // MOVE DOWN
+ if( this.key.isDown(InputDetection.DOWN_ARROW) ) {
+ //map.scrollDown();
+
+ if(this.hero.isRunning == true)
+ this.hero.setSequence('run_down');
+ else
+ this.hero.setSequence('walk_down');
+
+ if(down){
+ this.hero.moveDown(this.hero.getSpeed());
+ } else if(incPosValid){
+
+ if(slope > 0)
+ this.hero.setPositionOnMap(posDestination.x, posDestination.y);
+ if(slope < 0)
+ this.hero.setPositionOnMap(negDestination.x, negDestination.y);
+ if(this.scrollNeeded('lowerleft', this.hero.x, this.hero.y)){
+ this.map.scrollLeft(incNeg.x);
+ this.map.scrollDown(incNeg.y);
+ }
+ if(this.scrollNeeded('lowerright', this.hero.x, this.hero.y)){
+ this.map.scrollRight(incPos.x);
+ this.map.scrollDown(incPos.y);
+ }
+ } else
+ this.hero.setSequence('stop_down');
+ if(this.scrollNeeded('down', this.hero.x, this.hero.y))
+ this.map.scrollDown(this.hero.getSpeed());
+ }
+ }
+
+ // ACTIVATE
+ if( this.key.isDown(InputDetection.SPACE) ){
+ this.key.hit(InputDetection.SPACE); // this key is a toggle
+ console.log("space is down");
+ this.checkActivateEvents();
+ this.checkCurrentEvent();
+ if(this.currentEvent.waiting == false){
+ this.mt.printNextMessage();
+ } else {
+ // menu event has ended?!
+ if(this.currentEvent.complete == false){
+
+ this.currentEvent.options.choices[this.currentEvent.selected].payload();
+ this.currentEvent.unload();
+
+ if(this.currentEvent.repeatable == true){
+ this.currentEvent.reload();
+ }
+ this.currentEvent = 0;
+
+ }
+ this.mt.printNextMessage();
+ }
+ }
+
+ // Holding shift activates running
+ if( this.key.isDown(InputDetection.SHIFT) ){
+ this.hero.isRunning = true;
+ } else
+ this.hero.isRunning = false;
+ },
+ checkProximityEvents: function(){
+ for(var e = 0; e < this.map.events.length; e++){
+ var event = this.map.events[e];
+
+ if(event.trigger == Event.PROXIMITY){
+ var d = Util.distance(this.hero.mapX, this.hero.mapY, event.mapX, event.mapY);
+ if(d < event.radius){
+ if(event.type == Event.MESSAGE || event.type == Event.GENERIC){
+ if(this.currentEvent == 0 && event.enabled == true){
+ this.currentEvent = this.map.events[e];
+ console.log("proximity event");
+ this.checkCurrentEvent();
+ }
+ }
+ }
+ }
+ }
+ },
+ checkActivateEvents: function(){
+ if(this.currentEvent == 0){
+ for(var e = 0; e < this.map.events.length; e++){
+ var event = this.map.events[e];
+
+ if(event.trigger == Event.ACTIVATE){
+ var d = Util.distance(this.hero.mapX, this.hero.mapY, event.mapX, event.mapY);
+ if(d < event.radius){
+ if(event.type == Event.MESSAGE || event.type == Event.GENERIC || event.type == Event.CHOICE){
+ if(this.currentEvent == 0 && event.enabled == true){
+ this.currentEvent = this.map.events[e];
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ checkCurrentEvent: function(){
+ if(this.currentEvent != 0){
+ if(this.currentEvent.trigger == Event.ACTIVATE){
+ if(this.currentEvent.type == Event.MESSAGE){
+ if(this.currentEvent.lastMessageNum < this.currentEvent.options.text.length){
+ this.mt.message( this.currentEvent.options.text[this.currentEvent.lastMessageNum] );
+ this.currentEvent.lastMessageNum++;
+ } else {
+ this.currentEvent.unload();
+ if(this.currentEvent.repeatable == true){
+ this.currentEvent.reload();
+ }
+ this.currentEvent = 0;
+ }
+ } else if(this.currentEvent.type == Event.GENERIC){
+ if(this.currentEvent.nextStep < this.currentEvent.options.payload.length){
+ console.log('step:' + this.currentEvent.nextStep);
+ this.currentEvent.options.payload[this.currentEvent.nextStep]();
+ this.currentEvent.nextStep++;
+ } else {
+ this.currentEvent.unload();
+ if(this.currentEvent.repeatable == true){
+ this.currentEvent.reload();
+ }
+ this.currentEvent = 0;
+ }
+ } else if(this.currentEvent.type == Event.CHOICE){
+ var display = this.currentEvent.options.prompt + " <> ";
+ for(var c = this.currentEvent.nextStep; c < this.currentEvent.options.choices.length; c++){
+ if(c < this.currentEvent.nextStep + this.messageMaxLines - 1){
+ if(c == this.currentEvent.selected){
+ display += " POINTRIGHT ";
+ } else{
+ display += " POINTBLANK ";
+ }
+ display += this.currentEvent.options.choices[c].text + " <> ";
+ }
+ }
+ if(this.mt.messageShowing == false){
+ this.mt.message(display);
+ } else {
+ this.currentEvent.waiting = true;
+ this.mt.previousMessage = display;
+ }
+
+ }
+ } else if(this.currentEvent.trigger == Event.PROXIMITY){
+ if(this.currentEvent.type == Event.GENERIC){
+ if(this.currentEvent.complete == false){
+ this.currentEvent.unload();
+
+ if(this.currentEvent.repeatable == true){
+ this.currentEvent.reload();
+ }
+ this.currentEvent = 0;
+ }
+ }
+ }
+ }
+ },
+ checkMenuEvents: function(keyCode, scope){
+ if(scope.currentEvent != 0){
+ if(scope.currentEvent.type == Event.CHOICE){
+ switch(keyCode){
+ case InputDetection.DOWN_ARROW:
+ if(scope.currentEvent.selected + 1 < scope.currentEvent.options.choices.length){
+ scope.currentEvent.selected++;
+ scope.checkCurrentEvent();
+ }
+ if(scope.currentEvent.nextStep + scope.currentEvent.selected > 1
+ && scope.currentEvent.selected != scope.currentEvent.options.choices.length - 1){
+ scope.currentEvent.nextStep++;
+ if(scope.currentEvent.nextStep >= scope.currentEvent.options.choices.length){
+ scope.currentEvent.nextStep = scope.currentEvent.options.choices.length - 1;
+ }
+ scope.checkCurrentEvent();
+ }
+ break;
+ case InputDetection.UP_ARROW:
+ if(scope.currentEvent.selected - 1 >= 0){
+ scope.currentEvent.selected--;
+ scope.checkCurrentEvent();
+ }
+ if(scope.currentEvent.nextStep - 1 == scope.currentEvent.selected - 1){
+ scope.currentEvent.nextStep--;
+ if(scope.currentEvent.nextStep <= 0) scope.currentEvent.nextStep = 0;
+ scope.checkCurrentEvent();
+ }
+ break;
+ }
+ }
+ }
+ },
+ printDebugInfo: function(el){
+ el.innerHTML = "Map X Offset: "+this.map.x
+ +" <br />Map Y Offset: "+this.map.y+" <br />Hero MapX: "+this.hero.mapX
+ +" <br />Hero MapY: "+this.hero.mapY+" <br />Hero ScreenX: "+this.hero.x
+ +" <br />Hero ScreenY: "+this.hero.y;
+ },
+ switchMap: function(nameOfMap, heroX, heroY){
+ var MapClass = eval(nameOfMap);
+ this.map = new MapClass(this.width, this.height);
+ this.hero.setPositionOnMap(heroX, heroY);
+ this.map.scrollToAndCenter(heroX, heroY);
+ }
+};
55 src/SimpleSprite.js
<
@@ -0,0 +1,55 @@
+function SimpleSprite(){
+ this.name = "ss_" + Math.floor(Math.random() * 256000000);
+
+ this.image = new Image();
+
+ // location of the sprite relative to the upper left corner of the canvas/drawing area
+ this.x = 0;
+ this.y = 0;
+ this.z = 0;
+
+ // location of the sprite relative to the upper left corner of the map
+ this.mapX = 0;
+ this.mapY = 0;
+
+ this.opacity = 1;
+ this.addedObjects = [];
+ this.children = [];
+}
+
+SimpleSprite.prototype = {
+ // ctx: 2d drawing context
+ // x,y: the map x/y offset
+ draw: function(ctx, x, y){
+ ctx.globalAlpha = this.opacity;
+ ctx.drawImage(this.image, x, y);
+ ctx.globalAlpha = 1;
+ },
+ drawChildren: function(ctx, mapX, mapY, spriteObject){
+ this._processNewChildren();
+ for(var i = 0; i < this.children.length; i++){
+ this.children[i].draw(ctx, mapX, mapY, spriteObject);
+ this.children[i].drawChildren(ctx, mapX, mapY, spriteObject);
+ }