Created
June 16, 2014 05:37
-
-
Save YellowAfterlife/02bcc3dee235c04800a9 to your computer and use it in GitHub Desktop.
Tululoo export.js file with support for canvas scaling.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************************* | |
* Tululoo Game Maker //TULULOO_VERSION | |
* | |
* Creators | |
* Zoltan Percsich | |
* Vadim "YellowAfterlife" Dyachenko | |
* | |
* (c) SilentWorks 2011 - 2014 | |
* All rights reserved. | |
* www.tululoo.com | |
* | |
* Contributors: | |
* Csaba Herbut | |
********************************************/ | |
function tu_detect_audio(_type) { | |
var _au = document.createElement('audio'); | |
return _au.canPlayType && _au.canPlayType(_type).replace(/no/, ''); | |
} | |
// | |
var __path__ = window.__path__ ? window.__path__ : '', | |
// system variables: | |
tu_gameloop = tu_canvas = tu_context = tu_room_to_go = null, tu_canvas_id = 'tululoocanvas', | |
tu_canvas_css = 'background: rgb(42, 42, 42); border: 0;', | |
tu_loading = tu_load_total = 0, | |
var_override_ = (Object.defineProperty != undefined), | |
// resources: | |
tu_sprites = [], tu_audios = [], tu_backgrounds = [], tu_fonts = [], tu_scenes = [], | |
// time: | |
tu_frame_time = tu_frame_step = tu_frame_el = tu_frame_count = tu_elapsed = 0, | |
tu_prev_cycle_time = tu_prev_frame_time = (new Date()).getTime(), | |
// math: | |
max = Math.max, min = Math.min, round = Math.round, floor = Math.floor, ceil = Math.ceil, | |
sin = Math.sin, cos = Math.cos, sqrt = Math.sqrt, tan = Math.tan, rand = Math.random, | |
arccos = Math.acos, arcsin = Math.asin, arctan = Math.atan, arctan2 = Math.atan2, | |
tu_r2d = -180 / Math.PI, tu_d2r = Math.PI / -180, tu_2pi = Math.PI * 2, | |
// i/o variables: | |
mouse_x = mouse_y = 0, mouse_down = mouse_pressed = mouse_released = false, | |
key_down = [], key_pressed = [], key_released = [], tu_vkeys = [], | |
tu_keys_pressed = [], tu_keys_released = [], | |
touch_x = [], touch_y = [], touch_count = 0, | |
tu_unpausekey = 27, tu_paused = false, tu_modal = null, tu_modaldraw = true, | |
// i/o constants: | |
vk_0 = 48, vk_1 = 49, vk_2 = 50, vk_3 = 51, vk_4 = 52, vk_5 = 53, vk_6 = 54, | |
vk_7 = 55, vk_8 = 56, vk_9 = 57, vk_a = 65, vk_add = 107, vk_alt = 18, vk_b = 66, | |
vk_backspace = 8, vk_c = 67, vk_ctrl = 17, vk_d = 68, vk_decimal = 110, vk_delete = 46, | |
vk_divide = 111, vk_down = 40, vk_e = 69, vk_end = 35, vk_enter = 13, vk_escape = 27, | |
vk_f1 = 112, vk_f2 = 113, vk_f3 = 114, vk_f4 = 115, vk_f5 = 116, vk_f6 = 117, | |
vk_f7 = 118, vk_f8 = 119, vk_f9 = 120, vk_f10 = 121, vk_f11 = 122, vk_f12 = 123, | |
vk_g = 71, vk_h = 72, vk_home = 36, vk_f = 70, vk_i = 73, vk_insert = 45, vk_j = 74, vk_k = 75, | |
vk_l = 76, vk_left = 37, vk_m = 77, vk_multiply = 106, vk_n = 78, vk_num0 = 96, vk_num1 = 97, | |
vk_num2 = 98, vk_num3 = 99, vk_num4 = 100, vk_num5 = 101, vk_num6 = 102, vk_num7 = 103, | |
vk_num8 = 104, vk_num9 = 105, vk_o = 79, vk_p = 80, vk_pagedown = 34, vk_pageup = 33, | |
vk_pause = 19, vk_q = 81, vk_r = 82, vk_right = 39, vk_s = 83, vk_shift = 16, vk_space = 32, | |
vk_subtract = 109, vk_t = 84, vk_tab = 9, vk_u = 85, vk_up = 38, vk_v = 86, vk_w = 87, | |
vk_x = 88, vk_y = 89, vk_z = 90, | |
// collisions: | |
ct_null = 0, ct_point = 1, ct_box = 2, ct_circle = 3, | |
// tiles: | |
tu_tiles = [], tu_tilesi = [], tu_tilez = 256, | |
// sound variables: | |
tu_wav_supported = tu_detect_audio('audio/wav; codecs="1"'), | |
tu_ogg_supported = tu_detect_audio('audio/ogg; codecs="vorbis"'), | |
tu_mp3_supported = tu_detect_audio('audio/mpeg;'), | |
// drawing: | |
tu_draw_alpha = 1, tu_draw_color_red = tu_draw_color_green = tu_draw_color_blue = 0, | |
tu_draw_font = "Arial 12px", tu_draw_halign = "left", tu_draw_valign = "top", | |
tu_draw_font_ = { size: 12, family: 'Arial', bold: false, italic: false }, | |
tu_draw_color = "rgb(" + tu_draw_color_red + "," + | |
tu_draw_color_green + "," + tu_draw_color_blue + ")", | |
tu_redraw, tu_redraw_auto = true, | |
tu_viewport_inst = null, | |
// drawing constants: | |
fa_left = "left", fa_center = "center", fa_right = "right", | |
fa_top = "top", fa_middle = "middle", fa_bottom = "bottom", | |
// system room variables: | |
tu_depth = [], tu_depthi = [], tu_depthu = [], tu_types = [], tu_persist = [], | |
// public room variables: | |
room_current = null, | |
room_speed = 30, fps = room_speed, | |
room_background = null, | |
room_width = 0, room_height = 0, | |
room_background_color_show = true, room_background_color_red = 0, | |
room_background_color_green = 0, room_background_color_blue = 0, | |
room_viewport_width = 0, room_viewport_height = 0, | |
room_viewport_object = null, | |
room_viewport_hborder = 0, room_viewport_vborder = 0, | |
room_viewport_x = 0, room_viewport_y = 0, | |
global = null; | |
// keyboard functions: | |
function keyboard_check(_key) { return key_down[_key]; } | |
function keyboard_check_pressed(_key) { return key_pressed[_key]; } | |
function keyboard_check_released(_key) { return key_released[_key]; } | |
// mouse functions: | |
function mouse_check() { return mouse_down; } | |
function mouse_check_pressed() { return mouse_pressed; } | |
function mouse_check_released() { return mouse_released; } | |
// virtual keys: | |
function vkey() { | |
this.top = 0; | |
this.left = 0; | |
this.right = 0; | |
this.bottom = 0; | |
this.key = 0; | |
this.down = false; | |
this.active = true; | |
} | |
function vkey_add(_x, _y, _w, _h, _k) { | |
var _v = new vkey(); | |
_v.left = _x; | |
_v.top = _y; | |
_v.right = _x + _w; | |
_v.bottom = _y + _h; | |
_v.width = _w; | |
_v.height = _h; | |
_v.key = _k; | |
tu_vkeys.push(_v); | |
return _v; | |
} | |
// misc: | |
function trace() { console.log.apply(console, arguments); } | |
function tu_idle() { } // left empty on purpose | |
// minimal math: | |
function abs(_value) { return _value < 0 ? -_value : _value; } | |
function sign(_value) { return _value > 0 ? 1 : _value < 0 ? -1 : 0; } | |
function choose() { return arguments[~~(Math.random() * arguments.length)]; } | |
function random(_value) { return Math.random() * _value; } | |
function irandom(_value) { return ~~(Math.random() * _value + 1); } | |
// trig functions: | |
function lengthdir_x(_length, _direction) { return _length * Math.cos(_direction * tu_d2r); } | |
function lengthdir_y(_length, _direction) { return _length * Math.sin(_direction * tu_d2r); } | |
function point_distance(_x1, _y1, _x2, _y2) { return Math.sqrt(Math.pow(( _x1 - _x2), 2) + Math.pow((_y1 - _y2), 2)); } | |
function point_direction(_x1, _y1, _x2, _y2) { return Math.atan2(_y2 - _y1, _x2 - _x1) * tu_r2d; } | |
function degtorad(_degree) { return _degree * tu_d2r; } | |
function radtodeg(_degree) { return _degree * tu_r2d; } | |
// sound functions: | |
function sound_mode(_sound, _mode) { | |
if (_sound.audio.networkState == _sound.audio.NETWORK_NO_SOURCE) return; | |
switch (_sound.type) { | |
case "wav": if (!tu_wav_supported) return; break; | |
case "ogg": if (!tu_ogg_supported) return; break; | |
case "mp3": if (!tu_mp3_supported) return; break; | |
} | |
if (_mode != 3) { | |
_sound.audio.pause(); | |
if (_mode != 0) { | |
_sound.audio.currentTime = 0; | |
} else return; | |
_sound.audio.loop = _mode > 1; | |
} | |
_sound.audio.play(); | |
} | |
function sound_play(_sound) { sound_mode(_sound, 1); } | |
function sound_loop(_sound) { sound_mode(_sound, 2); } | |
function sound_resume(_sound) { sound_mode(_sound, 3); } | |
function sound_stop(_sound) { sound_mode(_sound, 0); } | |
function sound_stop_all() { for ( var _s = 0; _s < tu_audios.length; _s++) sound_stop( tu_audios[_s] ); } | |
function sound_volume( _sound, _volume) { | |
if (_sound.audio.networkState == _sound.audio.NETWORK_NO_SOURCE) return; | |
_sound.audio.volume = _volume; | |
} | |
// draw sprite: | |
function draw_sprite(_sprite_index, _sub_image, _x, _y) { | |
if (_sprite_index == null) return; | |
if (_sub_image > _sprite_index.frames.length - 1) _sub_image = 0; | |
tu_context.save(); | |
tu_context.translate(_x - room_viewport_x, _y - room_viewport_y); | |
tu_context.globalAlpha = tu_draw_alpha; | |
tu_context.drawImage(_sprite_index.frames[~~_sub_image], -_sprite_index.xoffset, -_sprite_index.yoffset); | |
tu_context.restore(); | |
} | |
function draw_sprite_part(_sprite_index, _sub_image, _left, _top, _width, _height, _x, _y) { | |
if (_sprite_index == null) return; | |
if (_sub_image >= _sprite_index.frames.length) _sub_image = _sub_image % _sprite_index.frames.length; | |
tu_context.save(); | |
tu_context.translate(_x - room_viewport_x, _y - room_viewport_y); | |
tu_context.globalAlpha = tu_draw_alpha; | |
tu_context.drawImage(_sprite_index.frames[~~_sub_image], _left, _top, _width, _height, 0, 0, _width, _height); | |
tu_context.restore(); | |
} | |
function draw_sprite_ext(_sprite_index, _sub_image, _x, _y, _xscale, _yscale, _rotation, _alpha) { | |
if (_sprite_index == null) return; | |
if (_sub_image >= _sprite_index.frames.length) _sub_image = _sub_image % _sprite_index.frames.length; | |
tu_context.save(); | |
tu_context.translate(_x - room_viewport_x, _y - room_viewport_y); | |
tu_context.rotate(degtorad(_rotation)); | |
tu_context.scale(_xscale, _yscale); | |
tu_context.globalAlpha = _alpha; | |
tu_context.drawImage(_sprite_index.frames[~~_sub_image], -_sprite_index.xoffset , -_sprite_index.yoffset, _sprite_index.width, _sprite_index.height); | |
tu_context.restore(); | |
} | |
// draw text: | |
function draw_text(_x, _y, _text) { | |
tu_context.font = tu_draw_font; | |
tu_context.textAlign = tu_draw_halign; | |
tu_context.textBaseline = tu_draw_valign; | |
tu_context.fillStyle = tu_context.strokeStyle = "rgba(" + tu_draw_color + ", " + tu_draw_alpha + ")"; | |
tu_context.fillText( _text, _x - room_viewport_x, _y - room_viewport_y ); | |
} | |
// draw shapes: | |
function draw_rectangle(_x1, _y1, _x2, _y2, _outline) { | |
tu_context.fillStyle = tu_context.strokeStyle = "rgba(" + tu_draw_color + ", " + tu_draw_alpha + ")"; | |
tu_context.beginPath(); | |
if (_outline) tu_context.strokeRect( _x1- room_viewport_x, _y1 - room_viewport_y, _x2 - _x1, _y2 - _y1 ); | |
else tu_context.fillRect( _x1- room_viewport_x, _y1 - room_viewport_y, _x2 - _x1, _y2 - _y1 ); | |
tu_context.closePath(); | |
} | |
function draw_circle(_x, _y, _r, _outline) { | |
tu_context.fillStyle = tu_context.strokeStyle = "rgba(" + tu_draw_color + ", " + tu_draw_alpha + ")"; | |
tu_context.beginPath(); | |
tu_context.arc( _x - room_viewport_x, _y - room_viewport_y, _r, 0, tu_2pi, true ); | |
tu_context.closePath(); | |
!_outline ? tu_context.fill() : tu_context.stroke(); | |
} | |
function draw_line(_x1, _y1, _x2, _y2) { | |
tu_context.strokeStyle = "rgba(" + tu_draw_color + ", " + tu_draw_alpha + ")"; | |
tu_context.beginPath(); | |
tu_context.moveTo( _x1 - room_viewport_x, _y1 - room_viewport_y ); | |
tu_context.lineTo( _x2 - room_viewport_x, _y2 - room_viewport_y ); | |
tu_context.closePath(); | |
tu_context.stroke(); | |
} | |
// draw settings: | |
function draw_set_alpha(_alpha) { | |
tu_draw_alpha = _alpha; | |
} | |
function draw_set_color( _r, _g, _b) { | |
tu_draw_color_red = _r; | |
tu_draw_color_green = _g; | |
tu_draw_color_blue = _b; | |
tu_draw_color = tu_draw_color_red + "," + tu_draw_color_green + "," + tu_draw_color_blue; | |
tu_context.fillStyle = "rgba(" + tu_draw_color + ", " + tu_draw_alpha + ")"; | |
tu_context.strokeStyle = "rgb(" + tu_draw_color + ")"; | |
} | |
function draw_set_linewidth(_width) { tu_context.lineWidth = _width; } | |
// draw settings - font: | |
function draw_set_font (_font) { | |
tu_draw_font_ = _font; | |
tu_draw_font = (_font.bold == 1 ? "bold" : "") + " " + (_font.italic == 1 ? "italic" : "") + " " + _font.size + "px " + _font.family; | |
tu_context.font = tu_draw_font; | |
tu_context.textAlign = tu_draw_halign; | |
tu_context.textBaseline = tu_draw_valign; | |
} | |
function draw_set_halign(_halign) { tu_draw_halign = _halign; } | |
function draw_set_valign(_valign) { tu_draw_valign = _valign; } | |
// room translations: | |
function room_goto(_scene) { | |
tu_viewport_inst = null; | |
tu_room_to_go = _scene; | |
} | |
function room_goto_next() { | |
var _ri = 0, _r; | |
for (_r = 0; _r < tu_scenes.length; _r++) if (tu_scenes[_r] == room_current) _ri = _r; | |
if (typeof tu_scenes[(_ri + 1)] == "object") room_goto(tu_scenes[_ri + 1]); | |
} | |
function room_goto_previous() { | |
var _ri = 0, _r; | |
for (_r = 0; _r < tu_scenes.length; _r++) if (tu_scenes[_r] == room_current) _ri = _r; | |
if (typeof tu_scenes[(_ri - 1)] == "object") room_goto(tu_scenes[_ri - 1]); | |
} | |
function room_goto_first() { room_goto(tu_scenes[0]); } | |
function room_goto_last() { room_goto(tu_scenes[(tu_scenes.length - 1)]); } | |
function room_restart() { room_goto(room_current); } | |
// instance functions: | |
function instance_create_(_x, _y, _object) { | |
var o = new _object.constructor; | |
o.parameters = arguments.length > 3 ? Array.prototype.slice.call(arguments, 3) : []; | |
o.object_index = _object; | |
o.__instance = true; | |
o.xstart = o.x = _x; | |
o.ystart = o.y = _y; | |
o._depth = o.depthstart; | |
instance_activate(o); | |
return o; | |
} | |
function instance_create(_x, _y, _object) { | |
var o = instance_create_.apply(this, arguments); | |
o.on_creation(); | |
return o; | |
} | |
function instance_number(_object) { | |
return instance_list(_object).length; | |
} | |
function instance_first(_object) { | |
var l = instance_list(_object); | |
return l.length ? l[0] : null; | |
} | |
// BBox <> BBox | |
function collide_bbox_bbox(l1, t1, r1, b1, l2, t2, r2, b2) { | |
return !(b1 <= t2 || t1 >= b2 || r1 <= l2 || l1 >= r2); | |
} | |
// BBox <> SpriteBox | |
// (left, top, right, bottom, instX, instY, scaleX, scaleY, sprite, ofsX, ofsY) | |
function collide_bbox_sbox(l1, t1, r1, b1, x2, y2, h2, v2, s2) { | |
return | |
!( b1 <= y2 + v2 * (s2.collision_top - s2.yoffset) | |
|| t1 >= y2 + v2 * (s2.collision_bottom - s2.yoffset) | |
|| r1 <= x2 + h2 * (s2.collision_left - s2.xoffset) | |
|| l1 <= x2 + h2 * (s2.collision_right - s2.xoffset)); | |
} | |
// SpriteBox <> BBox | |
function collide_sbox_point(x2, y2, h2, v2, s2, x1, y1) { | |
return | |
!( y1 <= y2 + v2 * (s2.collision_top - s2.yoffset) | |
|| y1 >= y2 + v2 * (s2.collision_bottom - s2.yoffset) | |
|| x1 <= x2 + h2 * (s2.collision_left - s2.xoffset) | |
|| x1 <= x2 + h2 * (s2.collision_right - s2.xoffset)); | |
} | |
// SpriteBox <> Circle | |
function collide_sbox_circle(x2, y2, h2, v2, s2, x1, y1, r1) { | |
var u, v, dx, dy; | |
u = x2 + h2 * (s2.collision_left - s2.xoffset); | |
v = x2 + h2 * (s2.collision_right - s2.xoffset); | |
dx = (x2 < u ? u : x2 > v ? v : x2) - x2; | |
u = y2 + v2 * (s2.collision_top - s2.yoffset); | |
v = y2 + v2 * (s2.collision_bottom - s2.yoffset); | |
dy = (y2 < u ? u : y2 > v ? v : y2) - y2; | |
return (dx * dx + dy * dy < r1 * r1); | |
} | |
// BBox <> Point | |
function collide_bbox_point(l1, t1, r1, b1, x2, y2) { | |
return (x2 > l1 && x2 < r1 && y2 > t1 && y2 < b1); | |
} | |
// BBox <> Circle | |
function collide_bbox_circle(l1, t1, r1, b1, x2, y2, r2) { | |
var dx = (x2 < l1 ? l1 : x2 > r1 ? r1 : x2) - x2, | |
dy = (y2 < t1 ? t1 : y2 > b1 ? b1 : y2) - y2; | |
return (dx * dx + dy * dy < r2 * r2); | |
} | |
// Circle <> Range | |
function collide_circle_range(dx, dy, dr) { | |
return (dx * dx + dy * dy < dr * dr); | |
} | |
// Circle <> Circle | |
function collide_circle_circle(x1, y1, r1, x2, y2, r2) { | |
return collide_circle_range(x1 - x2, y1 - y2, r1 + r2); | |
} | |
// Circle <> Point | |
function collide_circle_point(x1, y1, r1, x2, y2) { | |
return collide_circle_range(x1 - x2, y1 - y2, r1); | |
} | |
// instance collision checking: | |
function instance_position(_px, _py, _object, _mult) { | |
var _x, _y, _ox, _oy, _sx, _sy, _o, _s, _i, _il, _r, _dx, _dy, | |
_q = (_object.__instance ? [_object] : instance_list(_object)), | |
_tm = (_mult) ? true : false; | |
if (_tm) _ta = []; | |
_il = _q.length; | |
for (_i = 0; _i < _il; _i++) { | |
_o = _q[_i]; | |
if (!_o.collision_checking) continue; | |
_s = _o.sprite_index; | |
if (!_s) continue; | |
_x = _o.x; _sx = _o.image_xscale; | |
_y = _o.y; _sy = _o.image_yscale; | |
switch (_s.collision_shape) | |
{ | |
case 0x2: | |
if (_sx == 1 && _sy == 1) { | |
_ox = _s.xoffset; _oy = _s.yoffset; | |
if (!collide_bbox_point(_x + _s.collision_left - _ox, _y + _s.collision_top - _oy, | |
_x + _s.collision_right - _ox, _y + _s.collision_bottom - _oy, _px, _py)) break; | |
} else if (!collide_sbox_point(_x, _y, _sx, _sy, _s)) break; | |
if (!_tm) return _o; | |
_ta.push(_o); | |
break; | |
case 0x3: | |
_r = _s.collision_radius * Math.max(_o.image_xscale, _o.image_yscale); | |
_dx = _o.x + (_s.width / 2 - _s.xoffset) - _px; | |
_dy = _o.y + (_s.height / 2 - _s.yoffset) - _py; | |
if ((_dx * _dx) + (_dy * _dy) > _r * _r) break; | |
if (!_tm) return _o; | |
_ta.push(_o); | |
break; | |
} | |
} | |
return _tm ? _ta : null; | |
} | |
// | |
function __place_meeting__(nx, ny, what, many) { | |
this.other = null; | |
var i, l, | |
// sprite, scale: | |
ts = this.sprite_index, | |
tsx, tsy, tfx, tfy, tst, | |
// circle: | |
tcx, tcy, tcr, | |
// bbox: | |
tbl, tbr, tbt, tbb, | |
// instances, multiple, output, types: | |
tz, tm, ct, ch, ra, | |
// other: | |
o, ox, oy, os, ost, osx, osy, ofx, ofy, ofr; | |
if (ts == null) return false; | |
tfx = ts.xoffset; | |
tfy = ts.yoffset; | |
tsx = this.image_xscale; | |
tsy = this.image_yscale; | |
tst = ts.collision_shape; | |
// bbox: | |
if (tst == 2) { | |
tbl = nx + tsx * (ts.collision_left - tfx); | |
tbr = nx + tsx * (ts.collision_right - tfx); | |
tbt = ny + tsy * (ts.collision_top - tfy); | |
tbb = ny + tsy * (ts.collision_bottom - tfy); | |
} | |
// circle: | |
if (tst == 3) { | |
tcr = ts.collision_radius * (tsx > tsy ? tsx : tsy); | |
tcx = nx + tsx * (ts.width / 2 - tfx); | |
tcy = ny + tsy * (ts.height / 2 - tfy); | |
} | |
// | |
tz = (what.__instance ? [what] : instance_list(what)); | |
tm = many ? true : false; | |
if (tm) ra = []; | |
l = tz.length; | |
for (i = 0; i < l; i++) { | |
o = tz[i]; | |
if (!o.collision_checking) continue; | |
os = o.sprite_index; | |
if (os == null) continue; | |
ox = o.x; osx = o.image_xscale; | |
oy = o.y; osy = o.image_yscale; | |
ost = os.collision_shape; | |
ct = (tst << 4) | ost; | |
ch = false; | |
switch(ct) { | |
case 0x22: | |
if (osx == 1 && osy == 1) { | |
ofx = os.xoffset; ofy = os.yoffset; | |
if (!collide_bbox_bbox(tbl, tbt, tbr, tbb, | |
ox + os.collision_left - ofx, oy + os.collision_top - ofy, | |
ox + os.collision_right - ofx, oy + os.collision_bottom - ofy)) break; | |
} else if (!collide_bbox_sbox(tbl, tbt, tbr, tbb, ox, oy, osx, osy, os)) break; | |
ch = true; | |
break; | |
case 0x23: | |
ofr = os.collision_radius * (osx > osy ? osx : osy); | |
ofx = ox + osx * (os.width / 2 - os.xoffset); | |
ofy = oy + osy * (os.height / 2 - os.yoffset); | |
if (!collide_bbox_circle(tbl, tbt, tbr, tbb, ofx, ofy, ofr)) break; | |
ch = true; | |
break; | |
case 0x32: | |
if (osx == 1 && osy == 1) { | |
ofx = os.xoffset; ofy = os.yoffset; | |
if (!collide_bbox_circle( | |
ox + os.collision_left - ofx, oy + os.collision_top - ofy, | |
ox + os.collision_right - ofx, oy + os.collision_bottom - ofy, | |
tcx, tcy, tcr)) break; | |
} else if (!collide_sbox_circle(ox, oy, osx, osy, os, tcx, tcy, tcr)) break; | |
ch = true; | |
break; | |
case 0x33: | |
ofr = os.collision_radius * (osx > osy ? osx : osy); | |
ofx = ox + osx * (os.width / 2 - os.xoffset); | |
ofy = oy + osy * (os.height / 2 - os.yoffset); | |
if (!collide_circle_circle(tcx, tcy, tcr, ofx, ofy, ofr)) break; | |
ch = true; | |
break; | |
} if (!ch) continue; | |
this.other = o; | |
o.other = this; | |
if (!tm) return (o); | |
ra.push(o); | |
} return ra; | |
} | |
function position_meeting(_x, _y, _object) { | |
return instance_position(_x, _y, _object) != null; | |
} | |
function __move_towards_point__(_x, _y, _speed) { | |
if (_speed == 0) return; | |
if (this.x == _x && this.y == _y) return; | |
var _dx = _x - this.x, | |
_dy = _y - this.y, | |
_dist = _dx * _dx + _dy * _dy; | |
if (_dist < _speed * _speed) { | |
this.x = _x; | |
this.y = _y; | |
} else { | |
_dist = Math.sqrt(_dist); | |
this.x += _dx * _speed / _dist; | |
this.y += _dy * _speed / _dist; | |
} | |
} | |
function __instance_destroy__() { | |
tu_trash.push( this ); | |
} | |
// web data: | |
function save_web_data(_name, _value) { if (window.localStorage) window.localStorage.setItem(_name, _value); } | |
function save_web_integer(_name, _value) { if (window.localStorage) window.localStorage.setItem("int_" + _name, _value); } | |
function save_web_float(_name, _value) { if (window.localStorage) window.localStorage.setItem("float_" + _name, _value); } | |
function save_web_string(_name, _value) { if (window.localStorage) window.localStorage.setItem("string_" + _name, _value); } | |
function load_web_data(_name) { if (window.localStorage) return window.localStorage.getItem(_name); } | |
function load_web_integer(_name) { if (window.localStorage) return parseInt(window.localStorage.getItem("int_" + _name)); } | |
function load_web_float(_name) { if (window.localStorage) return parseFloat(window.localStorage.getItem("float_" + _name)); } | |
function load_web_string(_name) { if (window.localStorage) return '' + window.localStorage.getItem("string_" + _name); } | |
function delete_web_data(_name) { if (window.localStorage) window.localStorage.removeItem(_name); } | |
function delete_web_integer(_name) { if (window.localStorage) window.localStorage.removeItem("int_" + _name); } | |
function delete_web_float(_name) { if (window.localStorage) window.localStorage.removeItem("float_" + _name); } | |
function delete_web_string(_name) { if (window.localStorage) window.localStorage.removeItem("string_" + _name); } | |
function clear_web_data() { if (window.localStorage) window.localStorage.clear(); } | |
function web_data_number() { if (window.localStorage) return window.localStorage.length; } | |
// misc functions: | |
function pause_game( _key) { | |
tu_paused = true; | |
tu_unpausekey = _key; | |
} | |
function modal_end() { | |
if (tu_modal == null) return; | |
tu_modal.instance_destroy(); | |
tu_modal = null; | |
} | |
function modal_start(_inst, _draw) { | |
if (tu_modal != null) modal_end(); | |
tu_modal = _inst; | |
tu_modaldraw = _draw; | |
} | |
// | |
function show_mouse() { tu_canvas.style.cursor = "default"; } | |
function hide_mouse() { tu_canvas.style.cursor = "none"; } | |
// | |
function tu_gettime() { return (new Date()).getTime(); } | |
/*********************************************************************** | |
* ENGINE | |
***********************************************************************/ | |
function tu_global () { } | |
global = new tu_global(); | |
//{ Events | |
function __keydownlistener__(e) { | |
var r = true; | |
if (!e) e = window.event; | |
if (document.activeElement && document.activeElement == tu_canvas || document.activeElement == document.body) r = false; | |
if (e.repeat) return; | |
var keyCode = window.event ? e.which : e.keyCode; | |
if (!key_down[keyCode]) { | |
key_pressed[keyCode] = true; | |
tu_keys_pressed.push(keyCode); | |
} | |
key_down[keyCode] = true; | |
if (!r) e.preventDefault(); | |
return r; | |
}; | |
function __keyuplistener__(e) { | |
var r = true; | |
if (!e) e = window.event; | |
if (document.activeElement && document.activeElement == tu_canvas || document.activeElement == document.body) r = false; | |
var keyCode = window.event ? e.which : e.keyCode; | |
if (key_down[keyCode]) | |
{ | |
key_released[keyCode] = true; | |
tu_keys_released.push(keyCode); | |
} | |
key_down[keyCode] = false; | |
if (!r) e.preventDefault(); | |
return r; | |
}; | |
function canvas_scale_x() { | |
var r = tu_canvas.style.width, o = tu_canvas.width; | |
if (r) { | |
if (r.indexOf("px") >= 0) return parseFloat(r) / o; | |
} | |
return 1; | |
} | |
function canvas_scale_y() { | |
var r = tu_canvas.style.height, o = tu_canvas.height; | |
if (r) { | |
if (r.indexOf("px") >= 0) return parseFloat(r) / o; | |
} | |
return 1; | |
} | |
function __touchsim__(_x, _y) { | |
var r = [{}]; | |
r[0].pageX = tu_canvas.offsetLeft + _x * canvas_scale_x(); | |
r[0].pageY = tu_canvas.offsetTop + _y * canvas_scale_y(); | |
__touchvkey__(r); | |
} | |
function __mousemovelistener__(_e) { | |
if (_e.pageX != undefined && _e.pageY != undefined) { | |
mouse_x = _e.pageX; | |
mouse_y = _e.pageY; | |
} else { | |
mouse_x = _e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; | |
mouse_y = _e.clientY + document.body.scrollTop + document.documentElement.scrollTop; | |
} | |
if (room_current != null) { | |
mouse_x = (mouse_x - tu_canvas.offsetLeft) / canvas_scale_x(); | |
mouse_y = (mouse_y - tu_canvas.offsetTop) / canvas_scale_y(); | |
} | |
if (mouse_down) __touchsim__(mouse_x, mouse_y); | |
}; | |
function __mousedownlistener__(_e) { | |
//if (!mouse_down) mouse_pressed = true; | |
//mouse_down = true; | |
__touchsim__(mouse_x, mouse_y); | |
}; | |
function __mouseuplistener__(_e) { | |
//if (mouse_down) mouse_released = true; | |
//mouse_down = false; | |
__touchvkey__([]); | |
}; | |
function __touchvkey__(_t) { | |
var _tx = 0, _ty = 0, _tc = 0, _tl = _t.length, _vl = tu_vkeys.length, _i, _j, _c, _k, | |
_px, _py, _dx = tu_canvas.offsetLeft, _dy = tu_canvas.offsetTop, _mx = _my = 1; | |
if (tu_canvas.style.width) _mx | |
touch_x = []; touch_y = []; touch_count = 0; | |
for (_i = 0; _i < _vl; _i++) tu_vkeys[_i].count = 0; | |
for (_i = 0; _i < _tl; _i++) { | |
_c = 0; | |
_px = (_t[_i].pageX - _dx) / canvas_scale_x(); | |
_py = (_t[_i].pageY - _dy) / canvas_scale_y(); | |
for (_j = 0; _j < _vl; _j++) { | |
if (!tu_vkeys[_j].active) continue; | |
if (_px >= tu_vkeys[_j].left && _px < tu_vkeys[_j].right | |
&& _py >= tu_vkeys[_j].top && _py < tu_vkeys[_j].bottom) { | |
tu_vkeys[_j].count++; | |
if (!tu_vkeys[_j].down) { | |
tu_vkeys[_j].down = true; | |
_k = tu_vkeys[_j].key; | |
if (!key_down[_k]) { | |
key_down[_k] = true; | |
key_pressed[_k] = true; | |
tu_keys_pressed.push(_k); | |
} | |
} | |
_c++; | |
} | |
} | |
if (_c == 0) { | |
_tx += touch_x[_tc] = _px; | |
_ty += touch_y[_tc++] = _py; | |
} | |
} | |
for (_i = 0; _i < _vl; _i++) { | |
if (tu_vkeys[_i].count != 0) continue; | |
if (!tu_vkeys[_i].down) continue; | |
tu_vkeys[_i].down = false; | |
_k = tu_vkeys[_i].key; | |
if (key_down[_k]) { | |
key_down[_k] = false; | |
key_released[_k] = true; | |
tu_keys_released.push(_k); | |
} | |
} | |
touch_count = _tc; | |
if (_tc != 0) { | |
mouse_x = _tx / _tc; | |
mouse_y = _ty / _tc; | |
if (!mouse_down) { | |
mouse_down = true; | |
mouse_pressed = true; | |
} | |
} else if (mouse_down) { | |
mouse_down = false; | |
mouse_released = true; | |
} | |
}; | |
function __touchlistener__(e) { | |
e.preventDefault(); | |
__touchvkey__(e.targetTouches); | |
}; | |
//} | |
function tu_init () { | |
if (document.addEventListener) { | |
document.addEventListener("keydown", __keydownlistener__, false); | |
document.addEventListener("keyup", __keyuplistener__, false); | |
document.addEventListener("mousemove", __mousemovelistener__, false); | |
document.addEventListener("mousedown", __mousedownlistener__, false); | |
document.addEventListener("mouseup", __mouseuplistener__, false); | |
document.addEventListener("touchstart", __touchlistener__, false); | |
document.addEventListener("touchend", __touchlistener__, false); | |
document.addEventListener("touchmove", __touchlistener__, false); | |
document.addEventListener("touchenter", __touchlistener__, false); | |
document.addEventListener("touchleave", __touchlistener__, false); | |
document.addEventListener("touchcancel", __touchlistener__, false); | |
} else { | |
document.attachEvent("onkeydown", __keydownlistener__); | |
document.attachEvent("onkeyup", __keyuplistener__); | |
document.attachEvent("onmousemove", __mousemovelistener__); | |
document.attachEvent("onmousedown", __mousedownlistener__); | |
document.attachEvent("onmouseup", __mouseuplistener__); | |
} | |
// initialize keycodes | |
for (var _k = 0; _k < 256; _k++) { | |
key_down[_k] = key_pressed[_k] = key_released[_k] = false; | |
} | |
} | |
function tu_loading_inc() { tu_loading++; tu_load_total++; } | |
function tu_loading_dec() { tu_loading--; } | |
function _$_(_id_) { | |
return document.getElementById( _id_ ); | |
} | |
function var_override(_what, _svar, _fget, _fset) { | |
if (var_override_) { | |
if (_what.hasOwnProperty(_svar)) return; | |
Object.defineProperty(_what, _svar, { | |
get: _fget, | |
set: _fset | |
}); | |
} else { | |
if (_what.__lookupGetter__(_svar) != undefined) return; | |
_what.__defineGetter__(_svar, _fget); | |
_what.__defineSetter__(_svar, _fset); | |
} | |
} | |
//{ Depth | |
function _tu_depth_find(_d) { | |
var _tl = tu_depthi.length, _td, _ti; | |
for (_ti = 0; _ti < _tl; _ti++) { | |
_td = tu_depthi[_ti]; | |
if (_d > _td) return _ti; | |
} | |
return _tl; | |
} | |
function _tu_depth_new(_d) { | |
var _i = _tu_depth_find(_d), _o = []; | |
tu_depth.splice(_i, 0, _o); | |
tu_depthi.splice(_i, 0, _d); | |
return _i; | |
} | |
function tu_depth_add(_d, _o) { | |
var _t = tu_depthi.indexOf(_d); | |
if (_t == -1) _t = _tu_depth_new(_d); // create array if none | |
tu_depth[_t].push(_o); | |
} | |
function tu_depth_delete(_d, _o) { | |
var _t = tu_depth[tu_depthi.indexOf(_d)], _ti = _t.indexOf(_o); | |
if (_ti == -1) return; | |
_t.splice(_ti, 1); | |
} | |
function tu_depth_update() { | |
var i, l = tu_depthu.length, o; | |
if (l == 0) return; | |
for (i = 0; i < l; i++) { | |
o = tu_depthu[i]; | |
if (o.instance_active && o._depth !== undefined) tu_depth_delete(o._depth, o); | |
o._depth = o._depthn; | |
if (o.instance_active && o._depth !== undefined) tu_depth_add(o._depth, o); | |
o._depthu = false; | |
} | |
tu_depthu = []; | |
} | |
// Accessors: | |
function tu_depth_get() { return this._depth; } | |
function tu_depth_set(_d) { | |
if (this._depth == _d) return; // don't change on depth match | |
this._depthn = _d; | |
if (this._depthu) return; | |
this._depthu = true; | |
tu_depthu.push(this); | |
} | |
//} | |
//{ Types | |
function instance_list(_o) { | |
var _t = _o._object_index_; | |
if (tu_types[_t] == undefined) tu_types[_t] = []; | |
return tu_types[_t]; | |
} | |
function tu_type_add(_d, _o) { | |
instance_list(_d).push(_o); | |
} | |
function tu_type_delete(_o, _p) { | |
var _d = tu_types[_p], _t = _d.indexOf(_o); | |
_d.splice(_t, 1); | |
} | |
function tu_type_get() { return this._object_index; } | |
//} | |
//{ Tileset functions | |
function tile_layer_find(_d) { | |
var _tl = tu_tilesi.length, _td, _ti; | |
for (_ti = 0; _ti < _tl; _ti++) { | |
_td = tu_tilesi[_ti]; | |
if (_d > _td) return _ti; | |
} | |
return _tl; | |
} | |
function tile_layer_add(_d) { | |
var _i = tile_layer_find(_d), _o = []; | |
tu_tiles.splice(_i, 0, _o); | |
tu_tilesi.splice(_i, 0, _d); | |
return _o; | |
} | |
function tile(_s, _x, _y, _l, _t, _w, _h) { | |
this.source = _s; | |
this.x = _x; | |
this.y = _y; | |
this.left = _l; | |
this.top = _t; | |
this.width = _w; | |
this.height = _h; | |
this.width2 = _w; | |
this.height2 = _h; | |
this.sectors = []; | |
} | |
function tile_add(_b, _l, _t, _w, _h, _x, _y, _z) { | |
var _tx1 = Math.floor(_x / tu_tilez), | |
_ty1 = Math.floor(_y / tu_tilez), | |
_tx2 = Math.floor((_x + _w) / tu_tilez), | |
_ty2 = Math.floor((_y + _h) / tu_tilez), | |
_tt = new tile(_b, _x, _y, _l, _t, _w, _h), | |
_tx, _ty, _ts, | |
_d, _e = tu_tilesi.indexOf(_z); | |
if (_e != -1) _d = tu_tiles[_e]; | |
else _d = tile_layer_add(_z); | |
for (_tx = _tx1; _tx <= _tx2; _tx++) { | |
if (_d[_tx] == null) _d[_tx] = []; | |
for (_ty = _ty1; _ty <= _ty2; _ty++) { | |
if (_d[_tx][_ty] == null) _d[_tx][_ty] = []; | |
_ts = _d[_tx][_ty]; | |
_ts.push(_tt); | |
_tt.sectors.push(_ts); | |
} | |
} | |
return _tt; | |
} | |
function tile_find(_x, _y, _w, _h, _d) { | |
var _xw = _x + _w, | |
_yh = _y + _h, | |
_r = [], | |
_tx, _ty, _ti, _tl, _ts, _tt, _ta, | |
_tx1, _ty1, _tx2, _ty2; | |
_ti = tu_tilesi.indexOf(_d); | |
if (_ti == -1) return _r; | |
_ta = tu_tiles[_ti]; | |
_tx1 = Math.floor(_x / tu_tilez); | |
_ty1 = Math.floor(_y / tu_tilez); | |
_tx2 = Math.floor((_x + _w) / tu_tilez); | |
_ty2 = Math.floor((_y + _h) / tu_tilez); | |
for (_tx = _tx1; _tx <= _tx2; _tx++) { | |
if (_ta[_tx] == null) continue; | |
for (_ty = _ty1; _ty <= _ty2; _ty++) { | |
if (_ta[_tx][_ty] == null) continue; | |
_ts = _ta[_tx][_ty]; | |
_tl = _ts.length; | |
for (_ti = 0; _ti < _tl; _ti++) { | |
_tt = _ts[_ti]; | |
if (_tt.x >= _xw) continue; | |
if (_tt.y >= _yh) continue; | |
if (_tt.x + _tt.width2 < _x) continue; | |
if (_tt.y + _tt.height2 < _y) continue; | |
_r.push(_tt); | |
} | |
} | |
} | |
return _r; | |
} | |
function tile_delete(_t) { | |
var _ti, _tl, _ts; | |
_tl = _t.sectors.length; | |
for (_ti = 0; _ti < _tl; _ti++) { | |
_ts = _t.sectors[_ti]; | |
_ts.splice(_ts.indexOf(_t), 1); | |
} | |
} | |
function tile_srender(_s) { | |
var _ti, _tt; | |
for (_ti = 0; _ti < _s.length; _ti++) { | |
if (_s[_ti] == null) continue; | |
_tt = _s[_ti]; | |
if (_tt.source == null) continue; | |
if (_tt.source.image == null) continue; | |
tu_context.drawImage(_tt.source.image, _tt.left, _tt.top, _tt.width, _tt.height, _tt.x - room_viewport_x, _tt.y - room_viewport_y, _tt.width2, _tt.height2); | |
} | |
} | |
function tile_lrender(_l) { | |
var _tx, _ty, | |
_tx1 = Math.floor(room_viewport_x / tu_tilez), | |
_tx2 = Math.floor((room_viewport_x + room_viewport_width) / tu_tilez), | |
_ty1 = Math.floor(room_viewport_y / tu_tilez), | |
_ty2 = Math.floor((room_viewport_y + room_viewport_height) / tu_tilez); | |
for (_tx = _tx1; _tx <= _tx2; _tx++) { | |
if (_l[_tx] == null) continue; | |
for (_ty = _ty1; _ty <= _ty2; _ty++) { | |
if (_l[_tx][_ty] == null) continue; | |
tile_srender(_l[_tx][_ty]); | |
} | |
} | |
} | |
//} /Tileset functions | |
//{ Some events & accessors | |
function tu_id_get() { return this; } | |
function tu_parent_get() { return this._parent_index; } | |
function image_single_get() { return (this.image_speed == 0 ? this.image_index : -1); } | |
function image_single_set(_o) { this.image_speed = 0; this.image_index = _o; } | |
// Handles object size & sprite updates. Should get rid of this in favor of accessors. | |
function __handle_sprite__(_object_) { | |
if (_object_.sprite_index == null) return; | |
_object_.sprite_width = _object_.sprite_index.width; | |
_object_.sprite_height = _object_.sprite_index.height; | |
_object_.sprite_xoffset = _object_.sprite_index.xoffset; | |
_object_.sprite_yoffset = _object_.sprite_index.yoffset; | |
_object_.image_number = _object_.sprite_index.frames.length; | |
_object_.image_index += _object_.image_speed; | |
if (_object_.image_index >= _object_.image_number) _object_.image_index = _object_.image_index % _object_.image_number; | |
if (_object_.image_index < 0) _object_.image_index = _object_.image_number - 1 + (_object_.image_index % _object_.image_number); | |
} | |
function __draw_self__() { | |
draw_sprite_ext(this.sprite_index, this.image_index, this.x, this.y, this.image_xscale, this.image_yscale, this.image_angle, this.image_alpha); | |
} | |
//} | |
//{ Inherited event lookup functions. | |
// There's also a way to do this with much shorter code. | |
function on_creation_i() { | |
for (var o = this.parent; o; o = o.parent) | |
if (o.on_creation !== on_creation_i) | |
return o.on_creation.apply(this); | |
} | |
function on_destroy_i() { | |
for (var o = this.parent; o; o = o.parent) | |
if (o.on_destroy !== on_destroy_i) | |
return o.on_destroy.apply(this); | |
} | |
function on_step_i() { | |
for (var o = this.parent; o; o = o.parent) | |
if (o.on_step !== on_step_i) | |
return o.on_step.apply(this); | |
} | |
function on_end_step_i() { | |
for (var o = this.parent; o; o = o.parent) | |
if (o.on_end_step !== on_end_step_i) | |
return o.on_end_step.apply(this); | |
} | |
function on_draw_d() { | |
__handle_sprite__(this); | |
__draw_self__.apply(this); | |
} | |
function on_draw_i() { | |
for (var o = this.parent; o; o = o.parent) | |
if (o.on_draw !== on_draw_i) | |
return o.on_draw.apply(this); | |
on_draw_d.apply(this); | |
} | |
function on_collision_i() { | |
for (var o = this.parent; o; o = o.parent) | |
if (o.on_collision !== on_collision_i) | |
return o.on_collision.apply(this); | |
} | |
function on_animationend_i() { | |
for (var o = this.parent; o; o = o.parent) | |
if (o.on_animationend !== on_animationend_i) | |
return o.on_animationend.apply(this); | |
} | |
function on_roomstart_i() { | |
for (var o = this.parent; o; o = o.parent) | |
if (o.on_roomstart !== on_roomstart_i) | |
return o.on_roomstart.apply(this); | |
} | |
function on_roomend_i() { | |
for (var o = this.parent; o; o = o.parent) | |
if (o.on_roomend !== on_roomend_i) | |
return o.on_roomend.apply(this); | |
} | |
//} /Inherited event handles | |
// instance_init(this, object_index, parent_index, visible, depth, sprite, collideable, inner index) | |
// Universal object constructor: | |
function __instance_init__(_this, _oi, _p, _v, _d, _si, _c, _io) { | |
_this._object_index = undefined; | |
_this._object_index_ = _io; | |
_this._depth = undefined; | |
_this._depthn = undefined; | |
_this._depthu = false; | |
var_override(_this, 'depth', tu_depth_get, tu_depth_set ); | |
var_override(_this, 'object_index', tu_type_get, tu_idle ); | |
var_override(_this, 'image_single', image_single_get, image_single_set ); | |
var_override(_this, 'id', tu_id_get, tu_idle); | |
var_override(_this, 'parent', tu_parent_get, tu_idle); | |
_this._object_index = _oi; | |
_this._parent_index = _p; | |
_this.xstart = _this.xprevious = _this.x = 0; | |
_this.ystart = _this.yprevious = _this.y = 0; | |
_this.depthstart = _d; | |
_this.image_angle = _this.direction = 0; | |
_this.visible = _v; | |
_this.image_yscale = _this.image_xscale = 1; | |
_this.image_alpha = 1; | |
_this.image_index = 0; | |
_this.image_speed = 1; | |
_this.sprite_index = _si; | |
_this.speed = 0; | |
_this.other = null; | |
_this.collision_checking = _c; | |
_this.persistent = false; | |
_this.instance_active = false; | |
// Instance-specific functions: | |
_this.place_meeting = __place_meeting__; | |
_this.move_towards_point = __move_towards_point__; | |
_this.instance_destroy = __instance_destroy__; | |
_this.draw_self = __draw_self__; | |
} | |
// Universal sprite constructor: | |
function __sprite_init__(_this, _name, _width, _height, _xofs, _yofs, _cshape, _crad, _cl, _cr, _ct, _cb, _frames) { | |
_this.frames = []; | |
var _frame, _fi; | |
for (_fi = 0; _fi < _frames.length; _fi++) { | |
_frame = new Image(); | |
if (_frames[_fi]) { | |
tu_loading_inc(); | |
_frame.onload = tu_loading_dec; | |
_frame.onerror = tu_loading_dec; | |
_frame.src = _frames[_fi]; | |
} | |
_this.frames.push(_frame); | |
} | |
_this.width = _width; | |
_this.height = _height; | |
_this.xoffset = _xofs; | |
_this.yoffset = _yofs; | |
_this.collision_shape = (_cshape == 'Circle' ? ct_circle : _cshape == 'Box' ? ct_box : 0); | |
_this.collision_radius = _crad; | |
_this.collision_left = _cl; | |
_this.collision_right = _cr; | |
_this.collision_top = _ct; | |
_this.collision_bottom = _cb; | |
tu_sprites.push(_this); | |
} | |
// Universal audio constructor: | |
function __audio_init__(_this, _name, _wav, _mp3, _ogg) { | |
var _src = ''; | |
_this.type = 'none'; | |
if (tu_ogg_supported && (_ogg != '')) { | |
_this.type = 'ogg'; | |
_src = _ogg; | |
} else if (tu_mp3_supported && (_mp3 != '')) { | |
_this.type = 'mp3'; | |
_src = _mp3; | |
} else if (tu_wav_supported && (_wav != '')) { | |
_this.type = 'wav'; | |
_src = _wav; | |
} | |
if (_src != '') { | |
_this.audio = document.createElement('audio'); | |
_this.audio.setAttribute('src', _src); | |
} | |
tu_audios.push(_this); | |
} | |
function __background_init__(_this, _name, _file) { | |
_this.image = new Image(); | |
tu_loading_inc(); | |
_this.image.onload = tu_loading_dec; | |
_this.image.onerror = tu_loading_dec; | |
_this.image.src = _file; | |
tu_backgrounds.push(_this); | |
} | |
function __font_init__(_this, _name, _family, _size, _bold, _italic) { | |
_this.family = _family; | |
_this.size = _size; | |
_this.bold = _bold; | |
_this.italic = _italic; | |
tu_fonts.push(_this); | |
} | |
// (this, name, width, height, speed, back. red, back. green, back. blue, background, back. tilex, back. tiley, back. stretch, view width, view height, view object, view hborder, view vborder) | |
function __room_start__(_this, _name, _rw, _rh, _rs, _br, _bg, _bb, _bi, _bx, _by, _bs, _vw, _vh, _vo, _vx, _vy) { | |
_$_('tululoogame').innerHTML = "<canvas id='" + tu_canvas_id + "' width='" + _vw + "' height='" + _vh + "' style='" + tu_canvas_css + "'></canvas>"; | |
tu_canvas = _$_(tu_canvas_id); | |
tu_context = tu_canvas.getContext('2d'); | |
room_current = _this; | |
// generic: | |
room_speed = _rs; | |
room_width = _rw; | |
room_height = _rh; | |
// background color: | |
room_background_color_red = _br; | |
room_background_color_green = _bg; | |
room_background_color_blue = _bb; | |
// background image: | |
room_background = _bi; | |
room_background_x = 0; | |
room_background_y = 0; | |
room_background_tile_x = _bx; | |
room_background_tile_y = _by; | |
room_background_tile_stretch = _bs; | |
// view: | |
room_viewport_width = _vw; | |
room_viewport_height = _vh; | |
room_viewport_x = room_viewport_y = 0; | |
room_viewport_object = _vo; | |
room_viewport_hborder = _vx; | |
room_viewport_vborder = _vy; | |
// tiles: | |
var _l, _b, _t, _i, _il, _tls_, i, l, d, o, a; | |
_tls_ = _this.tiles; tu_tiles = []; tu_tilesi = []; | |
for (_l = 0; _l < _tls_.length; _l++) | |
for (_b = 1; _b < _tls_[_l].length; _b++) | |
for (_t = 1; _t < _tls_[_l][_b].length; _t++) | |
tile_add(_tls_[_l][_b][0], _tls_[_l][_b][_t][0], _tls_[_l][_b][_t][1], _tls_[_l][_b][_t][2], _tls_[_l][_b][_t][3], _tls_[_l][_b][_t][4], _tls_[_l][_b][_t][5], _tls_[_l][0]); | |
// objects: | |
tu_depth = []; tu_depthi = []; tu_depthu = []; tu_types = []; | |
a = _this.objects; | |
l = a.length; | |
for (i = 0; i < l; i++) { | |
d = a[i]; | |
d = d[0]; // temp.fix for rc2 | |
if (d.o === undefined) continue; | |
o = instance_create_(d.x, d.y, d.o); | |
if (d.s !== undefined) o.sprite_index = d.s; | |
if (d.d !== undefined) o.direction = d.d; | |
if (d.a !== undefined) o.image_angle = d.a; | |
if (d.u !== undefined) o.image_xscale = d.u; | |
if (d.v !== undefined) o.image_yscale = d.v; | |
if (d.c !== undefined) d.c.apply(o); | |
} | |
// persistent objects: | |
_l = tu_persist.length | |
for (_t = 0; _t < _l; _t++) instance_activate(tu_persist[_t]); | |
instance_foreach(function(o) { | |
if (tu_persist.indexOf(o) != -1) return; | |
o.on_creation(); | |
}); | |
tu_persist = []; | |
// | |
instance_foreach(function(o) { | |
o.on_roomstart(); | |
}); | |
} | |
function tu_preloader() { | |
var _w = Math.min(400, (tu_canvas.width * 0.6) >> 0), _h = 16, | |
_x = (tu_canvas.width - _w) >> 1, _y = (tu_canvas.height - _h) >> 1, | |
_p = (tu_load_total - tu_loading) / tu_load_total, | |
_s = "Loading resources: " + (tu_load_total - tu_loading) + "/" + (tu_load_total); | |
tu_canvas.width = tu_canvas.width; | |
tu_canvas.height = tu_canvas.height; | |
tu_canvas.style.backgroundColor = "rgb(42, 42, 42)"; | |
tu_context.font = "italic 12px Verdana"; | |
tu_context.textAlign = "left"; | |
tu_context.textBaseline = "bottom"; | |
tu_context.fillStyle = tu_context.strokeStyle = "rgba(192, 192, 192, 1)"; | |
tu_context.fillRect(_x - 1, _y - 1, _w + 2, _h + 2); | |
tu_context.fillStyle = tu_context.strokeStyle = "rgba(0, 0, 0, 1)"; | |
tu_context.fillRect(_x, _y, _w, _h); | |
tu_context.fillStyle = tu_context.strokeStyle = "rgba(255, 255, 255, 1)"; | |
tu_context.fillRect(_x + 2, _y + 2, (_w - 4) * _p, _h - 4); | |
tu_context.fillText(_s, _x, _y - 2); | |
} | |
function tu_render_back() { | |
if (room_background == null) return; | |
if (room_background_tile_stretch) { | |
tu_context.drawImage(room_background, 0 - room_viewport_x, 0 - room_viewport_y, room_width, room_height); | |
return; | |
} | |
var _bw, _bh, _bx, _by, _vx, _vy, _vw, _vh, _x1, _x2, _y1, _y2, _ht, _vt; | |
_bw = room_background.width; | |
_bh = room_background.height; | |
_bx = room_background_x; | |
if (room_background_tile_x) { _bx = _bx < 0 ? _bw - _bx % _bw : _bx % _bw; } | |
_by = room_background_y; | |
if (room_background_tile_y) { _bx = _by < 0 ? _bh - _by % _bh : _by % _bh; } | |
// | |
_vx = room_viewport_x; | |
_vy = room_viewport_y; | |
_vw = room_viewport_width; | |
_vh = room_viewport_height; | |
// | |
_x1 = room_background_tile_x ? Math.floor(_vx / _bw) * _bw - _bx : -_bx; | |
_x2 = room_background_tile_x ? Math.floor((_vx + _vw + _bw) / _bw) * _bw : _x1 + _bw; | |
_y1 = room_background_tile_y ? Math.floor(_vy / _bh) * _bh - _by : -_by; | |
_y2 = room_background_tile_y ? Math.floor((_vy + _vh + _bh) / _bh) * _bh : _y1 + _bh; | |
for (_ht = _x1; _ht < _x2; _ht += _bw) | |
for (_vt = _y1; _vt < _y2; _vt += _bh) | |
tu_context.drawImage(room_background, _ht - _vx, _vt - _vy); | |
} | |
// @1.2.6 | |
function instance_activate(_i) { | |
if (_i.instance_active) return; | |
for (var o = _i._object_index; o; o = o.parent) tu_type_add(o, _i); | |
//tu_type_add(_i._object_index, _i); | |
//if (_i.parent != null) tu_type_add(_i.parent, _i); | |
tu_depth_add(_i._depth, _i); | |
_i.instance_active = true; | |
} | |
// @1.2.6 | |
function instance_deactivate(_i) { | |
if (!_i.instance_active) return; | |
for (var o = _i._object_index; o; o = o.parent) tu_type_delete(o._object_index_, _i); | |
//tu_type_delete(_i, _i._object_index_); | |
//if (_i.parent != null) tu_type_delete(_i, _i.parent._object_index_); | |
tu_depth_delete(_i._depth, _i); | |
_i.instance_active = false; | |
} | |
// @1.2.6 Performs function for all instances | |
function instance_foreach(_function) { | |
var _d, _l, _o; | |
for (_d in tu_depth) { | |
_l = tu_depth[_d]; | |
for (_o = 0; _o < _l.length; _o++) _function(_l[_o]); | |
} | |
} | |
// @1.2.6 Performs function for all instances on specific depth | |
function instance_fordepth(_depth, _function) { | |
var _o, _d = tu_depthc[_depth], _l; | |
if (_d == null) return; | |
_l = _d.length; | |
for (_o = 0; _o < _l; _o++) _function(_d[_o]); | |
} | |
// @1.2.6 Actions performed on room switch | |
function tu_room_switchto_(_o) { | |
_o.on_roomend(); | |
if (!_o.persistent) return; | |
tu_persist.push(_o); | |
instance_deactivate(_o); | |
} | |
function tu_room_switchto(_dest) { | |
tu_persist = []; | |
instance_foreach(tu_room_switchto_); | |
room_current = _dest; | |
tu_room_to_go = null; | |
room_current.start(); | |
} | |
// @1.0.0 Global step event | |
function tu_step() { | |
// object step events: | |
tu_trash = []; | |
var tu_deptho, tu_depthl, _obj_, _objd_, _h, _v; | |
for (tu_depthd in tu_depth) { | |
tu_depthc = tu_depth[tu_depthd]; | |
tu_depthl = tu_depthc.length; | |
for (tu_deptho = 0; tu_deptho < tu_depthl; tu_deptho++) { | |
_obj_ = tu_depthc[tu_deptho]; | |
// is viewport object? | |
if (room_viewport_object != null && tu_viewport_inst == null && (_obj_.object_index == room_viewport_object || _obj_.parent == room_viewport_object)) { | |
tu_viewport_inst = _obj_; | |
} | |
// step events: | |
_obj_.on_step(); | |
// move object: | |
if (_obj_.speed != 0) { | |
_objd_ = _obj_.direction * tu_d2r; | |
_obj_.x += _obj_.speed * Math.cos(_objd_); | |
_obj_.y += _obj_.speed * Math.sin(_objd_); | |
} | |
// post-step events: | |
_obj_.on_collision(); | |
_obj_.on_end_step(); | |
// post: | |
_obj_.xprevious = _obj_.x; | |
_obj_.yprevious = _obj_.y; | |
} | |
} | |
// follow object | |
if (tu_viewport_inst != null) { | |
_h = min(room_viewport_hborder, room_viewport_width / 2); | |
_v = min(room_viewport_vborder, room_viewport_height / 2); | |
// hborder: | |
if (tu_viewport_inst.x < room_viewport_x + _h) room_viewport_x = tu_viewport_inst.x - _h; | |
if (tu_viewport_inst.x > room_viewport_x + room_viewport_width - _h) room_viewport_x = tu_viewport_inst.x - room_viewport_width + _h; | |
// vborder: | |
if (tu_viewport_inst.y < room_viewport_y + _v) room_viewport_y = tu_viewport_inst.y - _v; | |
if (tu_viewport_inst.y > room_viewport_y + room_viewport_height - _v) room_viewport_y = tu_viewport_inst.y - room_viewport_height + _v; | |
// limits: | |
room_viewport_x = Math.max(0, Math.min(room_viewport_x, room_width - room_viewport_width)) >> 0; | |
room_viewport_y = Math.max(0, Math.min(room_viewport_y, room_height - room_viewport_height)) >> 0; | |
} | |
} | |
function tu_draw() { | |
// clear canvas: | |
if (room_background_color_show) { | |
tu_canvas.width = tu_canvas.width; | |
tu_canvas.height = tu_canvas.height; | |
// set background color: | |
tu_canvas.style.backgroundColor = "rgb(" + room_background_color_red + "," + room_background_color_green + "," + room_background_color_blue + ")"; | |
} | |
tu_render_back(); | |
tile_layer_last = 0; | |
var tu_depthc, tu_depthv, tu_deptho, tu_depthl, _obj_; | |
for (tu_depthd in tu_depth) { | |
tu_depthc = tu_depth[tu_depthd]; | |
tu_depthv = tu_depthi[tu_depthd]; | |
for (; tu_tilesi[tile_layer_last] >= tu_depthv && tile_layer_last < tu_tiles.length; tile_layer_last++) | |
{ | |
tile_lrender(tu_tiles[tile_layer_last]); | |
} | |
tu_depthl = tu_depthc.length; | |
for (tu_deptho = 0; tu_deptho < tu_depthl; tu_deptho++) { | |
_obj_ = tu_depthc[tu_deptho]; | |
if (_obj_.visible) _obj_.on_draw(); | |
_obj_.on_animationend(); | |
} | |
} | |
// render remaining tile layers: | |
for (; tile_layer_last < tu_tiles.length; tile_layer_last++) { | |
tile_lrender(tu_tiles[tile_layer_last]); | |
} | |
} | |
function tu_prestep() { | |
// clear mouse states and keypressed / keyrelesed statuses | |
mouse_pressed = false; | |
mouse_released = false; | |
var _k, _r, _obj_; | |
for (_k = 0; _k < tu_keys_pressed.length; _k++) key_pressed[tu_keys_pressed[_k]] = false; | |
for (_k = 0; _k < tu_keys_released.length; _k++) key_released[tu_keys_released[_k]] = false; | |
tu_keys_pressed = []; | |
tu_keys_released = []; | |
// remove objects from destroy stack | |
for (_r = 0; _r < tu_trash.length; _r++) { | |
_obj_ = tu_trash[_r]; | |
if (tu_modal == _obj_) tu_modal = null; | |
_obj_.depth = undefined; | |
tu_type_delete(_obj_, _obj_._object_index_); | |
if (_obj_.parent != null) tu_type_delete(_obj_, _obj_.parent._object_index_); | |
_obj_.on_destroy(); | |
} | |
} | |
function tu_loop() { | |
// calculate render time | |
tu_frame_time = tu_gettime(); | |
tu_elapsed = (tu_frame_time - tu_prev_frame_time); | |
tu_frame_step += tu_elapsed; | |
tu_frame_el += tu_elapsed; | |
// continue game with the UN-Pause key | |
if (tu_paused && keyboard_check_pressed(tu_unpausekey)) tu_paused = false; | |
// | |
if (tu_room_to_go != null && tu_canvas == null) tu_room_switchto(tu_room_to_go); | |
// render game: | |
if (tu_frame_step >= 1000 / room_speed && tu_loading == 0 && tu_canvas != null && !tu_paused) { | |
tu_frame_count++; | |
tu_elapsed = tu_frame_time - tu_prev_cycle_time; | |
tu_prev_cycle_time = tu_frame_time; | |
tu_frame_step -= 1000 / room_speed; | |
if (tu_frame_step < 0 || tu_frame_step > 1024) tu_frame_step = 0; | |
// start next room, if any: | |
if (tu_room_to_go != null) tu_room_switchto(tu_room_to_go); | |
// | |
tu_redraw = tu_redraw_auto; | |
if (tu_modal != null) { | |
tu_modal.on_step(); | |
if (tu_modal != null) tu_modal.on_end_step(); | |
} else tu_step(); | |
tu_depth_update(); | |
if (tu_redraw) { | |
if (tu_modal == null || tu_modaldraw) tu_draw(); | |
else tu_modal.on_draw(); | |
} | |
tu_depth_update(); | |
tu_prestep(); | |
tu_depth_update(); | |
} else if (tu_loading > 0) tu_preloader(); | |
// calculate fps: | |
if (tu_frame_el >= Math.floor(200 / room_speed) * 5 * room_speed) | |
{ | |
fps = Math.ceil(tu_frame_count * 1000 / tu_frame_el); | |
if (fps > room_speed) fps = room_speed; | |
tu_frame_el = tu_frame_count = 0; | |
} | |
// repeat | |
tu_prev_frame_time = tu_frame_time; | |
setTimeout(tu_gameloop, 5); | |
} | |
tu_init(); | |
/*********************************************************************** | |
* EXTENSIONS | |
***********************************************************************/ | |
//TULULOO_EXTENSIONS | |
/*********************************************************************** | |
* SPRITES | |
***********************************************************************/ | |
//TULULOO_SPRITES | |
/*********************************************************************** | |
* SOUNDS | |
***********************************************************************/ | |
//TULULOO_SOUNDS | |
/*********************************************************************** | |
* MUSICS | |
***********************************************************************/ | |
//TULULOO_MUSICS | |
/*********************************************************************** | |
* BACKGROUNDS | |
***********************************************************************/ | |
//TULULOO_BACKGROUNDS | |
/*********************************************************************** | |
* FONTS | |
***********************************************************************/ | |
//TULULOO_FONTS | |
/*********************************************************************** | |
* OBJECTS | |
***********************************************************************/ | |
//TULULOO_OBJECTS | |
/*********************************************************************** | |
* SCENES | |
***********************************************************************/ | |
//TULULOO_SCENES | |
/*********************************************************************** | |
* CUSTOM GLOBAL VARIABLES | |
***********************************************************************/ | |
//TULULOO_GLOBAL_VARIABLES | |
/*********************************************************************** | |
* CUSTOM GLOBAL FUNCTIONS | |
***********************************************************************/ | |
//TULULOO_GLOBAL_FUNCTIONS | |
tu_gameloop = tu_loop; | |
tu_loop(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment