Untitled
unknown
javascript
2 years ago
43 kB
53
Indexable
/*
This is the main game file for the framework. It handles objects and advanced math functions.
*/
isothermalgame = class {
className = "isothermalgame";
constructor() {
// CONSTANTS
this.pi = Math.PI; // PI
//this.self = -1; // The instance which is executing the current block of code
this.other = -2; // The other instance involved in a collision event, or the other instance from a with function
//this.all = -3; // All instances currently active in the room
this.noone = -4; // No instance at all
// COLOR CONSTANTS
this.c_red = rgb(255, 0, 0);
this.c_white = rgb(255, 255, 255);
this.c_black = rgb(0, 0, 0);
this.c_ltgray = rgb(176, 176, 176);
this.c_gray = rgb(128, 128, 128);
this.c_dkgray = rgb(64, 64, 64);
this.c_blue = rgb(0, 0, 255);
this.c_lime = rgb(0, 255, 0);
this.c_green = rgb(0, 145, 0);
this.c_yellow = rgb(255, 255, 0);
this.c_orange = rgb(255, 176, 0);
this.c_purple = rgb(255, 0, 255);
this.a_100 = 1.0; // Alpha full
this.a_50 = 0.5; // Alpha half
this.a_0 = 0.0; // Alpha none
this.a_25 = 0.25; // Alpha 1/4
this.a_75 = 0.75; // Alpha 3/4
// HIDDEN GLOBAL VARIABLES
this.gameObjects = []; // The game object list
this.mx = 0; // Base mouse x
this.my = 0; // Base mouse y
this.tx = 0; // Touch x
this.ty = 0; // touch y
// GLOBAL VARIABLES
this.control = noone; // The global instance
this.room_width = 200;
this.room_height = 100;
this.view_xview = 0;
this.view_yview = 0;
this.view_wview = 200;
this.view_hview = 100;
this.view_angle = 0;
this.mouse_x = 0;
this.mouse_y = 0;
this.score = 0;
this.health = 100;
this.lives = 3;
this.instance_count = 0;
this.object_count = 0;
this.delta_time = 0;
this.time_scale = 1.0; // The time scale can be used for slow motion or game pausing
this.time_current = new Date().getTime();
this.fps = 0;
}
game_restart = function()
{
game_start();
}
// Restart the app with javascript input
this.game_restart_code = function(c)
{
game_start();
execute_string(c);
}
// Start the game
this.game_start = function()
{
gameObjects = [];
room_width = 1024;
room_height = 768;
view_xview = 0;
view_yview = 0;
view_wview = 640;
view_hview = 480;
time_scale = 1.0;
lastTick = new Date().getTime();
}
// Return a random skin color(based on real skin colors)
this.random_skin_color = function()
{
var col = '#FFFFFF';
switch (irandom(3))
{
case 0:
col = ('#FFE0BD');
break;
case 1:
col = ('#FFCD94');
break;
case 2:
col = ('#FFE39F');
break;
case 3:
col = ('#633C1D');
break;
}
return(col);
}
// Create a new instance of an object
this.instance_create = function(x, y, object)
{
var temp = object.instantiate(x, y);
temp.isParent = false;
return(temp);
}
// Create a new object that we can then add instances of to the game world
this.object_add = function()
{
var temp = new gameObject(0, 0, 0, 0);
gameObjects.push(temp);
return(temp);
}
// Game object
this.gameObject = function(x, y, width, height)
{
this.instances = [];
this.isParent = true;
this.object_id = noone;
this.id = 0;
this.need_removed = false;
this.has_sorted_depth = true;
this.need_sorted = false;
this.use_built_in_physics = true;
this.active = true;
this.visible = true;
// Hotspots are points on object like anchor points we can attatch other objects to
this.hotspot_x = [];
this.hotspot_y = [];
this.x = x;
this.y = y;
this.xstart = x;
this.ystart = y;
this.xprevious = x;
this.yprevious = y;
this.bbox_left = 0;
this.bbox_top = 0;
this.bbox_right = 0;
this.bbox_bottom = 0;
this.center_x = 0;
this.center_y = 0;
this.depth = 0;
this.width = width;
this.height = height;
this.hspeed = 0;
this.vspeed = 0;
this.friction = 0;
this.speed = 0;
this.direction = 0;
this.gravity = 0;
this.gravity_direction = 270;
this.offset_x = 0; // Collision box offset x
this.offset_y = 0; // Collision box offset y
this.hasWoken = false;
// When the object is first created
this.awake = function()
{};
// Perform on every loop
this.loop = function()
{};
// Perform before every loop
this.loop_begin = function()
{};
// Perform after every loop
this.loop_end = function()
{};
// Draw on every loop
this.draw = function()
{};
// Will be drawn very last, and on top of every normal draw event
this.draw_gui = function()
{};
// The update called in the game update method (DO NOT OVER WRITE)
this.updateMain = function()
{
if(!this.hasWoken)
{
this.awake();
this.hasWoken = true;
this.xstart = this.x;
this.ystart = this.y;
}
this.loop_begin();
this.xprevious = this.x;
this.yprevious = this.y;
//this.image_index += 1 % this.image_number;
this.loop();
if(this.use_built_in_physics)
{
// The speed functionality
if(this.speed != 0)
{
this.hspeed = lengthdir_x(this.speed, this.direction);
this.vspeed = lengthdir_y(this.speed, this.direction);
}
// Horizontal speed and vertical speed functionality
if(this.hspeed != 0)
{
this.x += this.hspeed * time_scale;
}
if(this.vspeed != 0)
{
this.y += this.vspeed * time_scale;
}
// Gravity functionality
if(this.gravity != 0)
{
this.hspeed += lengthdir_x(this.gravity, this.gravity_direction);
this.vspeed += lengthdir_y(this.gravity, this.gravity_direction);
}
// Have the friction work like game maker
if(this.friction > 0)
{
this.hspeed *= ceil(this.friction) - this.friction;
this.vspeed *= ceil(this.friction) - this.friction;
}
else
{
this.hspeed *= 1 - this.friction;
this.vspeed *= 1 - this.friction;
}
}
if(this.object_id.instances[0] == this) // If we are the first object in the line
{
this.object_id.sort_by_depth();
}
// Stop direction from exceeding 360 degrees
this.direction = (this.direction % 360.0);
// Collision positions
this.bbox_left = this.x - this.offset_x;
this.bbox_top = this.y - this.offset_y;
this.bbox_right = this.bbox_left + this.width;
this.bbox_bottom = this.bbox_top + this.height;
// Center of the object based on the collision box center
this.center_x = this.bbox_left + (this.width / 2);
this.center_y = this.bbox_top + (this.height / 2);
this.loop_end();
};
// Sort the instances based on their depth
this.sort_by_depth = function()
{
var len = this.instances.length;
if(len > 1)
{
for(var i = len - 1; i >= 0; i -= 1) // Loop through instances
{
for(var j = 1; j <= i; j += 1)
{
var d1 = this.instances[j].depth;
var d2 = this.instances[j - 1].depth;
if(d2 < d1)
{
var temp2 = this.instances[j - 1];
this.instances[j - 1] = this.instances[j];
this.instances[j] = temp2;
}
}
}
}
}
// The draw called in the game update method (DO NOT OVER WRITE)
this.mainDraw = function()
{
this.draw();
};
// This is called after every other event, so everything will be drawn last in this event
this.mainDrawGui = function()
{
this.draw_gui();
}
// Add a new instance to this object
this.instantiate = function(x, y)
{
var temp = new gameObject(x, y, this.width, this.height);
temp.hasWoken = false;
temp.awake = this.awake;
temp.loop = this.loop;
temp.loop_begin = this.loop_begin;
temp.loop_end = this.loop_end;
temp.draw = this.draw;
temp.draw_gui = this.draw_gui;
temp.object_id = this;
temp.id = this.id;
temp.isParent = false;
this.instances.push(temp);
this.id += 1;
return(temp);
};
// Check if there are inactive instaces waiting to be removed, and if so, remove them
this.clean_up_instances = function()
{
for(var i = 0; i < this.instances.length; i += 1)
{
var ins = this.instances[i];
if(!ins.active)
{
if(ins.need_removed)
{
this.instances.splice(i, 1);
}
}
}
};
// Remove this instance from the object_id instances list
this.instance_destroy = function()
{
this.active = false;
this.need_removed = true;
//object_id.clean_up_instances(); // Make the parent object clean up resources
};
// Add motion towards a direction
this.motion_add = function(direction, speed)
{
this.speed += speed;
this.direction = direction;
};
// Set motion in a direction
this.motion_set = function(direction, speed)
{
this.speed = speed;
this.direction = direction;
};
// Move the object towards a point at a speed
this.move_towards_point = function(x, y, speed)
{
var pos = point_direction(this.x, this.y, x, y);
this.motion_set(pos, speed);
}
// Snap the object to a grid
this.move_snap = function(hsnap, vsnap)
{
this.x = snap(this.x, hsnap);
this.y = snap(this.y, vsnap);
};
// Reverse the directions, takes in booleans
this.move_bounce = function(hbounce, vbounce, dirbounce)
{
if(hbounce)
{
if(dirbounce)
{
this.direction = 2 * 0 - this.direction - 180;
}
else
{
this.hspeed *= -1;
}
}
if(vbounce)
{
if(dirbounce)
{
this.direction = 2 * 90 - this.direction - 180;
}
else
{
this.vspeed *= -1;
}
}
};
// Check if the object is within the view bounds
this.within_view = function()
{
var x1, y1, x2, y2;
x1 = this.x;
y1 = this.y;
x2 = this.x + this.width;
y2 = this.y + this.height;
return (x2 > 0 && y2 > 0 && x1 < view_xview + view_wview && y1 < view_yview + view_hview);
}
// Check if the mouse is within the instances bounds
this.mouse_over = function()
{
return (mouse_x > this.x && mouse_y > this.y && mouse_x < this.x + this.width && mouse_y < this.y + this.height);
}
// Check if the mouse is within the instances bounds
this.point_inside = function(x, y)
{
return (x > this.x && y > this.y && x < this.x + this.width && y < this.y + this.height);
}
// Move the object
this.move_contact = function(dir, maxdist, object)
{
var dist = 1000;
if(maxdist == 0 || maxdist == -1)
{
dist = 1000;
}
else
{
dist = maxdist;
}
for(var i = 0; i < dist; i += 1)
{
this.x += lengthdir_x(1, dir);
this.y += lengthdir_y(1, dir);
for(var j = 0; j < object.instances.length; j += 1)
{
var ins = object.instances[j];
if(ins.active && this.active)
{
if(checkCollision(this, ins))
{
return (true);
}
}
}
}
return(false);
}
// If there is an instance at the location hor or ver, push self in the opposite direction at the amount until there is no longer a collision
this.jump_outside = function(amount, object)
{
var ret;
ret = false;
for(var i = 0; i < object.instances.length; i += 1)
{
var ins = object.instances[i];
if(ins.active && this.active)
{
while(checkCollision(this, ins))
{
var dir = point_direction(ins.bbox_right / 2, ins.bbox_bottom / 2, this.bbox_right / 2, this.bbox_bottom / 2);
this.x = this.x + lengthdir_x(amount, dir);
this.y = this.y + lengthdir_y(amount, dir);
}
}
}
}
// If there is an instance at the location hor or ver, push self in the opposite direction at the amount until there is no longer a collision
this.push_outside = function(amount, object)
{
var ret;
ret = false;
for(var i = 0; i < object.instances.length; i += 1)
{
var ins = object.instances[i];
if(ins.active && this.active)
{
if(checkCollision(this, ins))
{
var dir = point_direction(ins.bbox_right / 2, ins.bbox_bottom / 2, this.bbox_right / 2, this.bbox_bottom / 2);
this.x = this.x + lengthdir_x(amount, dir);
this.y = this.y + lengthdir_y(amount, dir);
}
}
}
}
// Return if there is a collision with a grid world
this.gridworld_place_meeting = function(x, y, id)
{
var xOld, yOld, ret;
ret = false;
xOld = this.x;
yOld = this.y;
this.x = x;
this.y = y;
this.x = xOld;
this.y = yOld;
return (ret);
}
// Return if there is a collision with an instance
this.place_meeting = function(x, y, object)
{
var xOld, yOld, ret;
ret = false;
xOld = this.x;
yOld = this.y;
this.x = x;
this.y = y;
for(var i = 0; i < object.instances.length; i += 1)
{
var ins = object.instances[i];
if(ins.active && this.active)
{
if(checkCollision(this, ins))
{
ret = true;
}
}
}
this.x = xOld;
this.y = yOld;
return (ret);
}
// Return a collision with an instance and return the instance
this.instance_place = function(x, y, object)
{
var xOld, yOld, ret;
ret = noone;
xOld = this.x;
yOld = this.y;
this.x = x;
this.y = y;
for(var i = 0; i < object.instances.length; i += 1)
{
var ins = object.instances[i];
if(ins.active && this.active)
{
if(collision_with(ins))
{
ret = ins;
}
}
}
this.x = xOld;
this.y = yOld;
return (ret);
}
// Detect collision with another instance of object type
this.collision_with = function(object)
{
if(!this.isParent)
{
for(var i = 0; i < object.instances.length; i += 1)
{
if(this != object.instances[i] && object.instances[i].active)
{
if(checkCollision(object.instances[i], this))
{
//alert('this = ' + this.id + ', other = ' + object.instances[i].id);
return(object.instances[i]);
}
}
}
}
return(noone);
}
// Get the nearest instance of an object to a point
this.instance_nearest = function(x, y, object)
{
var nearest = noone;
var dist = 9999999;
for(var i = 0; i < object.instances.length; i += 1)
{
if(object.instances[i] != this && object.instances[i].active)
{
var dist2 = point_distance(x, y, object.instances[i].x, object.instances[i].y);
if(dist2 < dist)
{
dist = dist2;
nearest = object.instances[i];
}
}
}
return(nearest);
}
}
// Set the view centered to a position with a smootheness value(8 is a good smoothness value)
view_center_position = function(x, y, smoothness)
{
if(smoothness == 0)
{
view_xview = x - (view_wview / 2);
view_yview = y - (view_hview / 2);
}
else
{
var xx, yy, xt, yt, dir, dist;
xx = view_xview + (view_wview / 2); // Center X position
yy = view_yview + (view_hview / 2); // Center Y position
xt = x;
yt = y;
dir = point_direction(xx, yy, xt, yt);
dist = point_distance(xx, yy, xt, yt);
view_xview = (xx + lengthdir_x((dist / smoothness), dir)) - (view_wview / 2);
view_yview = (yy + lengthdir_y((dist / smoothness), dir)) - (view_hview / 2);
}
}
// Return the instance(if any) at the position set
instance_position = function(x, y, object)
{
for(var i = 0; i < object.instances.length; i += 1)
{
var ins = object.instances[i];
if(ins.point_inside(x, y))
{
return (ins);
}
}
return (noone);
}
checkCollision = function(object1, object2)
{
if(object1.active && object2.active)
{
if(object1.x < object2.x + object2.width && object1.x+ object1.width > object2.x &&
object1.y < object2.y + object2.height && object1.y + object1.height > object2.y)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
// Sort all of the objects based on their top instances depth
sortObjectsByDepth = function()
{
if(gameObjects.length > 0)
{
var len = gameObjects.length;
for(var i = len - 1; i >= 0; i -= 1) // Loop through instances
{
for(var j = 1; j <= i; j += 1)
{
if(gameObjects[j].instances.length > 0)
{
//gameObjects[j].instances[0].object_id.sort_by_depth();
var d1 = gameObjects[j].instances[0].depth;
var d2 = gameObjects[j - 1].instances[0].depth;
if(d2 < d1)
{
var temp2 = gameObjects[j - 1];
gameObjects[j - 1] = gameObjects[j];
gameObjects[j] = temp2;
}
}
}
}
}
}
/// 2D GRID BASED WORLD like terraria
// Create a new grid world
gridworld_create = function(width, height, blockSize, defaultBlockType)
{
this.width = width;
this.height = height;
this.block_size = blockSize;
this.grid = array2d_create(width, height, defaultBlockType);
return (this);
}
// Set the value of a gridworld position
gridworld_set = function(id, x, y, value)
{
id.grid[x][y] = value;
}
// Get the value of the gridworld position
gridworld_get = function(id, x, y)
{
return (id.grid[x][y]);
}
// Get the x view point in the grid world
gridworld_view_x = function(id)
{
return (floor(view_xview / id.block_size));
}
// Get the position + width of the viewport in grid position
gridworld_view_width = function(id)
{
ceil((view_xview + view_wview) / id.block_size);
}
// Get the y view point in the grid world
gridworld_view_y = function(id)
{
return(floor(view_yview / id.block_size));
}
// Get the position + height of the viewport in grid position
gridworld_view_height = function(id)
{
ceil((view_yview + view_hview) / id.block_size);
}
// Get the width of the grid world
gridworld_get_width = function(id)
{
return (id.width);
}
// Get the height of the grid world
gridworld_get_height = function(id)
{
return (id.height);
}
// Get the block size in the grid world
gridworld_get_block_size = function(id)
{
return (id.block_size);
}
// Get the world position of the relative grid position
gridworld_grid_to_world = function(id, gridCell)
{
return(floor(gridCell * id.block_size));
}
// Get the relative grid position of the given world position
gridworld_world_to_grid = function(id, worldPosition)
{
return(floor(worldPosition / id.block_size));
}
// Get the world position of the relative grid position
gridworld_gtw = function(id, gridCell)
{
return(floor(gridCell * id.block_size));
}
// Get the relative grid position of the given world position
gridworld_wtg = function(id, worldPosition)
{
return(floor(worldPosition / id.block_size));
}
// Check if one of the objects has sorted by depth
objectHasSortedDepth = function()
{
for(var i = 0; i < gameObjects.length; i += 1)
{
if(gameObjects[i].has_sorted_depth)
{
gameObjects[i].has_sorted_depth = false;
return (true);
}
}
return (false);
}
// Main update loop
update_game_area = function()
{
// FPS CALCULATION
var delta = (new Date().getTime() - lastTick) / 1000;
lastTick = new Date().getTime();
fps = ceil(1 / delta);
time_current = new Date().getTime();
var oldViewAngle = view_angle; // Store the view angle
var oldViewW = view_wview;
var oldViewH = view_hview;
if(context != game.context)
{
context = game.context;
}
game.clear();
var insCount = 0; // InstanceCount
// This is the main game loop
for (var i = 0; i < gameObjects.length; i += 1)
{
if(gameObjects[i].instances != null)
{
for(var j = 0; j < gameObjects[i].instances.length; j += 1)
{
var ins = gameObjects[i].instances[j];
if(ins.active)
{
ins.updateMain();
insCount += 1;
}
}
}
}
for (var x = 0; x < gameObjects.length; x += 1)
{
if(gameObjects[x].instances != null)
{
for(var y = 0; y < gameObjects[x].instances.length; y += 1)
{
var ins = gameObjects[x].instances[y];
if(ins.visible && ins.active)
{
ins.mainDraw();
}
}
}
}
for (var x = 0; x < gameObjects.length; x += 1)
{
if(gameObjects[x].instances != null)
{
for(var y = 0; y < gameObjects[x].instances.length; y += 1)
{
var ins = gameObjects[x].instances[y];
if(ins.visible && ins.active)
{
ins.mainDrawGui();
}
}
}
}
instance_count = insCount;
object_count = gameObjects.length;
mouse_x = mx + view_xview;
mouse_y = my + view_yview;
// If the view angle has changed, change the canvas angle
/*if(oldViewAngle != view_angle)
{
draw_transform_begin();
context.translate(game.canvas.width / 2, game.canvas.height / 2);
context.rotate(degtorad(view_angle));
context.translate(-game.canvas.width / 2, -game.canvas.height / 2);
draw_transform_end();
}*/
if(oldViewH != view_hview)
{
game.canvas.height = view_hview;
}
if(oldViewW != view_wview)
{
game.canvas.width = view_wview;
}
view_angle % 360;
sortObjectsByDepth();
for(var i = 0; i < key_pressed.length; i += 1)
{
key_pressed[i] = false;
}
for(var i = 0; i < key_released.length; i += 1)
{
key_released[i] = false;
}
for(var i = 0; i < mouse_pressed.length; i += 1)
{
mouse_pressed[i] = false;
}
for(var i = 0; i < mouse_released.length; i += 1)
{
mouse_released[i] = false;
}
animationFrame = requestAnimationFrame(updateGameArea);
}
// Gets the number of instances of the given object
instance_number = function(object_id)
{
return(object_id.instances.length);
}
// Every timer tick
everyinterval = function(n)
{
if ((game.frameNo / n) % 1 == 0)
{
return true;
}
return false;
}
//#newfile BasicDrawing
// DRAWING STUFF
// Get color from rgb color values
rgb = function(r, g, b)
{
r = Math.floor(r);
g = Math.floor(g);
b = Math.floor(b);
return ["rgb(",r,",",g,",",b,")"].join("");
}
hsl = function(h, s, l)
{
r = Math.floor(h);
g = Math.floor(s) * 100;
b = Math.floor(l) * 100;
return ["hsl(",r,",",g,"%,",b,"%)"].join("");
}
// Cast a ray, and return a rayInfo about the ray
ray_cast = function(id, x, y, stepSize, length, direction, object)
{
var info = new ray_info();
this.id = id;
for(var i = 0; i < length; i += stepSize)
{
var xx = x + lengthdir_x(i, direction);
var yy = y + lengthdir_y(i, direction);
var ob = noone;
if(object != noone)
{
ob = instance_position(xx, yy, object);
}
if(ob != noone)
{
info.hit_instance = ob;
info.hit_distance = i;
return(info);
}
}
}
// To hold information about the distance etc of the ray
ray_info = function()
{
this.hit_instance = noone;
this.hit_distance = 0;
this.ray_id = 0;
}
//#newfile MathHelper
// ARRAY STUFF
// Create a new list
list_create = function()
{
var arr = [];
return(arr);
}
// Add to the list
list_add = function(id, value)
{
id.push(value);
}
// Set an item to a certain value in the list
list_set = function(id, pos, value)
{
id[pos] = value;
}
// Get the value of an item in the list
list_get = function(id, pos)
{
return(id[pos]);
}
// Create and initialize a 2d array
array2d_create = function(width, height, defaultValue)
{
var arr = [];
for(var i = 0; i < width; i += 1)
{
for(var j = 0; j < height; j += 1)
{
arr.push([i, j]);
arr[i][j] = defaultValue;
}
}
return(arr);
}
// Set the value of the 2d array
array2d_set = function(array, x, y, value)
{
array[x][y] = value;
}
// Get the value of the 2d array
array2d_get = function(array, x, y)
{
return(array[x][y]);
}
// Create and initialize a 2d array
array3d_create = function(width, height, depth, defaultValue)
{
var arr = [];
for(var i = 0; i < width; i += 1)
{
for(var j = 0; j < height; j += 1)
{
for(var f = 0; f < depth; f += 1)
{
arr.push([i, j, f]);
arr[i][j][f] = defaultValue;
}
}
}
return(arr);
}
// Set the value of the 2d array
array3d_set = function(array, x, y, z, value)
{
array[x][y][z] = value;
}
// Get the value of the 2d array
array3d_get = function(array, x, y, z)
{
return(array[x][y][z]);
}
// Clear the array
array_clear = function(array)
{
array = [];
return(array);
}
// MATH STUFF
// Returns the greatest integer less than or equal to its numeric argument
floor = function(x)
{
return (Math.floor(x));
}
// Returns the smallest integer greater than or equal to its numeric argument
ceil = function(x)
{
return (Math.ceil(x));
}
// Returns the absolute value of a number
abs = function(x)
{
return (Math.abs(x));
}
// Returns a supplied numeric expression rounded to the nearest number
round = function(x)
{
return (Math.round(x));
}
// Returns the value of a base expression taken to a specific power
power = function(x, y)
{
return (Math.pow(x, y));
}
// Returns the sine of a number
sin = function(x)
{
return (Math.sin(x));
}
// Returns the cosine of a number
cos = function(x)
{
return (Math.cos(x));
}
// Returns the cosine of a number from degrees to radians
this.dcos = function(x)
{
return (cos(degtorad(x)));
}
this.sign = function(x)
{
return (Math.sign(x));
}
// Returns degrees to radians
this.degtorad2 = function()
{
return ((pi * 2) / -360);
}
// Returns degrees to radians
this.degtorad = function(x)
{
return (x * pi / 180);
}
// Returns radians to degrees
this.radtodeg = function(x)
{
return (x * 180 / pi);
}
// Snap a position to a grid position
this.snap = function(position, grid_size)
{
return (floor(position / grid_size) * grid_size);
}
// Return the distance between 2 points
this.point_distance = function(x1, y1, x2, y2)
{
var a = (x1) - (x2);
var b = (y1) - (y2);
return (Math.sqrt((a * a) + (b * b)));
}
// Return the direction from one point to another
this.point_direction = function(x1, y1, x2, y2)
{
var xdiff = (x2) - x1;
var ydiff = (y2) - y1;
return (-(Math.atan2(ydiff, xdiff) * 180.0 / Math.PI));
}
// Returns the length and direction on the x axis
this.lengthdir_x = function(length, direction)
{
return (length * cos(direction * degtorad2()));
}
// Returns the length and direction on the y axis
this.lengthdir_y = function(length, direction)
{
return (length * sin(direction * degtorad2()));
}
// Lerp a value towards another value
this.lerp = function(from, to, amount)
{
return (from + amount * (to - from));
}
// Get the max value from the array
this.max = function(...values)
{
return (Math.max(values));
}
// Get the min value from the array
this.min = function(...values)
{
return (Math.min(values));
}
// Returns a random floating point from 1 to max value
this.random = function(max)
{
return ((Math.random() * max) + 1);
}
// Returns a random floating point from min to max value
this.random_range = function(min, max)
{
return (Math.random() * (max - min) + min);
}
// Returns a random integer from 1 to max value
this.irandom = function(max)
{
return (floor((Math.random() * max) + 1));
}
// Returns a random integer from min to max value
this.irandom_range = function(min, max)
{
return (floor(Math.random() * (max - min) + min));
}
// Returns either true or false
this.random_bool = function()
{
return (Math.random() >= 0.5);
}
// Replace every occurance of a string inside another string
this.string_replace_all = function(str, find, replace)
{
return (str.replace(new RegExp(escapeRegExp(find), 'g'), replace));
}
// Returns a value to a string
this.to_string = function(val)
{
return (val.toString());
}
// Converts a string to an integer
this.to_int = function(val)
{
return (parseInt(val));
}
// Returns a value pulsing at the rate of delay to a maximum number
/*
var red = pulse(10, 255);
*/
this.pulse = function(delay, max)
{
var val = sin(time_current / delay) * max;
return (val);
}
// Returns a value pulsing at the rate of delay from 0 to a maximum number
this.pulse_positive = function(delay, max)
{
var val = sin(time_current / delay) * max;
return (keep_positive(val));
}
// Returns a value pulsing at the rate of delay from 0 to a maximum number
this.pulse_negative = function(delay, max)
{
var val = sin(time_current / delay) * max;
return (keep_negative(val));
}
// Clamp a value to a max and min value
this.clamp = function(value, min, max)
{
if(value > max) { value = max; }
if(value < min) { value = min; }
return (value);
}
// Return a number that is always positive
this.keep_positive = function(x)
{
if(x < 0)
{
x *= -1;
}
return (x);
}
// Return a number that is always negative
this.keep_negative = function(x)
{
if(x > 0)
{
x *= -1;
}
return (x);
}
// Create a new vector2
this.vec2 = function(x, y)
{
this.x = x;
this.y = y;
}
// Create a new vector2
this.vec3 = function(x, y, z)
{
this.x = x;
this.y = y;
this.z = z;
}
/**
* Helper function to determine whether there is an intersection between the two polygons described
* by the lists of vertices. Uses the Separating Axis Theorem
*
* @param a an array of connected points [{x:, y:}, {x:, y:},...] that form a closed polygon
* @param b an array of connected points [{x:, y:}, {x:, y:},...] that form a closed polygon
* @return true if there is any intersection between the 2 polygons, false otherwise
*/
this.doPolygonsIntersect = function(a, b) {
var polygons = [a, b];
var minA, maxA, projected, i, i1, j, minB, maxB;
for (i = 0; i < polygons.length; i++) {
// for each polygon, look at each edge of the polygon, and determine if it separates
// the two shapes
var polygon = polygons[i];
for (i1 = 0; i1 < polygon.length; i1++) {
// grab 2 vertices to create an edge
var i2 = (i1 + 1) % polygon.length;
var p1 = polygon[i1];
var p2 = polygon[i2];
// find the line perpendicular to this edge
var normal = { x: p2.y - p1.y, y: p1.x - p2.x };
minA = maxA = undefined;
// for each vertex in the first shape, project it onto the line perpendicular to the edge
// and keep track of the min and max of these values
for (j = 0; j < a.length; j++) {
projected = normal.x * a[j].x + normal.y * a[j].y;
if (isUndefined(minA) || projected < minA) {
minA = projected;
}
if (isUndefined(maxA) || projected > maxA) {
maxA = projected;
}
}
// for each vertex in the second shape, project it onto the line perpendicular to the edge
// and keep track of the min and max of these values
minB = maxB = undefined;
for (j = 0; j < b.length; j++) {
projected = normal.x * b[j].x + normal.y * b[j].y;
if (isUndefined(minB) || projected < minB) {
minB = projected;
}
if (isUndefined(maxB) || projected > maxB) {
maxB = projected;
}
}
// if there is no overlap between the projects, the edge we are looking at separates the two
// polygons, and we know there is no overlap
if (maxA < minB || maxB < minA) {
console.log("polygons don't intersect!");
return false;
}
}
}
return true;
};
// Execute javascript code from a string
this.execute_string = function(string)
{
eval(string);
}
// Returns the width of the screen
this.screen_get_width = function()
{
return (screen.width);
}
// Returns the height of the screen
this.screen_get_height = function()
{
return (screen.height);
}
// Returns whether or not a rectangle is inside the view bounds
this.within_view = function(x1, y1, x2, y2)
{
var xx, yy, w, h; // View bounds
xx = view_xview;
yy = view_yview;
w = view_xview + view_wview;
h = view_yview + view_hview;
return (
x1 + (x2) >= xx && y1 + (y2) >= yy && x1 <= w && y1 <= h
);
}
// KEYBOARD KEYS
var 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;
}Editor is loading...
Leave a Comment