Added arcade machine hat blinking
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled

- Добавил моргание шапки автомата, пока игра не началась
- Исправил баг, что при бесплатной игре для продолжения требовалась оплата
This commit is contained in:
Данил Ярош 2026-01-22 09:59:17 +03:00
parent d95afbe445
commit b0a9b433c1
6 changed files with 83 additions and 1498 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1807,7 +1807,7 @@ MonoBehaviour:
m_HandleRect: {fileID: 434895585}
m_Direction: 2
m_Value: 0
m_Size: 0.9858968
m_Size: 0.9916019
m_NumberOfSteps: 0
m_OnValueChanged:
m_PersistentCalls:
@ -2099,7 +2099,7 @@ MonoBehaviour:
m_TargetGraphic: {fileID: 2040132803}
m_HandleRect: {fileID: 2040132802}
m_Direction: 0
m_Value: 1
m_Value: 0
m_Size: 0.99999994
m_NumberOfSteps: 0
m_OnValueChanged:
@ -4361,7 +4361,7 @@ MonoBehaviour:
m_HandleRect: {fileID: 1078381204}
m_Direction: 2
m_Value: 1
m_Size: 0.8630169
m_Size: 0.85431695
m_NumberOfSteps: 0
m_OnValueChanged:
m_PersistentCalls:
@ -11914,7 +11914,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: -0.000037980128}
m_AnchoredPosition: {x: 0, y: 0.00001012047}
m_SizeDelta: {x: 0, y: 300}
m_Pivot: {x: 0, y: 1}
--- !u!114 &1792218764
@ -13281,7 +13281,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.132, y: 0.21750003}
m_AnchorMax: {x: 0.846, y: 0.5}
m_AnchoredPosition: {x: -54.5, y: -79.00001}
m_AnchoredPosition: {x: -54.5, y: -79.000015}
m_SizeDelta: {x: -107, y: -63}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1959311160

View File

@ -1,10 +1,12 @@
using System;
using System.Text;
using System.Collections;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using RR.Game2D.Core.Managers;
using UnityEngine;
using UnityEngine.Events;
using Random = UnityEngine.Random;
namespace RR.Common.Controls
{
@ -25,7 +27,8 @@ namespace RR.Common.Controls
public static UnityEvent<string> OnInputReceived;
public static Action OnInitialize;
#region Приватные поля
#region Приватные поля
private const string REQUEST_INPUT = "91";
private const string LIGHTSIGNAL_PREFIX = "80";
@ -51,7 +54,10 @@ namespace RR.Common.Controls
// Кэш последнего состояния INPUT
// ВАЖНО: 0 = кнопка нажата, 1 = кнопка отпущена, поэтому по умолчанию все единицы
private static string lastInputBits = "11111111111111111111111111"; // 26 бит по умолчанию
#endregion
private Coroutine blinkingCoroutine;
#endregion
//===========================start: PUBLIC API===========================//
@ -81,6 +87,7 @@ namespace RR.Common.Controls
// Отправляем сигнал запуска игры
Send("2171");
Blink();
// Запускаем асинхронный опрос порта
pollCancellationTokenSource = new CancellationTokenSource();
@ -223,6 +230,20 @@ namespace RR.Common.Controls
return false;
}
public void Blink()
{
StopBlink();
blinkingCoroutine = StartCoroutine(BlinkingCoroutine());
}
public void StopBlink()
{
if (blinkingCoroutine != null) StopCoroutine(blinkingCoroutine);
}
/// <summary>
/// Получаем текущий баланс кредитов
@ -329,7 +350,7 @@ namespace RR.Common.Controls
// Обновляем кэш последнего состояния
lastInputBits = binaryValue;
GameManager.Logger.Log($"Decimal: {rawData} → Binary: {binaryValue}");
// Debug.Log($"Decimal: {rawData} → Binary: {binaryValue}");
OnInputReceived?.Invoke(binaryValue);
}
}
@ -355,24 +376,24 @@ namespace RR.Common.Controls
return new string(chars);
}
GameManager.Logger.Log($"Не удалось распарсить значение INPUT: {decimalString}");
Debug.Log($"Не удалось распарсить значение INPUT: {decimalString}");
return "11111111111111111111111111"; // 26 единиц по умолчанию
}
catch (Exception e)
{
GameManager.Logger.Log($"Ошибка преобразования в двоичную систему: {e.Message}");
Debug.Log($"Ошибка преобразования в двоичную систему: {e.Message}");
return "11111111111111111111111111"; // 26 единиц по умолчанию
}
}
/// <summary>
/// Получает пос<EFBFBD><EFBFBD>еднее кэшированное состояние INPUT.
/// Получает последнее кэшированное состояние INPUT.
/// Полезно когда нужно узнать состояние кнопок без ожидания нового события.
/// </summary>
/// <returns>Строка с двоичным представлением состояния кнопок</returns>
public static string GetLastInputState() => lastInputBits;
#region Приватные методы
#region Приватные методы
//Ну тут по дебаг логам все должно быть понятно
//Если интересно, то h - это хэндл. Что то на плюсовом, типа ID соединения или чтото. Если 0 то нету соед. если меньше то ошибка, больше 0 - норм.
private void initPort()
@ -608,6 +629,18 @@ namespace RR.Common.Controls
GameManager.Logger.Log($"Ошибка проверки соединения: {e.Message}");
}
}
private static IEnumerator BlinkingCoroutine()
{
while (true)
{
float randomFloat = Random.Range(0f, 1f);
Send(randomFloat < 0.5f ? "2130" : "2131");
yield return new WaitForSeconds(0.5f);
}
}
#endregion

View File

@ -1,6 +1,7 @@
using System;
using System.IO;
using RR.Common.Behaviour.ScriptableObjects;
using RR.Common.Controls;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.SceneManagement;
@ -26,6 +27,9 @@ namespace RR.Game2D.Core.Managers
// Payment control for game
public PaymentManager Payment {get; private set;}
// Plate control for game
public ComWrapper Plate { get; private set; }
// Globals
[Header("Globals")]
[SerializeField] private string globalsPrefabResourcePath = "Prefabs/Global/Globals";
@ -75,7 +79,7 @@ namespace RR.Game2D.Core.Managers
private static void Initialize()
{
if (Instance != null) return;
GameObject go = new GameObject(nameof(GameManager));
GameObject go = new(nameof(GameManager));
Instance = go.AddComponent<GameManager>();
go.AddComponent<AutoCursorHider>();
DontDestroyOnLoad(go);
@ -136,6 +140,11 @@ namespace RR.Game2D.Core.Managers
Payment = globals.GetComponent<PaymentManager>();
}
if (Plate == null)
{
Plate = globals.GetComponent<ComWrapper>();
}
Payment.OnCreditAdded.AddListener(OnCreditAdded);
_gameStartTime = Time.unscaledTime;
@ -247,12 +256,15 @@ public void TogglePause() => SetPause(!IsPaused);
LivesChanged?.Invoke(Lives);
Coins = 0;
CoinsChanged?.Invoke(Coins);
_gameStartTime = Time.time;
Logger.Log(gameObject.name,$"Game start time = {_gameStartTime}");
if (!Payment.IsFreePlayEnabled()) Payment.ProcessPayment(Payment.CreditsCount);
if (Plate) Plate.StopBlink();
LoadLevel(1, 1);
}
public void ContinueGame()
@ -357,12 +369,12 @@ public void TogglePause() => SetPause(!IsPaused);
SceneManager.LoadScene(sceneName);
if (useUI)
if (useUI) SceneManager.LoadScene("Level UI", LoadSceneMode.Additive);
else
{
SceneManager.LoadScene("Level UI", LoadSceneMode.Additive);
Plate.Blink();
_shouldSpawnPlayer = false;
}
else _shouldSpawnPlayer = false;
}
/// <summary>

View File

@ -104,7 +104,7 @@ namespace RR.Common.UI
if (continueButton)
{
continueButton.gameObject.SetActive(true);
continueButton.interactable = _paymentManager != null && _paymentManager.CreditsCount > 0;
continueButton.interactable = _paymentManager.IsFreePlayEnabled() || (_paymentManager != null && _paymentManager.CreditsCount > 0);
}
Open();