some changes

This commit is contained in:
Evert Prants 2022-04-15 14:33:27 +03:00
parent dd9c35d3bd
commit 51a2396d9a
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
10 changed files with 99 additions and 41 deletions

View File

@ -96,7 +96,7 @@ export class Game {
8,
0.5,
8,
this.world.getInterpolatedHeight.bind(this.world),
this.world.getHeight.bind(this.world),
);
const flowerfield = Grass.getInstance().createGrassPatch(
@ -104,7 +104,7 @@ export class Game {
8,
4,
3,
this.world.getInterpolatedHeight.bind(this.world),
this.world.getHeight.bind(this.world),
);
const flowerfield2 = Grass.getInstance().createGrassPatch(
@ -112,7 +112,7 @@ export class Game {
4,
4,
3,
this.world.getInterpolatedHeight.bind(this.world),
this.world.getHeight.bind(this.world),
);
const grass = Grass.getInstance().createInstance(

View File

@ -1,4 +1,5 @@
import { CanvasTexture, LinearFilter, ClampToEdgeWrapping } from 'three';
import { rgbToHex, to1D } from '../../common/convert';
/**
* Draws a rounded rectangle using the current state of the canvas.
@ -172,4 +173,49 @@ export class CanvasUtils {
return { texture, width, height };
}
public readPixelDataRGB(image: HTMLImageElement): number[] {
const array = new Array(image.width * image.height);
const ctx = document.createElement('canvas').getContext('2d');
ctx.canvas.width = image.width;
ctx.canvas.height = image.height;
ctx.drawImage(image, 0, 0, image.width, image.height);
// pixel data
const data = ctx.getImageData(0, 0, image.width, image.height);
for (let x = 0; x < image.width; x++) {
for (let y = 0; y < image.height; y++) {
const index = to1D(x, y, image.width);
array[index] = rgbToHex(
data.data[index * 4],
data.data[index * 4 + 1],
data.data[index * 4 + 2],
);
}
}
return array;
}
public readPixelDataRScaled(
image: HTMLImageElement,
scale: number,
): number[] {
const array = new Array(image.width * image.height);
const ctx = document.createElement('canvas').getContext('2d');
ctx.canvas.width = image.width;
ctx.canvas.height = image.height;
ctx.drawImage(image, 0, 0, image.width, image.height);
// pixel data
const data = ctx.getImageData(0, 0, image.width, image.height);
for (let x = 0; x < image.width; x++) {
for (let y = 0; y < image.height; y++) {
const index = to1D(x, y, image.width);
array[index] = (data.data[index * 4] * scale) / 255;
}
}
return array;
}
}

View File

@ -28,6 +28,10 @@ const nameTagBuilder = new CanvasUtils({
export class PonyEntity {
public velocity = new Vector3(0, 0, 0);
public angularVelocity = new Vector3(0, 0, 0);
public onFloor = true;
public remote = false;
public gravity = -50;
public jumpPower = 16;
public mixer!: AnimationMixer;
public container!: Object3D;
public model!: Object3D;
@ -58,6 +62,14 @@ export class PonyEntity {
}
update(dt: number) {
this.mixer.update(dt);
if (this.remote) {
return;
}
this.velocity.y += this.gravity * dt;
this.container.position.add(this.velocity.clone().multiplyScalar(dt));
this.container.rotation.setFromVector3(
new Vector3(
@ -69,13 +81,18 @@ export class PonyEntity {
// Put pony on the terrain
const terrainFloorHeight =
this.heightSource?.getInterpolatedHeight(
this.heightSource?.getHeight(
this.container.position.x,
this.container.position.z,
) || 0;
this.container.position.y = terrainFloorHeight;
this.mixer.update(dt);
if (this.container.position.y <= terrainFloorHeight) {
this.onFloor = true;
this.velocity.y = 0;
this.container.position.y = terrainFloorHeight;
} else {
this.onFloor = false;
}
}
dispose() {
@ -106,6 +123,10 @@ export class PonyEntity {
}
}
public jump() {
this.velocity.y = 16;
}
public setColor(color: number | string) {
this.material.color = new Color(color);
}

View File

@ -18,6 +18,7 @@ export class PlayerEntity extends PonyEntity {
private _targetFrame: any = null;
private _lastFrame: any = null;
private _chats: ChatBubble[] = [];
public remote = true;
private _p1 = new Vector3();
private _p2 = new Vector3();

View File

@ -97,14 +97,17 @@ export class Player extends PonyEntity {
}
if (vector.y !== 0) {
this.velocity.copy(this._lookVector.clone().multiplyScalar(vector.y * 5));
const directional = this._lookVector
.clone()
.multiplyScalar(vector.y * 2.5);
this.velocity.set(directional.x, this.velocity.y, directional.z);
this.changes.velocity = this.velocity.toArray();
this._wasMoving = true;
this.setWalkAnimationState(1);
} else if (this._wasMoving && !wasExternalForce) {
this._wasMoving = false;
this.velocity.set(0, 0, 0);
this.velocity.set(0, this.velocity.y, 0);
this.changes.velocity = this.velocity.toArray();
this.changes.position = this.container.position.toArray();
this.setWalkAnimationState(0);
@ -133,6 +136,10 @@ export class Player extends PonyEntity {
this._direction.x = 0;
}
if (this.keydownMap[' '] && !this._prevKeydownMap[' '] && this.onFloor) {
this.jump();
}
this.moveCharacter(dt);
super.update(dt);

View File

@ -17,10 +17,10 @@ export class ClientWorld extends WorldManager {
private _shader = new ClientWorldChunkShader(this._worldTextures);
getNormalVector(x: number, y: number): Vector3 {
const heightL = this.getHeight(x - 1, y);
const heightR = this.getHeight(x + 1, y);
const heightD = this.getHeight(x, y - 1);
const heightU = this.getHeight(x, y + 1);
const heightL = this.getPointHeight(x - 1, y);
const heightR = this.getPointHeight(x + 1, y);
const heightD = this.getPointHeight(x, y - 1);
const heightU = this.getPointHeight(x, y + 1);
const normalized = new Vector3(heightL - heightR, 2, heightD - heightU);
normalized.normalize();
return normalized;
@ -75,7 +75,7 @@ export class ClientWorld extends WorldManager {
material,
);
root.getHeight = this.getInterpolatedHeight.bind(this);
root.getHeight = this.getHeight.bind(this);
root.getNormal = this.getNormalVector.bind(this);
root.initialize();

View File

@ -1,9 +1,10 @@
import { ImageLoader } from 'three';
import { to1D } from '../../../common/convert';
import { WorldLoader } from '../../../common/world/WorldLoader';
import { CanvasUtils } from '../canvas-utils';
const loader = new ImageLoader();
const worldPath = '/assets/terrain/region/';
const canvasUtil = new CanvasUtils();
const worldPath = '/assets/terrain/region';
export class ClientWorldLoader implements WorldLoader {
async loadHeightMap(
@ -14,7 +15,7 @@ export class ClientWorldLoader implements WorldLoader {
return new Promise((resolve, reject) => {
loader.load(
`${worldPath}/height-${chunkX}-${chunkY}.png`,
(data) => resolve(ClientWorldLoader.heightFromImage(data, scale)),
(data) => resolve(canvasUtil.readPixelDataRScaled(data, scale)),
undefined,
(err) => {
reject(err);
@ -22,26 +23,4 @@ export class ClientWorldLoader implements WorldLoader {
);
});
}
public static heightFromImage(
image: HTMLImageElement,
scale: number,
): number[] {
const array = new Array(image.width * image.height);
const ctx = document.createElement('canvas').getContext('2d');
ctx.canvas.width = image.width;
ctx.canvas.height = image.height;
ctx.drawImage(image, 0, 0, image.width, image.height);
// pixel data
const data = ctx.getImageData(0, 0, image.width, image.height);
for (let x = 0; x < image.width; x++) {
for (let y = 0; y < image.height; y++) {
const index = to1D(x, y, image.width);
array[index] = (data.data[index * 4] * scale) / 255;
}
}
return array;
}
}

View File

@ -73,7 +73,7 @@ export class QuadtreeNode {
);
if (this._leaf) {
if (abs.distanceTo(camera) < size && this._canSubdivide()) {
if (this._canSubdivide() && abs.distanceTo(camera) < size) {
this._subdivide();
this.root.actionsLeft -= 1;
return;

View File

@ -6,6 +6,10 @@ export function convertHex(hex: number): { r: number; g: number; b: number } {
};
}
export function rgbToHex(r: number, g: number, b: number): number {
return (1 << 24) + (r << 16) + (g << 8) + b;
}
export function hexToString(hex: number): string {
const { r, g, b } = convertHex(hex);
return `#${r.toString(16).padStart(2, '0')}${g

View File

@ -46,7 +46,7 @@ export class WorldManager {
}
}
getHeight(x: number, y: number): number {
getPointHeight(x: number, y: number): number {
const chunkX = Math.floor(x / this.worldChunkSize);
const chunkY = Math.floor(y / this.worldChunkSize);
if (
@ -64,7 +64,7 @@ export class WorldManager {
);
}
getInterpolatedHeight(x: number, y: number): number {
getHeight(x: number, y: number): number {
const chunkX = Math.floor(x / this.worldChunkSize);
const chunkY = Math.floor(y / this.worldChunkSize);
if (