Merge pull request #27 from realModusOperandi/controls

Use triangular hotspots for controls
This commit is contained in:
Andrew Guibert 2018-03-07 16:13:34 -06:00 committed by GitHub
commit 00237e4e63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 115 additions and 25 deletions

View File

@ -1,5 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { GameWebsocket } from '../net/websocket';
import { Triangle } from '../geom/triangle';
import { Point } from '../geom/point';
@Component({
selector: 'app-controls',
@ -16,29 +18,17 @@ export class ControlsComponent implements OnInit {
gameSocket: GameWebsocket;
upTriangle: Triangle;
leftTriangle: Triangle;
downTriangle: Triangle;
rightTriangle: Triangle;
constructor() {}
ngOnInit() {
this.canvas = document.getElementById('dpad-canvas') as HTMLCanvasElement;
this.context = this.canvas.getContext('2d');
this.initCanvas();
this.canvas.addEventListener("touchstart", (evt: TouchEvent) => {
this.touchStarted(evt);
});
this.canvas.addEventListener("mousedown", (evt: MouseEvent) => {
this.mouseDown(evt);
})
this.roundId = sessionStorage.getItem('roundId');
console.log(`Round ID: ${this.roundId}`);
this.serverHost = document.location.hostname;
this.serverPort = '8080';
this.gameSocket = new GameWebsocket(
this.serverHost,
this.serverPort,
this.roundId
);
this.initSocket();
window.onkeydown = (e: KeyboardEvent): any => {
const key = e.keyCode ? e.keyCode : e.which;
@ -53,6 +43,61 @@ export class ControlsComponent implements OnInit {
this.moveRight();
}
};
}
initCanvas() {
this.canvas = document.getElementById('dpad-canvas') as HTMLCanvasElement;
this.context = this.canvas.getContext('2d');
this.canvas.addEventListener('touchstart', (evt: TouchEvent) => {
this.touchStarted(evt);
// Prevent touch events and mouse events from doubling up.
evt.preventDefault();
});
this.canvas.addEventListener('mousedown', (evt: MouseEvent) => {
this.mouseDown(evt);
});
const canvasWidth = this.canvas.width;
const canvasHeight = this.canvas.height;
this.upTriangle = new Triangle(
new Point(0, 0),
new Point(canvasWidth, 0),
new Point(canvasWidth / 2, canvasHeight / 2)
);
this.leftTriangle = new Triangle(
new Point(0, canvasHeight),
new Point(0, 0),
new Point(canvasWidth / 2, canvasHeight / 2)
);
this.downTriangle = new Triangle(
new Point(canvasWidth, canvasHeight),
new Point(0, canvasHeight),
new Point(canvasWidth / 2, canvasHeight / 2)
);
this.rightTriangle = new Triangle(
new Point(canvasWidth, 0),
new Point(canvasWidth, canvasHeight),
new Point(canvasWidth / 2, canvasHeight / 2)
);
}
initSocket() {
this.roundId = sessionStorage.getItem('roundId');
console.log(`Round ID: ${this.roundId}`);
this.serverHost = document.location.hostname;
this.serverPort = '8080';
this.gameSocket = new GameWebsocket(
this.serverHost,
this.serverPort,
this.roundId
);
this.gameSocket.openCallback = (evt: MessageEvent): any => {
this.onConnect(evt);
@ -81,33 +126,36 @@ export class ControlsComponent implements OnInit {
}
touchStarted(evt: TouchEvent) {
console.log(evt);
if (evt.touches.length > 0) {
this.canvasPressed(evt.touches[0].pageX, evt.touches[0].pageY);
}
}
mouseDown(evt: MouseEvent) {
console.log(evt);
this.canvasPressed(evt.pageX, evt.pageY);
}
canvasPressed(x: number, y: number) {
const locationX = ((x - this.canvas.offsetLeft) * this.canvas.width) / this.canvas.offsetWidth;
const locationY = ((y - this.canvas.offsetTop) * this.canvas.height) / this.canvas.offsetHeight;
const locationX = (x - this.canvas.offsetLeft) * this.canvas.width / this.canvas.offsetWidth;
const locationY = (y - this.canvas.offsetTop) * this.canvas.height / this.canvas.offsetHeight;
const location = new Point(locationX, locationY);
if (locationX >= 300 && locationX < 500 && locationY >= 0 && locationY < 300) {
if (this.upTriangle.containsPoint(location)) {
this.moveUp();
}
if (locationX >= 0 && locationX < 300 && locationY >= 300 && locationY < 500) {
if (this.leftTriangle.containsPoint(location)) {
this.moveLeft();
}
if (locationX >= 300 && locationX < 500 && locationY >= 500 && locationY < 800) {
if (this.downTriangle.containsPoint(location)) {
this.moveDown();
}
if (locationX >= 500 && locationX < 800 && locationY >= 300 && locationY < 500) {
if (this.rightTriangle.containsPoint(location)) {
this.moveRight();
}
}

View File

@ -0,0 +1,9 @@
export class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}

View File

@ -0,0 +1,33 @@
import { Point } from "./point";
export class Triangle {
point1: Point;
point2: Point;
point3: Point;
constructor(p1: Point, p2: Point, p3: Point) {
this.point1 = p1;
this.point2 = p2;
this.point3 = p3;
}
// Adapted from https://www.gamedev.net/forums/topic/295943-is-this-a-better-point-in-triangle-test-2d/?do=findComment&comment=2874043
// Should tolerate either vertex winding direction
containsPoint(other: Point) {
const b1 = this.sign(other, this.point1, this.point2) < 0.0;
const b2 = this.sign(other, this.point2, this.point3) < 0.0;
const b3 = this.sign(other, this.point3, this.point1) < 0.0;
return (b1 == b2) && (b2 == b3);
}
sign(p1: Point, p2: Point, p3: Point) {
const term1 = p1.x - p3.x;
const term2 = p2.y - p3.y;
const term3 = p2.x - p3.x;
const term4 = p1.y - p3.y;
return term1 * term2 - term3 * term4;
}
}