mirror of
https://gitgud.io/BondageProjects/Bondage-College.git
synced 2025-04-25 17:59:34 +00:00
429 lines
No EOL
14 KiB
JavaScript
429 lines
No EOL
14 KiB
JavaScript
// The main game canvas where everything will be drawn
|
|
var MainCanvas;
|
|
var TempCanvas;
|
|
var ColorCanvas;
|
|
|
|
// A bank of all the chached images
|
|
var DrawCacheImage = {};
|
|
var DrawCacheLoadedImages = 0;
|
|
var DrawCacheTotalImages = 0;
|
|
var DrawScreenWidth = -1;
|
|
var DrawScreenHeight = -1;
|
|
|
|
// Convert a hex color string to a RGB color
|
|
function DrawHexToRGB(color) {
|
|
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
|
color = color.replace(shorthandRegex, function(m, r, g, b) {
|
|
return r + r + g + g + b + b;
|
|
});
|
|
|
|
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);
|
|
return result ? {
|
|
r: parseInt(result[1], 16),
|
|
g: parseInt(result[2], 16),
|
|
b: parseInt(result[3], 16)
|
|
} : {
|
|
r: 0,
|
|
g: 0,
|
|
b: 0
|
|
};
|
|
}
|
|
|
|
// Returns the hex value of a RGB data
|
|
function DrawRGBToHex(rgb){
|
|
var rgb = rgb[2] | (rgb[1] << 8) | (rgb[0] << 16);
|
|
return '#' + (0x1000000 + rgb).toString(16).slice(1);
|
|
};
|
|
|
|
// Loads the drawing objects
|
|
function DrawLoad() {
|
|
|
|
// Creates the objects used in the game
|
|
MainCanvas = document.getElementById("MainCanvas").getContext("2d");
|
|
TempCanvas = document.createElement("canvas").getContext("2d");
|
|
ColorCanvas = document.createElement("canvas");
|
|
document.getElementById("MainCanvas").addEventListener("keypress", KeyDown);
|
|
document.getElementById("MainCanvas").tabIndex = 1000;
|
|
|
|
// Font is fixed for now, color can be set
|
|
MainCanvas.font = "36px Arial";
|
|
MainCanvas.textAlign = "center";
|
|
MainCanvas.textBaseline = "middle";
|
|
|
|
}
|
|
|
|
// Returns the image file or build it from the source
|
|
function DrawGetImage(Source) {
|
|
|
|
// Search in the cache to find the image
|
|
if (!DrawCacheImage[Source]) {
|
|
var img = new Image;
|
|
img.src = Source;
|
|
DrawCacheImage[Source] = img;
|
|
|
|
// Reloads all character canvas once everything is loaded
|
|
if (Source.indexOf("Assets") >= 0) {
|
|
DrawCacheTotalImages++;
|
|
img.onload = function () {
|
|
DrawCacheLoadedImages++;
|
|
if (DrawCacheLoadedImages == DrawCacheTotalImages)
|
|
CharacterLoadCanvasAll();
|
|
}
|
|
}
|
|
}
|
|
|
|
// returns the final image
|
|
return DrawCacheImage[Source];
|
|
}
|
|
|
|
// Refreshes the character if not all images are loaded and draw the character canvas on the main game screen
|
|
function DrawCharacter(C, X, Y, Zoom) {
|
|
|
|
// Make sure we have a character
|
|
if (C != null)
|
|
if ((C.ID == 0) || (Player.Effect.indexOf("BlindHeavy") < 0)) {
|
|
|
|
// There's 2 different canvas, one blinking and one that doesn't
|
|
var seconds = new Date().getTime();
|
|
var Canvas = (Math.round(seconds / 400) % C.BlinkFactor == 0) ? C.CanvasBlink : C.Canvas;
|
|
|
|
// If we must dark the Canvas characters
|
|
if ((C.ID != 0) && Player.IsBlind()) {
|
|
var CanvasH = document.createElement("canvas");
|
|
CanvasH.width = Canvas.width;
|
|
CanvasH.height = Canvas.height;
|
|
CanvasH.getContext('2d').drawImage(Canvas, 0, 0);
|
|
var imageData = CanvasH.getContext('2d').getImageData(0, 0, CanvasH.width, CanvasH.height);
|
|
var pixels = imageData.data;
|
|
var DarkFactor = (Player.Effect.indexOf("BlindNormal") >= 0) ? 0.3 : 0.6;
|
|
for(var i = 0; i < pixels.length; i += 4) {
|
|
pixels[i] = pixels[i] * DarkFactor;
|
|
pixels[i+1] = pixels[i+1] * DarkFactor;
|
|
pixels[i+2] = pixels[i+2] * DarkFactor;
|
|
}
|
|
CanvasH.getContext('2d').putImageData(imageData, 0, 0);
|
|
Canvas = CanvasH;
|
|
}
|
|
|
|
// If we must flip the canvas vertically
|
|
if (C.Pose.indexOf("Suspension") >= 0) {
|
|
var CanvasH = document.createElement("canvas");
|
|
var CtxH = CanvasH.getContext("2d");
|
|
CanvasH.width = Canvas.width;
|
|
CanvasH.height = Canvas.height;
|
|
CtxH.scale(1, -1);
|
|
CtxH.translate(0, -Canvas.height);
|
|
CtxH.drawImage(Canvas, 0, 0);
|
|
Canvas = CanvasH;
|
|
}
|
|
|
|
// Draw the character
|
|
if ((Zoom == undefined) || (Zoom == 1))
|
|
DrawCanvas(Canvas, X, Y - C.HeightModifier);
|
|
else
|
|
DrawCanvasZoom(Canvas, X, Y - (C.HeightModifier * Zoom), Zoom);
|
|
|
|
// Draws the character focus zones if we need too
|
|
if ((C.FocusGroup != null) && (C.FocusGroup.Zone != null))
|
|
for(var Z = 0; Z < C.FocusGroup.Zone.length; Z++)
|
|
if (C.Pose.indexOf("Suspension") >= 0)
|
|
DrawEmptyRect(C.FocusGroup.Zone[Z][0] + X, 1000 - (C.FocusGroup.Zone[Z][1] + Y + C.FocusGroup.Zone[Z][3]) - C.HeightModifier, C.FocusGroup.Zone[Z][2], C.FocusGroup.Zone[Z][3], "cyan");
|
|
else
|
|
DrawEmptyRect(C.FocusGroup.Zone[Z][0] + X, C.FocusGroup.Zone[Z][1] + Y - C.HeightModifier, C.FocusGroup.Zone[Z][2], C.FocusGroup.Zone[Z][3], "cyan");
|
|
|
|
// Draw the character name below herself
|
|
if ((C.Name != "") && (CurrentModule == "Room"))
|
|
if (!Player.IsBlind())
|
|
DrawText(C.Name, X + 255, Y + 980, "White", "Black");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Draw a zoomed image from a source to a specific canvas
|
|
function DrawImageZoomCanvas(Source, Canvas, SX, SY, SWidth, SHeight, X, Y, Width, Height) {
|
|
Canvas.drawImage(DrawGetImage(Source), SX, SY, Math.round(SWidth), Math.round(SHeight), X, Y, Width, Height);
|
|
}
|
|
|
|
function DrawImageResize(Source, X, Y, Width, Height) {
|
|
var img = DrawGetImage(Source);
|
|
MainCanvas.drawImage(img, 0, 0, img.width, img.height, X, Y, Width, Height);
|
|
}
|
|
|
|
// Draw a zoomed image from a source to a specific canvas
|
|
function DrawImageCanvas(Source, Canvas, X, Y) {
|
|
Canvas.drawImage(DrawGetImage(Source), X, Y);
|
|
}
|
|
|
|
// Draw a specific canvas on the main canvas
|
|
function DrawCanvas(Canvas, X, Y) {
|
|
MainCanvas.drawImage(Canvas, X, Y);
|
|
}
|
|
|
|
// Draw a specific canvas with a zoom on the main canvas
|
|
function DrawCanvasZoom(Canvas, X, Y, Zoom) {
|
|
MainCanvas.drawImage(Canvas, 0, 0, Canvas.width, Canvas.height, X, Y, Canvas.width * Zoom, Canvas.height * Zoom);
|
|
}
|
|
|
|
// Draw a zoomed image from a source to the canvas and mirrors it from left to right
|
|
function DrawImageZoomMirror(Source, SX, SY, SWidth, SHeight, X, Y, Width, Height) {
|
|
MainCanvas.save();
|
|
MainCanvas.scale(-1, 1);
|
|
MainCanvas.drawImage(DrawGetImage(Source), X * -1, Y, Width * -1, Height);
|
|
MainCanvas.restore();
|
|
}
|
|
|
|
// Draw an image from a source to the canvas
|
|
function DrawImage(Source, X, Y) {
|
|
MainCanvas.drawImage(DrawGetImage(Source), X, Y);
|
|
}
|
|
|
|
// Draw an image from a source to the canvas
|
|
function DrawImageCanvasColorize(Source, Canvas, X, Y, Zoom, HexColor, FullAlpha) {
|
|
|
|
// Make sure that the starting image is loaded
|
|
var Img = new Image();
|
|
Img.src = DrawGetImage(Source).src;
|
|
if ((Img != null) && (Img.width > 0)) {
|
|
|
|
// Prepares a canvas to draw the colorized image
|
|
ColorCanvas.width = Img.width;
|
|
ColorCanvas.height = Img.height;
|
|
var ctx = ColorCanvas.getContext("2d");
|
|
ctx.drawImage(Img,0,0);
|
|
var imageData = ctx.getImageData(0,0,ColorCanvas.width,ColorCanvas.height);
|
|
var data = imageData.data;
|
|
|
|
// Get the RGB color used to transform
|
|
var rgbColor = DrawHexToRGB(HexColor);
|
|
var trans;
|
|
|
|
// We transform each non transparent pixel based on the RGG value
|
|
if (FullAlpha) {
|
|
for(var p = 0, len = data.length; p < len; p+=4) {
|
|
if (data[p+3] == 0)
|
|
continue;
|
|
trans = ((data[p] + data[p + 1] + data[p + 2]) / 383);
|
|
data[p + 0] = rgbColor.r * trans;
|
|
data[p + 1] = rgbColor.g * trans;
|
|
data[p + 2] = rgbColor.b * trans;
|
|
}
|
|
} else {
|
|
for(var p = 0, len = data.length; p < len; p+=4) {
|
|
trans = ((data[p] + data[p + 1] + data[p + 2]) / 383);
|
|
if ((data[p+3] == 0) || (trans < 0.8) || (trans > 1.2))
|
|
continue;
|
|
data[p + 0] = rgbColor.r * trans;
|
|
data[p + 1] = rgbColor.g * trans;
|
|
data[p + 2] = rgbColor.b * trans;
|
|
}
|
|
}
|
|
|
|
// Replace the source image with the modified canvas
|
|
ctx.putImageData(imageData, 0, 0);
|
|
Canvas.drawImage(ctx.canvas, 0, 0, Img.width, Img.height, X, Y, Img.width * Zoom, Img.height * Zoom);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Draw an image from a source to the canvas
|
|
function DrawImageMirror(Source, X, Y) {
|
|
MainCanvas.save();
|
|
MainCanvas.scale(-1, 1);
|
|
MainCanvas.drawImage(DrawGetImage(Source), X * -1, Y);
|
|
MainCanvas.restore();
|
|
}
|
|
|
|
// Draw a word wrapped text in a rectangle
|
|
function DrawTextWrap(Text, X, Y, Width, Height, ForeColor, BackColor) {
|
|
|
|
// Draw the rectangle if we need too
|
|
if (BackColor != null) {
|
|
MainCanvas.beginPath();
|
|
MainCanvas.rect(X, Y, Width, Height);
|
|
MainCanvas.fillStyle = BackColor;
|
|
MainCanvas.fillRect(X, Y, Width, Height);
|
|
MainCanvas.fill();
|
|
MainCanvas.lineWidth = '2';
|
|
MainCanvas.strokeStyle = ForeColor;
|
|
MainCanvas.stroke();
|
|
MainCanvas.closePath();
|
|
}
|
|
|
|
// Split the text if it wouldn't fit in the rectangle
|
|
MainCanvas.fillStyle = ForeColor;
|
|
if (MainCanvas.measureText(Text).width > Width) {
|
|
var words = Text.split(' ');
|
|
var line = '';
|
|
Y += 46;
|
|
for(var n = 0; n < words.length; n++) {
|
|
var testLine = line + words[n] + ' ';
|
|
var metrics = MainCanvas.measureText(testLine);
|
|
var testWidth = metrics.width;
|
|
if (testWidth > Width && n > 0) {
|
|
MainCanvas.fillText(line, X + Width / 2, Y);
|
|
line = words[n] + ' ';
|
|
Y += 46;
|
|
}
|
|
else {
|
|
line = testLine;
|
|
}
|
|
}
|
|
MainCanvas.fillText(line, X + Width / 2, Y);
|
|
} else MainCanvas.fillText(Text, X + Width / 2, Y + Height / 2);
|
|
|
|
}
|
|
|
|
// Draw a text that will fit on the specified width
|
|
function DrawTextFit(Text, X, Y, Width, Color) {
|
|
|
|
for (var S = 36; S >= 10; S = S - 2) {
|
|
MainCanvas.font = S.toString() + "px Arial";
|
|
var metrics = MainCanvas.measureText(Text);
|
|
if (metrics.width <= Width)
|
|
break;
|
|
}
|
|
MainCanvas.fillStyle = Color;
|
|
MainCanvas.fillText(Text, X, Y);
|
|
MainCanvas.font = "36px Arial";
|
|
}
|
|
|
|
// Draw a text in the canvas
|
|
function DrawText(Text, X, Y, Color, BackColor) {
|
|
|
|
// Draw a back color relief text if needed
|
|
if ((BackColor != null) && (BackColor != "")) {
|
|
MainCanvas.fillStyle = BackColor;
|
|
MainCanvas.fillText(Text, X + 1, Y + 1);
|
|
}
|
|
|
|
// Split the text on two lines if there's a |
|
|
MainCanvas.fillStyle = Color;
|
|
MainCanvas.fillText(Text, X, Y);
|
|
|
|
}
|
|
|
|
// Draw a button
|
|
function DrawButton(Left, Top, Width, Height, Label, Color, Image) {
|
|
|
|
// Draw the button rectangle (makes the background color cyan if the mouse is over it)
|
|
MainCanvas.beginPath();
|
|
MainCanvas.rect(Left, Top, Width, Height);
|
|
MainCanvas.fillStyle = ((MouseX >= Left) && (MouseX <= Left + Width) && (MouseY >= Top) && (MouseY <= Top + Height) && !CommonIsMobile) ? "Cyan" : Color;
|
|
MainCanvas.fillRect(Left, Top, Width, Height);
|
|
MainCanvas.fill();
|
|
MainCanvas.lineWidth = '2';
|
|
MainCanvas.strokeStyle = 'black';
|
|
MainCanvas.stroke();
|
|
MainCanvas.closePath();
|
|
|
|
// Draw the text
|
|
DrawText(Label, Left + Width / 2, Top + Height / 2, "black");
|
|
if ((Image != null) && (Image != "")) DrawImage(Image, Left + 2, Top + 2);
|
|
|
|
}
|
|
|
|
// Draw a basic empty rectangle
|
|
function DrawEmptyRect(Left, Top, Width, Height, Color) {
|
|
MainCanvas.beginPath();
|
|
MainCanvas.rect(Left, Top, Width, Height);
|
|
MainCanvas.lineWidth = '3';
|
|
MainCanvas.strokeStyle = Color;
|
|
MainCanvas.stroke();
|
|
MainCanvas.closePath();
|
|
}
|
|
|
|
// Draw a basic rectangle
|
|
function DrawRect(Left, Top, Width, Height, Color) {
|
|
MainCanvas.beginPath();
|
|
MainCanvas.rect(Left, Top, Width, Height);
|
|
MainCanvas.fillStyle = Color;
|
|
MainCanvas.fillRect(Left, Top, Width, Height);
|
|
MainCanvas.fill();
|
|
MainCanvas.closePath();
|
|
}
|
|
|
|
// Draw a basic circle
|
|
function DrawCircle(CenterX, CenterY, Radius, LineWidth, LineColor) {
|
|
MainCanvas.beginPath();
|
|
MainCanvas.arc(CenterX, CenterY, Radius, 0, 2 * Math.PI, false);
|
|
MainCanvas.lineWidth = LineWidth;
|
|
MainCanvas.strokeStyle = LineColor;
|
|
MainCanvas.stroke();
|
|
}
|
|
|
|
// Draw a progress bar
|
|
function DrawProgressBar(X, Y, W, H, Progress) {
|
|
DrawRect(X, Y, W, H, "white");
|
|
DrawRect(X + 2, Y + 2, Math.floor((W - 4) * Progress / 100), H - 4, "#66FF66");
|
|
DrawRect(Math.floor(X + 2 + (W - 4) * Progress / 100), Y + 2, Math.floor((W - 4) * (100 - Progress) / 100), H - 4, "red");
|
|
}
|
|
|
|
// Makes sure the screen is at the proper size
|
|
function DrawProcess() {
|
|
|
|
// Gets the Width and Height differently on mobile and regular browsers
|
|
var W = (CommonIsMobile) ? document.documentElement.clientWidth : window.innerWidth;
|
|
var H = (CommonIsMobile) ? document.documentElement.clientHeight : window.innerHeight;
|
|
|
|
// If we need to resize, we keep the 2x1 ratio
|
|
if ((DrawScreenWidth != W) || (DrawScreenHeight != H)) {
|
|
DrawScreenWidth = W;
|
|
DrawScreenHeight = H;
|
|
if (W <= H * 2) {
|
|
MainCanvas.width = W;
|
|
MainCanvas.height = MainCanvas.width / 2;
|
|
MainCanvas.canvas.style.width = "100%";
|
|
MainCanvas.canvas.style.height = "";
|
|
} else {
|
|
MainCanvas.height = H;
|
|
MainCanvas.width = MainCanvas.height * 2;
|
|
MainCanvas.canvas.style.width = "";
|
|
MainCanvas.canvas.style.height = "100%";
|
|
}
|
|
}
|
|
|
|
// Gets the current screen background and draw it, a darker version in character dialog mode
|
|
var B = window[CurrentScreen + "Background"];
|
|
if ((B != null) && (B != ""))
|
|
if (((Player.Effect.indexOf("BlindNormal") >= 0) || (Player.Effect.indexOf("BlindHeavy") >= 0)) && (CurrentModule != "Character"))
|
|
DrawRect(0, 0, 2000, 1000, "Black");
|
|
else
|
|
DrawImage("Backgrounds/" + B + ((((CurrentCharacter != null) || ShopStarted || (Player.Effect.indexOf("BlindLight") >= 0)) && (CurrentModule != "Character")) ? "Dark" : "") + ".jpg", 0, 0);
|
|
|
|
// Draws the dialog screen or current screen if there's no loaded character
|
|
if (CurrentCharacter != null) DialogDraw();
|
|
else CommonDynamicFunction(CurrentScreen + "Run()");
|
|
|
|
}
|
|
|
|
// Draw the item preview box
|
|
function DrawItemPreview(X, Y, Item) {
|
|
DrawRect(X, Y, 225, 275, "white");
|
|
DrawImageResize("Assets/" + Item.Asset.Group.Family + "/" + Item.Asset.Group.Name + "/Preview/" + Item.Asset.Name + ".png", X + 2, Y + 2, 221, 221);
|
|
DrawTextFit(Item.Asset.Description, X + 110, Y + 250, 221, "black");
|
|
}
|
|
|
|
// Draw a regular HTML element at a specific position
|
|
function DrawElementPosition(ElementID, X, Y, W) {
|
|
|
|
// Different positions based on the width/height ratio
|
|
if (DrawScreenWidth <= DrawScreenHeight * 2) {
|
|
Font = (DrawScreenWidth / 50);
|
|
Height = Font * 1.15;
|
|
Left = ((X - (W / 2)) * DrawScreenWidth / 2000);
|
|
Width = (W * DrawScreenWidth / 2000) - 18;
|
|
Top = (Y * DrawScreenWidth / 2000) + ((DrawScreenHeight * 2 - DrawScreenWidth) / 4) - (Height / 2);
|
|
} else {
|
|
Font = (DrawScreenHeight / 25);
|
|
Height = Font * 1.15;
|
|
Left = ((X - (W / 2)) * DrawScreenHeight / 1000) + (DrawScreenWidth - DrawScreenHeight * 2) / 2;
|
|
Width = (W * DrawScreenHeight / 1000) - 18;
|
|
Top = (Y * DrawScreenHeight / 1000) - (Height / 2);
|
|
}
|
|
|
|
// Sets the element style
|
|
document.getElementById(ElementID).setAttribute("style", "font-size:" + Font + "px; font-family:Arial; position:absolute; padding-left:10px; left:" + Left + "px; top:" + Top + "px; width:" + Width + "px; height:" + Height + "px;");
|
|
|
|
} |