|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using Unity.Netcode;
|
|
|
|
using UnityEngine;
|
|
|
|
using UnityEngine.InputSystem;
|
|
|
|
using UnityEngine.UIElements;
|
|
|
|
|
|
|
|
namespace Game {
|
|
|
|
|
|
|
|
public enum Side {Top, Bottom}
|
|
|
|
|
|
|
|
public class Player : NetworkBehaviour {
|
|
|
|
|
|
|
|
public Side Side { get; set; }
|
|
|
|
|
|
|
|
protected bool goingLeft, goingRight;
|
|
|
|
|
|
|
|
public VisualElement Panel { get; private set; }
|
|
|
|
|
|
|
|
public List<ActiveModification> Modifications { get; } = new();
|
|
|
|
|
|
|
|
private int Score { get; set; }
|
|
|
|
|
|
|
|
// Units per second
|
|
|
|
private const float BaseSpeed = 15;
|
|
|
|
private const float SpeedMultiplier = 1.5f;
|
|
|
|
protected float Speed {
|
|
|
|
get {
|
|
|
|
return Modifications.Where(m => m.Properties.effect == ModEffect.Speed)
|
|
|
|
.Aggregate(BaseSpeed, (current, speedMod) => current * speedMod.Properties.type switch {
|
|
|
|
ModType.Buff => SpeedMultiplier,
|
|
|
|
ModType.Nerf => 1 / SpeedMultiplier,
|
|
|
|
_ => throw new ArgumentOutOfRangeException()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unit distance from zero
|
|
|
|
private readonly float baseBorder = Dimensions.Singleton.PlaySize.x / 2 * 0.9f;
|
|
|
|
private readonly float borderSummand = Dimensions.Singleton.PlaySize.x / 2 * 0.1f;
|
|
|
|
protected float Border {
|
|
|
|
get {
|
|
|
|
return Mathf.Min(Modifications.Where(m => m.Properties.effect == ModEffect.Border)
|
|
|
|
.Aggregate(baseBorder, (current, borderMod) => current + borderMod.Properties.type switch {
|
|
|
|
ModType.Buff => borderSummand,
|
|
|
|
ModType.Nerf => -borderSummand,
|
|
|
|
_ => throw new ArgumentOutOfRangeException()
|
|
|
|
}),
|
|
|
|
Dimensions.Singleton.PlaySize.x / 2
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected float Width => transform.localScale.x;
|
|
|
|
|
|
|
|
private float LeftEdge => X - Width / 2;
|
|
|
|
private float RightEdge => X + Width / 2;
|
|
|
|
|
|
|
|
protected float X => transform.position.x;
|
|
|
|
|
|
|
|
protected float Y => transform.position.y;
|
|
|
|
|
|
|
|
public void GainScore() {
|
|
|
|
Score++;
|
|
|
|
UpdatePanel();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void UpdatePanel() {
|
|
|
|
Panel.Q<TextElement>("score").text = Score.ToString();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void ClampInsideBorders() {
|
|
|
|
if (LeftEdge < -Border)
|
|
|
|
transform.Translate(Vector2.right * (-Border - LeftEdge), Space.World);
|
|
|
|
if (RightEdge > Border)
|
|
|
|
transform.Translate(Vector2.left * (RightEdge - Border), Space.World);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void TryLinearMove(float h) {
|
|
|
|
Vector2 trans = new Vector2((goingLeft ? -1 : 0) + (goingRight ? 1 : 0), 0);
|
|
|
|
trans *= Speed * h;
|
|
|
|
transform.Translate(trans, Space.World);
|
|
|
|
ClampInsideBorders();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void Start() {
|
|
|
|
float y = Side switch {
|
|
|
|
Side.Bottom => -Dimensions.Singleton.PlaySizeBoards.y / 2,
|
|
|
|
Side.Top => Dimensions.Singleton.PlaySizeBoards.y / 2,
|
|
|
|
_ => throw new ArgumentOutOfRangeException()
|
|
|
|
};
|
|
|
|
transform.position = new Vector2(0, y);
|
|
|
|
if (Side == Side.Top)
|
|
|
|
transform.Rotate(transform.forward, 180);
|
|
|
|
Panel = GameUI.Singleton.PlayerPanel(Side);
|
|
|
|
UpdatePanel();
|
|
|
|
GameUI.Singleton.buttonDown += (side, direction) => {
|
|
|
|
if (!side.Equals(Side))
|
|
|
|
return;
|
|
|
|
if (direction == "left")
|
|
|
|
goingLeft = true;
|
|
|
|
else
|
|
|
|
goingRight = true;
|
|
|
|
};
|
|
|
|
GameUI.Singleton.buttonUp += (side, direction) => {
|
|
|
|
if (!side.Equals(Side))
|
|
|
|
return;
|
|
|
|
if (direction == "left")
|
|
|
|
goingLeft = false;
|
|
|
|
else
|
|
|
|
goingRight = false;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class RealPlayer : Player {
|
|
|
|
public bool isThisClient;
|
|
|
|
|
|
|
|
private void FixedUpdate() {
|
|
|
|
if (!isThisClient)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (Application.isEditor) {
|
|
|
|
var keyboard = Keyboard.current;
|
|
|
|
goingLeft = keyboard.aKey.isPressed;
|
|
|
|
goingRight = keyboard.dKey.isPressed;
|
|
|
|
}
|
|
|
|
|
|
|
|
TryLinearMove(Time.fixedDeltaTime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|