another color for other tanks
This commit is contained in:
parent
4af51b3e51
commit
a0a0762f84
|
@ -12,10 +12,3 @@ internal sealed class GamePixel
|
||||||
EntityType = null;
|
EntityType = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal enum GamePixelEntityType : byte
|
|
||||||
{
|
|
||||||
Wall = 0x0,
|
|
||||||
Tank = 0x1,
|
|
||||||
Bullet = 0x2
|
|
||||||
}
|
|
||||||
|
|
8
TanksServer/Graphics/GamePixelEntityType.cs
Normal file
8
TanksServer/Graphics/GamePixelEntityType.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace TanksServer.Graphics;
|
||||||
|
|
||||||
|
internal enum GamePixelEntityType : byte
|
||||||
|
{
|
||||||
|
Wall = 0x0,
|
||||||
|
Tank = 0x1,
|
||||||
|
Bullet = 0x2
|
||||||
|
}
|
|
@ -8,9 +8,13 @@ const pixelsPerRow = 352;
|
||||||
const pixelsPerCol = 160;
|
const pixelsPerCol = 160;
|
||||||
const observerMessageSize = pixelsPerCol * pixelsPerRow / 8;
|
const observerMessageSize = pixelsPerCol * pixelsPerRow / 8;
|
||||||
|
|
||||||
const isPlayerMask = 1;
|
enum GamePixelEntityType {
|
||||||
|
Wall = 0x0,
|
||||||
|
Tank = 0x1,
|
||||||
|
Bullet = 0x2
|
||||||
|
}
|
||||||
|
|
||||||
function getIndexes(bitIndex: number) {
|
function getPixelDataIndexes(bitIndex: number) {
|
||||||
return {
|
return {
|
||||||
byteIndex: Math.floor(bitIndex / 8),
|
byteIndex: Math.floor(bitIndex / 8),
|
||||||
bitInByteIndex: 7 - bitIndex % 8
|
bitInByteIndex: 7 - bitIndex % 8
|
||||||
|
@ -23,16 +27,31 @@ function normalizeColor(context: CanvasRenderingContext2D, color: string) {
|
||||||
return context.getImageData(0, 0, 1, 1).data;
|
return context.getImageData(0, 0, 1, 1).data;
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawPixelsToCanvas({context, width, height, pixels, additional, foreground, background, playerColor}: {
|
function parseAdditionalDataNibble(nibble: number) {
|
||||||
context: CanvasRenderingContext2D,
|
const isPlayerMask = 1;
|
||||||
width: number,
|
const entityTypeMask = 12;
|
||||||
height: number,
|
|
||||||
pixels: Uint8ClampedArray,
|
return {
|
||||||
additional: Uint8ClampedArray | null,
|
isCurrentPlayer: (nibble & isPlayerMask) != 0,
|
||||||
background: Uint8ClampedArray,
|
entityType: ((nibble & entityTypeMask) >> 2) as GamePixelEntityType,
|
||||||
foreground: Uint8ClampedArray,
|
};
|
||||||
playerColor: Uint8ClampedArray
|
}
|
||||||
}) {
|
|
||||||
|
function drawPixelsToCanvas(
|
||||||
|
{
|
||||||
|
context, width, height, pixels, additional, foreground, background, playerColor, otherTanksColor
|
||||||
|
}: {
|
||||||
|
context: CanvasRenderingContext2D,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
pixels: Uint8ClampedArray,
|
||||||
|
additional: Uint8ClampedArray | null,
|
||||||
|
background: Uint8ClampedArray,
|
||||||
|
foreground: Uint8ClampedArray,
|
||||||
|
playerColor: Uint8ClampedArray,
|
||||||
|
otherTanksColor: Uint8ClampedArray
|
||||||
|
}
|
||||||
|
) {
|
||||||
let additionalDataIndex = 0;
|
let additionalDataIndex = 0;
|
||||||
let additionalDataByte: number | null = null;
|
let additionalDataByte: number | null = null;
|
||||||
const nextPixelColor = (isOn: boolean) => {
|
const nextPixelColor = (isOn: boolean) => {
|
||||||
|
@ -45,15 +64,17 @@ function drawPixelsToCanvas({context, width, height, pixels, additional, foregro
|
||||||
if (additionalDataByte === null) {
|
if (additionalDataByte === null) {
|
||||||
additionalDataByte = additional[additionalDataIndex];
|
additionalDataByte = additional[additionalDataIndex];
|
||||||
additionalDataIndex++;
|
additionalDataIndex++;
|
||||||
info = additionalDataByte;
|
info = parseAdditionalDataNibble(additionalDataByte);
|
||||||
} else {
|
} else {
|
||||||
info = additionalDataByte >> 4;
|
info = parseAdditionalDataNibble(additionalDataByte >> 4);
|
||||||
additionalDataByte = null;
|
additionalDataByte = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((info & isPlayerMask) != 0) {
|
if (info.isCurrentPlayer)
|
||||||
return playerColor;
|
return playerColor;
|
||||||
}
|
|
||||||
|
if (info.entityType == GamePixelEntityType.Tank)
|
||||||
|
return otherTanksColor;
|
||||||
|
|
||||||
return foreground;
|
return foreground;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +85,7 @@ function drawPixelsToCanvas({context, width, height, pixels, additional, foregro
|
||||||
for (let y = 0; y < height; y++) {
|
for (let y = 0; y < height; y++) {
|
||||||
for (let x = 0; x < width; x++) {
|
for (let x = 0; x < width; x++) {
|
||||||
const pixelIndex = y * pixelsPerRow + x;
|
const pixelIndex = y * pixelsPerRow + x;
|
||||||
const {byteIndex, bitInByteIndex} = getIndexes(pixelIndex);
|
const {byteIndex, bitInByteIndex} = getPixelDataIndexes(pixelIndex);
|
||||||
const isOn = (pixels[byteIndex] & (1 << bitInByteIndex)) !== 0;
|
const isOn = (pixels[byteIndex] & (1 << bitInByteIndex)) !== 0;
|
||||||
const color = nextPixelColor(isOn);
|
const color = nextPixelColor(isOn);
|
||||||
|
|
||||||
|
@ -111,10 +132,6 @@ export default function ClientScreen({logout, theme, playerId}: {
|
||||||
if (!drawContext)
|
if (!drawContext)
|
||||||
throw new Error('could not get draw context');
|
throw new Error('could not get draw context');
|
||||||
|
|
||||||
const colorBackground = normalizeColor(drawContext, hslToString(theme.background));
|
|
||||||
const colorPrimary = normalizeColor(drawContext, hslToString(theme.primary));
|
|
||||||
const colorSecondary = normalizeColor(drawContext, hslToString(theme.secondary));
|
|
||||||
|
|
||||||
let pixels = new Uint8ClampedArray(lastMessage.data);
|
let pixels = new Uint8ClampedArray(lastMessage.data);
|
||||||
let additionalData: Uint8ClampedArray | null = null;
|
let additionalData: Uint8ClampedArray | null = null;
|
||||||
if (pixels.length > observerMessageSize) {
|
if (pixels.length > observerMessageSize) {
|
||||||
|
@ -122,17 +139,16 @@ export default function ClientScreen({logout, theme, playerId}: {
|
||||||
pixels = pixels.slice(0, observerMessageSize);
|
pixels = pixels.slice(0, observerMessageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('', {pixelLength: pixels.length, additionalLength: additionalData?.length});
|
|
||||||
|
|
||||||
drawPixelsToCanvas({
|
drawPixelsToCanvas({
|
||||||
context: drawContext,
|
context: drawContext,
|
||||||
width: canvas.width,
|
width: canvas.width,
|
||||||
height: canvas.height,
|
height: canvas.height,
|
||||||
pixels,
|
pixels,
|
||||||
additional: additionalData,
|
additional: additionalData,
|
||||||
background: colorBackground,
|
background: normalizeColor(drawContext, hslToString(theme.background)),
|
||||||
foreground: colorPrimary,
|
foreground: normalizeColor(drawContext, hslToString(theme.primary)),
|
||||||
playerColor: colorSecondary
|
playerColor: normalizeColor(drawContext, hslToString(theme.secondary)),
|
||||||
|
otherTanksColor: normalizeColor(drawContext, hslToString(theme.tertiary))
|
||||||
});
|
});
|
||||||
sendMessage('');
|
sendMessage('');
|
||||||
}, [lastMessage, canvasRef.current, theme]);
|
}, [lastMessage, canvasRef.current, theme]);
|
||||||
|
|
|
@ -4,6 +4,7 @@ export type Theme = {
|
||||||
primary: HSL;
|
primary: HSL;
|
||||||
secondary: HSL;
|
secondary: HSL;
|
||||||
background: HSL;
|
background: HSL;
|
||||||
|
tertiary: HSL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -68,7 +69,10 @@ export function getRandomTheme(): Theme {
|
||||||
const secondary = getRandomHsl(otherColorParams);
|
const secondary = getRandomHsl(otherColorParams);
|
||||||
primary.h = angle(+1 * goldenAngle + primary.h);
|
primary.h = angle(+1 * goldenAngle + primary.h);
|
||||||
|
|
||||||
return {background, primary, secondary};
|
const tertiary = getRandomHsl(otherColorParams);
|
||||||
|
primary.h = angle(+3 * goldenAngle + primary.h);
|
||||||
|
|
||||||
|
return {background, primary, secondary, tertiary};
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyTheme(theme: Theme) {
|
function applyTheme(theme: Theme) {
|
||||||
|
|
Loading…
Reference in a new issue