Init
This commit is contained in:
commit
893c226fe4
|
@ -0,0 +1,2 @@
|
||||||
|
.idea
|
||||||
|
test*
|
|
@ -0,0 +1,18 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Mr. Crocs Adventures</title>
|
||||||
|
<style>
|
||||||
|
#canvas {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script type="module" src="js/module.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="canvas"></canvas>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,20 @@
|
||||||
|
import GeometryPoint from "./GeometryPoint.js";
|
||||||
|
|
||||||
|
export default class GeometryCircle
|
||||||
|
{
|
||||||
|
constructor(x, y, radius)
|
||||||
|
{
|
||||||
|
this.position = new GeometryPoint(x, y);
|
||||||
|
this.radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDistanceToCircle(circle)
|
||||||
|
{
|
||||||
|
return this.position.getDistanceToPoint(circle.position);
|
||||||
|
}
|
||||||
|
|
||||||
|
hasIntersectionWithCircle(circle)
|
||||||
|
{
|
||||||
|
return this.getDistanceToCircle(circle) <= this.radius + circle.radius;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
import GeometryPoint from "./GeometryPoint.js";
|
||||||
|
import GeometryStroke from "./GeometryStroke.js";
|
||||||
|
|
||||||
|
export default class GeometryLine
|
||||||
|
{
|
||||||
|
constructor(pointA, pointB)
|
||||||
|
{
|
||||||
|
this.pointA = pointA;
|
||||||
|
this.pointB = pointB;
|
||||||
|
}
|
||||||
|
|
||||||
|
getIntersectionWithLine(line)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
let xa = (line.pointB.x - line.pointA.x) * (this.pointB.x * this.pointA.y - this.pointA.x * this.pointB.y);
|
||||||
|
let xb = (this.pointB.x - this.pointA.x) * (line.pointB.x * line.pointA.y - line.pointA.x * line.pointB.y);
|
||||||
|
let xc = (line.pointB.y - line.pointA.y) * (this.pointB.x - this.pointA.x);
|
||||||
|
let xd = (this.pointB.y - this.pointA.y) * (line.pointB.x - line.pointA.x);
|
||||||
|
|
||||||
|
let x = (xa - xb) / (xc - xd);
|
||||||
|
|
||||||
|
if (isNaN(x)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ya = (this.pointA.y - this.pointB.y) *(line.pointB.x * line.pointA.y - line.pointA.x * line.pointB.y);
|
||||||
|
let yb = (line.pointA.y - line.pointB.y) *(this.pointB.x * this.pointA.y - this.pointA.x * this.pointB.y);
|
||||||
|
let yc = (line.pointB.y - line.pointA.y) * (this.pointB.x - this.pointA.x);
|
||||||
|
let yd = (this.pointB.y - this.pointA.y) * (line.pointB.x - line.pointA.x);
|
||||||
|
|
||||||
|
let y = (ya - yb) / (yc - yd);
|
||||||
|
|
||||||
|
if (isNaN(y)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new GeometryPoint(x, y);
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getStroke()
|
||||||
|
{
|
||||||
|
return new GeometryStroke(this.pointA, this.pointB);
|
||||||
|
}
|
||||||
|
|
||||||
|
draw(context)
|
||||||
|
{
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(this.pointA.x, this.pointA.y);
|
||||||
|
context.lineTo(this.pointB.x, this.pointB.y);
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
export default class GeometryPoint
|
||||||
|
{
|
||||||
|
constructor(x, y)
|
||||||
|
{
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
isEqual(geometryPoint)
|
||||||
|
{
|
||||||
|
return this.x === geometryPoint.x && this.y === geometryPoint.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDistanceToPoint(geometryPoint)
|
||||||
|
{
|
||||||
|
return Math.sqrt(Math.pow(geometryPoint.x - this.x,2) + Math.pow(geometryPoint.y - this.y,2));
|
||||||
|
}
|
||||||
|
|
||||||
|
getAngleToPoint(geometryPoint)
|
||||||
|
{
|
||||||
|
return Math.atan2(this.y - geometryPoint.y, this.x - geometryPoint.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
draw(context)
|
||||||
|
{
|
||||||
|
context.beginPath();
|
||||||
|
context.arc(this.x, this.y, 3, 0, 2 * Math.PI);
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
import GeometryRect from "./GeometryRect.js";
|
||||||
|
|
||||||
|
export default class GeometryPointCollection
|
||||||
|
{
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
this.points = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
addGeometryPoint(geometryPoint)
|
||||||
|
{
|
||||||
|
if (!this.isContainingPoint(geometryPoint)) {
|
||||||
|
this.points.push(geometryPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isContainingPoint(geometryPoint)
|
||||||
|
{
|
||||||
|
for (let p = 0; p < this.points.length; p++) {
|
||||||
|
if (geometryPoint.isEqual(this.points[p])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLength()
|
||||||
|
{
|
||||||
|
return this.points.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPoint(index)
|
||||||
|
{
|
||||||
|
return this.points[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
forEach(callback)
|
||||||
|
{
|
||||||
|
this.points.forEach(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
sort()
|
||||||
|
{
|
||||||
|
this.points.sort(
|
||||||
|
function (a, b) {
|
||||||
|
return a.x > b.x || a.y > b.y;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
getRect()
|
||||||
|
{
|
||||||
|
if (this.getLength() < 2) {
|
||||||
|
console.log('GeometryPointCollection.getRect(): Collection must contain at least 2 points!');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sort();
|
||||||
|
|
||||||
|
let positionTopLeft = this.getPoint(0);
|
||||||
|
let positionBottomRight = this.getPoint(this.getLength() - 1);
|
||||||
|
let width = positionBottomRight.x - positionTopLeft.x;
|
||||||
|
let height = positionBottomRight.y - positionTopLeft.y;
|
||||||
|
|
||||||
|
return new GeometryRect(positionTopLeft.x, positionTopLeft.y, width, height);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,230 @@
|
||||||
|
import GeometryPoint from "./GeometryPoint.js";
|
||||||
|
import GeometryStroke from "./GeometryStroke.js";
|
||||||
|
import GeometryPointCollection from "./GeometryPointCollection.js";
|
||||||
|
|
||||||
|
export default class GeometryRect
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param x: float
|
||||||
|
* @param y: float
|
||||||
|
* @param width: float
|
||||||
|
* @param height: float
|
||||||
|
*/
|
||||||
|
constructor(x, y, width, height)
|
||||||
|
{
|
||||||
|
this.position = new GeometryPoint(x, y);
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if the given point is inside this rect.
|
||||||
|
*
|
||||||
|
* @param geometryPoint
|
||||||
|
* @returns {boolean|boolean}
|
||||||
|
*/
|
||||||
|
isContainingPoint(geometryPoint)
|
||||||
|
{
|
||||||
|
let containsHorizontally = geometryPoint.x >= this.position.x && geometryPoint.x <= this.position.x + this.width;
|
||||||
|
let containsVertically = geometryPoint.y >= this.position.y && geometryPoint.y <= this.position.y + this.height;
|
||||||
|
|
||||||
|
return containsHorizontally && containsVertically;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBorderTop()
|
||||||
|
{
|
||||||
|
return new GeometryStroke(
|
||||||
|
new GeometryPoint(this.position.x, this.position.y),
|
||||||
|
new GeometryPoint(this.position.x + this.width, this.position.y)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getBorderLeft()
|
||||||
|
{
|
||||||
|
return new GeometryStroke(
|
||||||
|
new GeometryPoint(this.position.x, this.position.y),
|
||||||
|
new GeometryPoint(this.position.x, this.position.y + this.height)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getBorderRight()
|
||||||
|
{
|
||||||
|
return new GeometryStroke(
|
||||||
|
new GeometryPoint(this.position.x + this.width, this.position.y),
|
||||||
|
new GeometryPoint(this.position.x + this.width, this.position.y + this.height)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getBorderBottom() {
|
||||||
|
return new GeometryStroke(
|
||||||
|
new GeometryPoint(this.position.x, this.position.y + this.height),
|
||||||
|
new GeometryPoint(this.position.x + this.width, this.position.y + this.height)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all intersection points between this rect and a line.
|
||||||
|
*
|
||||||
|
* @param geometryLine
|
||||||
|
* @returns {GeometryPointCollection}
|
||||||
|
*/
|
||||||
|
getBorderIntersectionsWithLine(geometryLine)
|
||||||
|
{
|
||||||
|
let borders = [
|
||||||
|
this.getBorderTop(),
|
||||||
|
this.getBorderLeft(),
|
||||||
|
this.getBorderRight(),
|
||||||
|
this.getBorderBottom()
|
||||||
|
];
|
||||||
|
|
||||||
|
let intersections = new GeometryPointCollection();
|
||||||
|
|
||||||
|
borders.forEach(
|
||||||
|
(border) => {
|
||||||
|
let intersection = border.getIntersectionWithLine(geometryLine);
|
||||||
|
|
||||||
|
if (intersection !== null && this.isContainingPoint(intersection)) {
|
||||||
|
intersections.addGeometryPoint(intersection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return intersections;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBorderIntersectionsWithStroke(stroke)
|
||||||
|
{
|
||||||
|
let borders = [
|
||||||
|
this.getBorderTop(),
|
||||||
|
this.getBorderLeft(),
|
||||||
|
this.getBorderRight(),
|
||||||
|
this.getBorderBottom()
|
||||||
|
];
|
||||||
|
|
||||||
|
let intersections = new GeometryPointCollection();
|
||||||
|
|
||||||
|
borders.forEach(
|
||||||
|
(border) => {
|
||||||
|
let intersection = border.getIntersectionWithStroke(stroke);
|
||||||
|
|
||||||
|
if (intersection !== null && this.isContainingPoint(intersection)) {
|
||||||
|
intersections.addGeometryPoint(intersection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return intersections;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all intersections between this and another rect as point collection.
|
||||||
|
*
|
||||||
|
* @param rect GeometryRect
|
||||||
|
* @returns {GeometryPointCollection}
|
||||||
|
*/
|
||||||
|
getBorderIntersectonsWithRect(rect)
|
||||||
|
{
|
||||||
|
let intersections = new GeometryPointCollection();
|
||||||
|
|
||||||
|
let strokes = [
|
||||||
|
rect.getBorderTop(),
|
||||||
|
rect.getBorderLeft(),
|
||||||
|
rect.getBorderRight(),
|
||||||
|
rect.getBorderBottom(),
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
strokes.forEach(
|
||||||
|
(stroke) => {
|
||||||
|
this.getBorderIntersectionsWithStroke(stroke).forEach(
|
||||||
|
(point) => {
|
||||||
|
intersections.addGeometryPoint(point);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return intersections;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the four points that define the edges of this rect.
|
||||||
|
*
|
||||||
|
* @returns {GeometryPointCollection}
|
||||||
|
*/
|
||||||
|
getRectanglePoints()
|
||||||
|
{
|
||||||
|
let collection = new GeometryPointCollection();
|
||||||
|
|
||||||
|
collection.addGeometryPoint(this.position);
|
||||||
|
collection.addGeometryPoint(new GeometryPoint(this.position.x + this.width, this.position.y));
|
||||||
|
collection.addGeometryPoint(new GeometryPoint(this.position.x, this.position.y + this.height));
|
||||||
|
collection.addGeometryPoint(new GeometryPoint(this.position.x + this.width, this.position.y + this.height));
|
||||||
|
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the intersection area between this and another rect as new rect or null.
|
||||||
|
*
|
||||||
|
* @param rect GeometryRect
|
||||||
|
* @returns {null|GeometryRect}
|
||||||
|
*/
|
||||||
|
getRectIntersection(rect)
|
||||||
|
{
|
||||||
|
let intersectionPoints = new GeometryPointCollection();
|
||||||
|
|
||||||
|
this.getRectanglePoints().forEach(
|
||||||
|
(point) => {
|
||||||
|
if (rect.isContainingPoint(point)) {
|
||||||
|
intersectionPoints.addGeometryPoint(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (intersectionPoints.getLength() >= 4) {
|
||||||
|
return intersectionPoints.getRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.getRectanglePoints().forEach(
|
||||||
|
(point) => {
|
||||||
|
if (this.isContainingPoint(point)) {
|
||||||
|
intersectionPoints.addGeometryPoint(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (intersectionPoints.getLength() >= 4) {
|
||||||
|
return intersectionPoints.getRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getBorderIntersectonsWithRect(rect).forEach(
|
||||||
|
(point) => {
|
||||||
|
intersectionPoints.addGeometryPoint(point);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (intersectionPoints.getLength() >= 2) {
|
||||||
|
return intersectionPoints.getRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visualizes the rect.
|
||||||
|
*
|
||||||
|
* @param context Context
|
||||||
|
* @param color string
|
||||||
|
*/
|
||||||
|
draw(context, color = 'red')
|
||||||
|
{
|
||||||
|
context.fillStyle = color;
|
||||||
|
context.fillRect(this.position.x, this.position.y, this.width, this.height);
|
||||||
|
this.getBorderTop().draw(context);
|
||||||
|
this.getBorderLeft().draw(context);
|
||||||
|
this.getBorderRight().draw(context);
|
||||||
|
this.getBorderBottom().draw(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
import GeometryLine from "./GeometryLine.js";
|
||||||
|
import GeometryRect from "./GeometryRect.js";
|
||||||
|
|
||||||
|
export default class GeometryStroke extends GeometryLine
|
||||||
|
{
|
||||||
|
getIntersectionWithLine(line) {
|
||||||
|
let intersection = super.getIntersectionWithLine(line);
|
||||||
|
|
||||||
|
if (
|
||||||
|
intersection === null ||
|
||||||
|
!this.getRect().isContainingPoint(intersection)
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return intersection;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLine()
|
||||||
|
{
|
||||||
|
return new GeometryLine(this.pointA, this.pointB);
|
||||||
|
}
|
||||||
|
|
||||||
|
getIntersectionWithStroke(stroke)
|
||||||
|
{
|
||||||
|
let intersection = super.getIntersectionWithLine(stroke);
|
||||||
|
|
||||||
|
if (
|
||||||
|
intersection === null ||
|
||||||
|
!this.getRect().isContainingPoint(intersection) ||
|
||||||
|
!stroke.getRect().isContainingPoint(intersection)
|
||||||
|
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return intersection;
|
||||||
|
}
|
||||||
|
|
||||||
|
getRect()
|
||||||
|
{
|
||||||
|
let x = Math.min(this.pointA.x, this.pointB.x);
|
||||||
|
let y = Math.min(this.pointA.y, this.pointB.y);
|
||||||
|
|
||||||
|
let width = Math.max(this.pointA.x, this.pointB.x) - x;
|
||||||
|
let height = Math.max(this.pointA.y, this.pointB.y) - y;
|
||||||
|
|
||||||
|
return new GeometryRect(x, y, width, height);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
import RetroSprite from "./retro/RetroSprite.js";
|
||||||
|
|
||||||
|
let image = new Image();
|
||||||
|
image.src = 'graphics/mario.png';
|
||||||
|
|
||||||
|
image.onload = function () {
|
||||||
|
let sprite = new RetroSprite(image, 10);
|
||||||
|
let canvas = document.getElementById('canvas');
|
||||||
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
|
||||||
|
let context = canvas.getContext('2d');
|
||||||
|
|
||||||
|
console.log(context);
|
||||||
|
|
||||||
|
sprite.draw(context);
|
||||||
|
};
|
|
@ -0,0 +1,51 @@
|
||||||
|
import GeometryPoint from "../geometry/GeometryPoint.js";
|
||||||
|
|
||||||
|
export default class RetroSprite
|
||||||
|
{
|
||||||
|
constructor(image, scale = 1)
|
||||||
|
{
|
||||||
|
this.image = image;
|
||||||
|
this.canvas = document.createElement('canvas');
|
||||||
|
this.context = this.canvas.getContext('2d');
|
||||||
|
this.position = new GeometryPoint();
|
||||||
|
this.scale = scale;
|
||||||
|
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
draw(context)
|
||||||
|
{
|
||||||
|
context.drawImage(this.canvas, this.position.x, this.position.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
hasRectCollisionWith(sprite)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
hasCollisionWith(sprite)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render()
|
||||||
|
{
|
||||||
|
let canvasTemp = document.createElement('canvas');
|
||||||
|
let contextTemp = canvasTemp.getContext('2d');
|
||||||
|
contextTemp.drawImage(this.image, 0, 0);
|
||||||
|
|
||||||
|
this.canvas.width = this.image.width * this.scale;
|
||||||
|
this.canvas.height = this.image.height * this.scale;
|
||||||
|
|
||||||
|
this.context.clearRect(0, 0, this.image.width * this.scale, this.image.height * this.scale);
|
||||||
|
|
||||||
|
for (let y = 0; y < this.image.height; y++) {
|
||||||
|
for (let x = 0; x < this.image.width; x++) {
|
||||||
|
let pixel = contextTemp.getImageData(x, y, 1, 1).data;
|
||||||
|
this.context.globalAlpha = pixel[3] / 255;
|
||||||
|
this.context.fillStyle = 'rgb(' + pixel[0] + ',' + pixel[1] + ',' + pixel[2] + ')';
|
||||||
|
this.context.fillRect(x * this.scale, y * this.scale, this.scale, this.scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue