start working on touch, for web

This commit is contained in:
RandomityGuy 2022-08-03 19:51:50 +05:30
parent d6c599acbd
commit 3af3ef8fee
8 changed files with 245 additions and 6 deletions

View file

@ -106,7 +106,7 @@ class CameraController extends Object {
#end
}
function orbit(mouseX:Float, mouseY:Float) {
public function orbit(mouseX:Float, mouseY:Float) {
var scaleFactor = 1.0;
#if js
scaleFactor = 1 / js.Browser.window.devicePixelRatio;

52
src/JSPlatform.hx Normal file
View file

@ -0,0 +1,52 @@
package src;
import src.Util;
class JSPlatform {
#if js
public static function initFullscreenEnforcer() {
var dislikesFullscreen = false;
var fullscreenEnforcer = js.Browser.document.querySelector("#fullscreen-enforcer");
fullscreenEnforcer.addEventListener('click', () -> {
js.Browser.document.documentElement.requestFullscreen();
});
var enterFullscreenButton = js.Browser.document.querySelector("#enter-fullscreen");
enterFullscreenButton.addEventListener('click', () -> {
js.Browser.document.documentElement.requestFullscreen();
dislikesFullscreen = false;
});
var fullscreenButtonVisibility = true;
var setEnterFullscreenButtonVisibility = (state:Bool) -> {
fullscreenButtonVisibility = state;
if (state && Util.isTouchDevice() && !Util.isSafari() && !Util.isInFullscreen()) {
enterFullscreenButton.classList.remove('hidden');
} else {
enterFullscreenButton.classList.add('hidden');
}
}
var lastImmunityTime = Math.NEGATIVE_INFINITY;
js.Browser.window.setInterval(() -> {
if (js.Browser.document.activeElement != null) {
if (Util.isTouchDevice() && !Util.isSafari()) {
if (Util.isInFullscreen()) {
// They're in fullscreen, hide the overlay
fullscreenEnforcer.classList.add('hidden');
} else if (!dislikesFullscreen && js.Browser.window.performance.now() - lastImmunityTime > 666) {
// They're not in fullscreen, show the overlay
fullscreenEnforcer.classList.remove('hidden');
}
}
setEnterFullscreenButtonVisibility(fullscreenButtonVisibility);
}
}, 250);
}
#end
}

View file

@ -1,5 +1,6 @@
package;
import src.Util;
import src.ResourceLoader;
#if js
import fs.ManifestFileSystem;
@ -29,7 +30,7 @@ class Main extends hxd.App {
hl.UI.closeConsole();
#end
#if js
var zoomRatio = js.Browser.window.innerHeight * js.Browser.window.devicePixelRatio / 768; // js.Browser.window.devicePixelRatio;
var zoomRatio = Util.isTouchDevice() ? js.Browser.window.screen.height * js.Browser.window.devicePixelRatio / 600 : js.Browser.window.devicePixelRatio; // js.Browser.window.devicePixelRatio;
s2d.scaleMode = Zoom(zoomRatio);
#end
ResourceLoader.init(s2d, () -> {

View file

@ -1,5 +1,6 @@
package src;
import touch.TouchInput;
import src.ResourceLoader;
import src.AudioManager;
import gui.PlayMissionGui;
@ -10,7 +11,9 @@ import h3d.Vector;
import gui.GuiControl.MouseState;
import hxd.Window;
import src.MarbleWorld;
import src.JSPlatform;
import gui.Canvas;
import src.Util;
@:publicFields
class MarbleGame {
@ -27,14 +30,20 @@ class MarbleGame {
var exitGameDlg:ExitGameDlg;
var touchInput:TouchInput;
public function new(scene2d:h2d.Scene, scene:h3d.scene.Scene) {
canvas = new Canvas(scene2d, cast this);
this.scene = scene;
this.scene2d = scene2d;
MarbleGame.instance = this;
this.touchInput = new TouchInput();
#if js
// Pause shit
if (Util.isTouchDevice())
this.touchInput.registerTouchInput();
js.Browser.document.addEventListener('pointerlockchange', () -> {
if (!paused && world != null) {
if (world.finishTime == null && world._ready) {
@ -115,6 +124,7 @@ class MarbleGame {
e.returnValue = '';
}
});
JSPlatform.initFullscreenEnforcer();
#end
}
@ -124,6 +134,7 @@ class MarbleGame {
world = null;
return;
}
touchInput.update();
if (!paused) {
world.update(dt);
}

View file

@ -1,5 +1,6 @@
package src;
import haxe.ds.Option;
import gui.Canvas;
import src.AudioManager;
import hxd.Key;
@ -11,6 +12,7 @@ import sys.io.File;
#end
import src.ResourceLoader;
import haxe.Json;
import src.Util;
typedef Score = {
var name:String;
@ -90,6 +92,8 @@ class Settings {
public static var zoomRatio = 1.0;
public static var isTouch:Option<Bool> = Option.None;
public static function applySettings() {
Window.getInstance().resize(optionsSettings.screenWidth, optionsSettings.screenHeight);
Window.getInstance().displayMode = optionsSettings.isFullScreen ? FullscreenResize : Windowed;
@ -205,8 +209,7 @@ class Settings {
var wnd = Window.getInstance();
var zoomRatio = 1.0;
#if js
zoomRatio = js.Browser.window.innerHeight * js.Browser.window.devicePixelRatio / 600; // 768 / js.Browser.window.innerHeight; // js.Browser.window.innerHeight * js.Browser.window.devicePixelRatio / 768;
trace("zoomRatio: " + zoomRatio);
var zoomRatio = Util.isTouchDevice() ? js.Browser.window.screen.height * js.Browser.window.devicePixelRatio / 600 : js.Browser.window.devicePixelRatio; // 768 / js.Browser.window.innerHeight; // js.Browser.window.innerHeight * js.Browser.window.devicePixelRatio / 768;
Settings.zoomRatio = zoomRatio;
#end
#if hl
@ -214,8 +217,12 @@ class Settings {
Settings.optionsSettings.screenHeight = cast wnd.height / zoomRatio;
#end
#if js
Settings.optionsSettings.screenWidth = cast js.Browser.window.innerWidth * js.Browser.window.devicePixelRatio; // 1024; // cast(js.Browser.window.innerWidth / js.Browser.window.innerHeight) * 768; // cast js.Browser.window.innerWidth * js.Browser.window.devicePixelRatio * 0.5;
Settings.optionsSettings.screenHeight = cast js.Browser.window.innerHeight * js.Browser.window.devicePixelRatio; // 768; // cast js.Browser.window.innerHeight * js.Browser.window.devicePixelRatio * 0.5;
Settings.optionsSettings.screenWidth = cast js.Browser.window.screen.width * js.Browser.window.devicePixelRatio; // 1024; // cast(js.Browser.window.innerWidth / js.Browser.window.innerHeight) * 768; // cast js.Browser.window.innerWidth * js.Browser.window.devicePixelRatio * 0.5;
Settings.optionsSettings.screenHeight = cast js.Browser.window.screen.height * js.Browser.window.devicePixelRatio; // 768; // cast js.Browser.window.innerHeight * js.Browser.window.devicePixelRatio * 0.5;
var canvasElement = js.Browser.document.getElementById("webgl");
canvasElement.style.width = "100%";
canvasElement.style.height = "100%";
#end
MarbleGame.canvas.scene2d.scaleMode = Zoom(zoomRatio);

View file

@ -6,6 +6,7 @@ import h2d.Tile;
import h3d.mat.Texture;
import hxd.BitmapData;
import h3d.Vector;
import src.Settings;
class Util {
public static function adjustedMod(a:Float, n:Float) {
@ -316,4 +317,50 @@ class Util {
v.set(vresult_0, vresult_1, vresult_2);
}
public static function isTouchDevice() {
#if js
switch (Settings.isTouch) {
case None:
Settings.isTouch = Some(js.lib.Object.keys(js.Browser.window).contains('ontouchstart'));
return js.lib.Object.keys(js.Browser.window).contains('ontouchstart');
case Some(val):
return val;
}
// Let's see if this suffices for now actually (this doesn't match my touchscreen laptop)
#end
#if hl
switch (Settings.isTouch) {
case None:
Settings.isTouch = Some(false);
return false;
case Some(val):
return val;
}
return false;
#end
}
public static function isSafari() {
#if js
var reg = ~/^((?!chrome|android).)*safari/;
return reg.match(js.Browser.navigator.userAgent);
#end
#if hl
return false;
#end
}
public static function isInFullscreen() {
#if js
return (js.Browser.window.innerHeight == js.Browser.window.screen.height
|| (js.Browser.window.screen.orientation.type == js.html.OrientationType.PORTRAIT_PRIMARY
|| js.Browser.window.screen.orientation.type == js.html.OrientationType.PORTRAIT_SECONDARY)
&& js.Browser.window.innerHeight == js.Browser.window.screen.width)
|| js.Browser.document.fullscreenElement != null;
#end
#if hl
return Settings.optionsSettings.isFullScreen;
#end
}
}

39
src/touch/CameraInput.hx Normal file
View file

@ -0,0 +1,39 @@
package touch;
import src.MarbleGame;
import src.Settings;
import touch.TouchInput.TouchEventState;
class CameraInput {
var identifier:Int = -1;
var doing = false;
public function new() {}
public function update(touchState:TouchEventState) {
if (!doing) {
// Check for touches on the right half of the screen
for (touch in touchState.changedTouches) {
if (touch.position.x >= Settings.optionsSettings.screenWidth / 2 && touch.state == Pressed) {
identifier = touch.identifier;
doing = true;
}
}
} else {
// Get our identifier
for (touch in touchState.changedTouches) {
if (touch.identifier == this.identifier && touch.state == Release) {
doing = false;
return; // lol
}
if (touch.identifier == this.identifier && touch.state == Move) {
MarbleGame.instance.world.marble.camera.orbit(touch.deltaPosition.x, touch.deltaPosition.y);
return;
}
}
// Could not find
doing = false;
}
}
}

82
src/touch/TouchInput.hx Normal file
View file

@ -0,0 +1,82 @@
package touch;
import src.MarbleWorld;
import h3d.Vector;
enum TouchState {
Pressed;
Move;
Release;
}
class Touch {
public var state:TouchState;
public var position:Vector;
public var deltaPosition:Vector;
public var identifier:Int;
public function new(state:TouchState, position:Vector, deltaPos:Vector, id:Int) {
this.state = state;
this.position = position;
this.deltaPosition = deltaPos;
this.identifier = id;
}
}
class TouchEventState {
public var changedTouches:Array<Touch>;
public function new() {
this.changedTouches = [];
}
}
class TouchInput {
public var cameraInput:CameraInput;
public var currentTouchState:TouchEventState;
public var previousTouchState:TouchEventState;
public function new() {
this.cameraInput = new CameraInput();
this.currentTouchState = new TouchEventState();
this.previousTouchState = new TouchEventState();
}
// Registers the callbacks to the native stuff
public function registerTouchInput() {
#if js
var pointercontainer = js.Browser.document.querySelector("#pointercontainer");
pointercontainer.addEventListener('touchstart', (e:js.html.TouchEvent) -> {
for (touch in e.changedTouches) {
var t = new Touch(Pressed, new Vector(touch.clientX, touch.clientY), new Vector(0, 0), touch.identifier);
currentTouchState.changedTouches.push(t);
}
});
pointercontainer.addEventListener('touchmove', (e:js.html.TouchEvent) -> {
for (touch in e.changedTouches) {
var prevt = previousTouchState.changedTouches.filter(x -> x.identifier == touch.identifier);
var prevDelta = new Vector(0, 0);
if (prevt.length != 0) {
prevDelta = new Vector(touch.clientX, touch.clientY).sub(prevt[0].position);
}
var t = new Touch(Move, new Vector(touch.clientX, touch.clientY), prevDelta, touch.identifier);
currentTouchState.changedTouches.push(t);
}
});
pointercontainer.addEventListener('touchend', (e:js.html.TouchEvent) -> {
for (touch in e.changedTouches) {
var t = new Touch(Release, new Vector(touch.clientX, touch.clientY), new Vector(0, 0), touch.identifier);
currentTouchState.changedTouches.push(t);
}
});
#end
}
public function update() {
this.cameraInput.update(currentTouchState);
previousTouchState = currentTouchState;
currentTouchState = new TouchEventState();
}
}