You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

135 lines
3.5 KiB

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.Width / 2 * 0.9f;
private readonly float borderSummand = Dimensions.Singleton.Width / 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.Width / 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.boardBottom,
Side.Top => Dimensions.Singleton.boardTop,
_ => 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;
};
}
private void OnCollisionEnter2D(Collision2D other) {
other.gameObject.GetComponent<Ball>().LastContactPlayer = this;
}
}
public class RealPlayer : Player {
public bool isThisClient;
private void FixedUpdate() {
if (!isThisClient)
return;
var keyboard = Keyboard.current;
//goingLeft = keyboard.aKey.isPressed;
//goingRight = keyboard.dKey.isPressed;
TryLinearMove(Time.fixedDeltaTime);
}
}
}