Init
This commit is contained in:
commit
893c226fe4
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.idea
|
||||
test*
|
18
index.html
Normal file
18
index.html
Normal file
@ -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>
|
20
js/geometry/GeometryCircle.js
Normal file
20
js/geometry/GeometryCircle.js
Normal file
@ -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;
|
||||
}
|
||||
}
|
55
js/geometry/GeometryLine.js
Normal file
55
js/geometry/GeometryLine.js
Normal file
@ -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();
|
||||
}
|
||||
}
|
30
js/geometry/GeometryPoint.js
Normal file
30
js/geometry/GeometryPoint.js
Normal file
@ -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();
|
||||
}
|
||||
}
|
68
js/geometry/GeometryPointCollection.js
Normal file
68
js/geometry/GeometryPointCollection.js
Normal file
@ -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);
|
||||
}
|
||||
}
|
230
js/geometry/GeometryRect.js
Normal file
230
js/geometry/GeometryRect.js
Normal file
@ -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);
|
||||
}
|
||||
|
||||
}
|
50
js/geometry/GeometryStroke.js
Normal file
50
js/geometry/GeometryStroke.js
Normal file
@ -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);
|
||||
}
|
||||
}
|
17
js/module.js
Normal file
17
js/module.js
Normal file
@ -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);
|
||||
};
|
51
js/retro/RetroSprite.js
Normal file
51
js/retro/RetroSprite.js
Normal file
@ -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
Block a user