Рефакторинг

This commit is contained in:
Сергей Бондарь 2026-07-20 11:35:39 +03:00
parent e97190be72
commit f02cdee36b
21 changed files with 752 additions and 361 deletions

View File

@ -0,0 +1,399 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &4478126490810938235
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2308229979791902274}
- component: {fileID: 2785177574404548980}
- component: {fileID: -5597252834244713330}
- component: {fileID: 4011524773098274618}
- component: {fileID: 8209685094204570851}
- component: {fileID: 581128120472889901}
m_Layer: 0
m_Name: ChipPrefab
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2308229979791902274
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4478126490810938235}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1.15, y: 1.15, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1661318112489111391}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!96 &2785177574404548980
TrailRenderer:
serializedVersion: 4
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4478126490810938235}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 0
m_LightProbeUsage: 0
m_ReflectionProbeUsage: 0
m_RayTracingMode: 0
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: fc368c70ff252e649adbbe3df84fdada, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: -5330059
m_SortingLayer: 2
m_SortingOrder: -1
m_MaskInteraction: 0
m_Time: 0.2
m_PreviewTimeScale: 1
m_Parameters:
serializedVersion: 3
widthMultiplier: 1
widthCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0.97508717
inSlope: -0.38808823
outSlope: -0.38808823
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0.99767745
- serializedVersion: 3
time: 1
value: 0.6
inSlope: -0.38939682
outSlope: -0.38939682
tangentMode: 0
weightedMode: 0
inWeight: 1
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
colorGradient:
serializedVersion: 2
key0: {r: 1, g: 0.47496206, b: 0, a: 1}
key1: {r: 1, g: 0.022731155, b: 0, a: 0}
key2: {r: 0, g: 0, b: 0, a: 0}
key3: {r: 0, g: 0, b: 0, a: 0}
key4: {r: 0, g: 0, b: 0, a: 0}
key5: {r: 0, g: 0, b: 0, a: 0}
key6: {r: 0, g: 0, b: 0, a: 0}
key7: {r: 0, g: 0, b: 0, a: 0}
ctime0: 0
ctime1: 65535
ctime2: 0
ctime3: 0
ctime4: 0
ctime5: 0
ctime6: 0
ctime7: 0
atime0: 0
atime1: 65535
atime2: 65535
atime3: 65535
atime4: 65535
atime5: 0
atime6: 0
atime7: 0
m_Mode: 0
m_ColorSpace: 0
m_NumColorKeys: 2
m_NumAlphaKeys: 2
numCornerVertices: 5
numCapVertices: 0
alignment: 0
textureMode: 0
textureScale: {x: 1, y: 1}
shadowBias: 0.5
generateLightingData: 0
m_MinVertexDistance: 0
m_Autodestruct: 0
m_Emitting: 1
m_ApplyActiveColorSpace: 1
--- !u!82 &-5597252834244713330
AudioSource:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4478126490810938235}
m_Enabled: 1
serializedVersion: 4
OutputAudioMixerGroup: {fileID: 0}
m_audioClip: {fileID: 0}
m_Resource: {fileID: 8300000, guid: 97356cb5584c41849a213dd28906602f, type: 3}
m_PlayOnAwake: 0
m_Volume: 1
m_Pitch: 1.2
Loop: 0
Mute: 0
Spatialize: 0
SpatializePostEffects: 0
Priority: 128
DopplerLevel: 1
MinDistance: 1
MaxDistance: 500
Pan2D: 0
rolloffMode: 0
BypassEffects: 0
BypassListenerEffects: 0
BypassReverbZones: 0
rolloffCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
panLevelCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
spreadCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
reverbZoneMixCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
--- !u!114 &4011524773098274618
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4478126490810938235}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5a33d20e192d63748be8104592f6ef66, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!54 &8209685094204570851
Rigidbody:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4478126490810938235}
serializedVersion: 5
m_Mass: 1
m_LinearDamping: 0
m_AngularDamping: 0.05
m_CenterOfMass: {x: 0, y: 0, z: 0}
m_InertiaTensor: {x: 1, y: 1, z: 1}
m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_ImplicitCom: 1
m_ImplicitTensor: 1
m_UseGravity: 1
m_IsKinematic: 1
m_Interpolate: 0
m_Constraints: 0
m_CollisionDetection: 0
--- !u!114 &581128120472889901
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4478126490810938235}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: aa727783246783d45abdace8138c97fd, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Chip
linearSpeed: 50
acceleration: 200
--- !u!1 &7100645357252458328
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1661318112489111391}
- component: {fileID: 5157516706225878083}
m_Layer: 0
m_Name: image
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1661318112489111391
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7100645357252458328}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2308229979791902274}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &5157516706225878083
SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7100645357252458328}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 0
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: -5330059
m_SortingLayer: 2
m_SortingOrder: 0
m_MaskInteraction: 0
m_Sprite: {fileID: 21300000, guid: 8d6432ff047c62946a41e3235f28ba57, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 1.6384, y: 1.6384}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_SpriteSortPoint: 0

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c349c741ed95e864ca8d5b3217c40598
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -6672,22 +6672,18 @@ MonoBehaviour:
Rows: 5
Cols: 6
botsAmount: 5
boardVersion: 1
stateMachine: {fileID: 259182281}
slotLeftTop: {fileID: 687989434}
board: {fileID: 1551328426}
AdminPanel: {fileID: 581100730}
NumberPanel: {fileID: 1124603895}
SettingsPointer: {fileID: 334401357}
timerManager: {fileID: 259182288}
rulesController: {fileID: 454272343}
chipPointer: {fileID: 1615046714}
gameMode: 0
coinPanel: {fileID: 1407544274}
board: {fileID: 1551328425}
boardTransform: {fileID: 1551328425}
noPrizeLabel: {fileID: 1796045835}
mainMenu: {fileID: 1122363131}
menuUi: {fileID: 1122363136}
russo_font: {fileID: 11400000, guid: 3f10bbcf486189d4f95b8de6dc2e2177, type: 2}
player1score: 0
player2score: 0
vsBotScore: 0
@ -6699,11 +6695,9 @@ MonoBehaviour:
player1Chip: {fileID: 4478126490810938235, guid: 1e042d6979719a240abdf06769829f7f, type: 3}
player2Chip: {fileID: 4478126490810938235, guid: 376ff57f7b90bd845a887cfd6ba95427, type: 3}
botChip: {fileID: 4478126490810938235, guid: afe8782fb49b2254cbdae76f1a9f22a8, type: 3}
chipPrefab: {fileID: 581128120472889901, guid: c349c741ed95e864ca8d5b3217c40598, type: 3}
currentChip: {fileID: 0}
selectedPanel: {fileID: 1304898661, guid: bff7731f029e97345b55849f0e330c32, type: 3}
deselectedPanel: {fileID: 1744797893, guid: 93e5f9833bed0474cb1481410d00191c, type: 3}
EngamePanel: {fileID: 347852021}
TimerImage: {fileID: 0}
smallPrizesOut: {fileID: 1279805983}
ReplayButton: {fileID: 1482394973}
MenuButton: {fileID: 2055613808}
@ -6714,16 +6708,11 @@ MonoBehaviour:
winPanel: {fileID: 1029921558}
currentPlayer: 1
currentColumnIndex: 0
stepX: 1.444
stepY: 1.48
startY: 5
moveMade: 0
chipXSpeed: 50
chipYSpeed: 0
chipAcceleration: 200
nameInput: {fileID: 1956417153}
ValutaNameInput: {fileID: 5418903569610246314}
specialPrizeInput: {fileID: 0}
NumberTech: {fileID: 1596344490}
pricePveInput: {fileID: 7215466293005402346}
pricePvpInput: {fileID: 2019841221}
@ -6733,8 +6722,6 @@ MonoBehaviour:
valutaPerPulseInput: {fileID: 483216802}
leaderboard: {fileID: 1784614873}
CharactersConfigurator: {fileID: 141381088}
fastCheckCounters: {fileID: 0}
checkQrPanel: {fileID: 1614501702}
avatarController: {fileID: 1851050354}
pvpPointer: {fileID: 492468475}
movesAndTimeCounter: {fileID: 1039507332}
@ -53287,6 +53274,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 1551328425}
- component: {fileID: 1551328426}
m_Layer: 0
m_Name: Board
m_TagString: Untagged
@ -53322,6 +53310,22 @@ Transform:
- {fileID: 1304043906}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1551328426
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1551328423}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 040b26fb5ec466e4893b26086fd3f23f, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Board
topLeftCell: {fileID: 687989434}
pointer: {fileID: 1615046714}
cellOffset: {x: 1.444, y: 1.48}
stickedY: 5
--- !u!1 &1556574614
GameObject:
m_ObjectHideFlags: 0

View File

@ -3,7 +3,6 @@ using UnityEngine;
public class BotThinkingState : IState
{
Thread calcThread;
int calculatedColumn = -1;
float startTime;
@ -40,9 +39,8 @@ public class BotThinkingState : IState
}
int movesMade = GameManager.instance.GetMovesCount();
int movesMade = GameManager.instance.board.MovesCount;
currentPreset = currentPreset.GetPreset(movesMade);
//Debug.Log("Ходов: " + movesMade + " Пресет: " + currentPreset.Description);
Solver.SetPreset(currentPreset);
@ -93,14 +91,10 @@ public class BotThinkingState : IState
if (animationStarted && Time.time - startAnimTime > animLength)
{
//ставим фишку в расчитанную колонку (подготовка к следующему состоянию)
GameManager.instance.currentColumnIndex = calculatedColumn;
float targetY = GameManager.instance.startY;
float targetX = GameManager.instance.slotLeftTop.position.x +
GameManager.instance.currentColumnIndex *
GameManager.instance.stepX;
Vector2 targetPosition = new Vector2(targetX, targetY);
Vector2 targetPosition = GameManager.instance.board.GetStickedPosition(calculatedColumn);
targetPosition += Vector2.up * 5;
GameManager.instance.currentChip.transform.position = new Vector2(targetX, targetY + 5);
GameManager.instance.currentChip.transform.position = targetPosition;
GameManager.instance.stateMachine.ChangeState(new ChipFallingState(0, calculatedColumn));
}
}
@ -117,12 +111,12 @@ public class BotThinkingState : IState
bool NeedSuperPreset = OnBossByScore && (IsHardCommonDifficulty || IsUpperCashDifficulty);
if (NeedSuperPreset)
{
calculatedColumn = SolverV2.FindBestMove(GameManager.fieldModel.FieldArray, GameManager.instance.currentPlayer);
calculatedColumn = SolverV2.FindBestMove(gm.board.GridToTeam(), GameManager.instance.currentPlayer);
}
else
{
calculatedColumn = Solver.FindBestMove(GameManager.fieldModel.FieldArray, GameManager.instance.currentPlayer);
calculatedColumn = Solver.FindBestMove(gm.board.GridToTeam(), GameManager.instance.currentPlayer);
}
}
}
}

View File

@ -2,46 +2,36 @@
using UnityEngine;
public class ChipFallingState : IState
{
const float MAX_ANGULAR_SPEED = 500;
int rowIndex;
int targetRow;
int targetColumn;
float angularSpeed;
float velocityY = 0;
Vector2 targetPosition;
Transform chipTransform;
Chip chip;
float startDelay = 0;
bool delayCompleted = false;
private GameManager gm;
public ChipFallingState(float startDelay, int col)
public ChipFallingState(float startDelay, int column)
{
gm = GameManager.instance;
chip = gm.currentChip;
this.startDelay = startDelay;
targetColumn = col;
rowIndex = GameManager.fieldModel.GetColumnHeight(targetColumn);
}
private Vector2 CalculateTargetPosition()
{
float targetX = gm.slotLeftTop.position.x + targetColumn * gm.stepX;
float targetY = gm.slotLeftTop.transform.position.y - GameManager.instance.stepY * rowIndex;
return new Vector2(targetX, targetY);
this.targetColumn = column;
this.targetRow = gm.board.GetLowestEmptyRow(column);
}
public void enter()
{
targetPosition = CalculateTargetPosition();
GameManager.instance.StartCoroutine(DelayedEnter(startDelay));
}
private void CacheFields()
{
chipTransform = GameManager.instance.currentChip.transform;
angularSpeed = Random.Range(-MAX_ANGULAR_SPEED, MAX_ANGULAR_SPEED);
gm.StartCoroutine(DelayedEnter(startDelay));
chip.SetRandomRotationSpeed();
targetPosition = gm.board.GetTargetPosition(targetColumn);
}
private void PrepareForFalling()
{
chipTransform.GetComponent<TrailRenderer>().enabled = true;
chip.GetComponent<TrailRenderer>().enabled = true;
}
private void InitialSound() => SoundManager.instance.playDropDown();
@ -49,34 +39,25 @@ public class ChipFallingState : IState
{
if (!delayCompleted) return;
ChipFallProcess();
bool reachedTarget = chip.MoveToAccelerated(targetPosition);
chip.Rotate();
if (chipTransform.position.y == targetPosition.y)
if (reachedTarget)
{
chipTransform.GetComponent<TrailRenderer>().emitting = false;
chip.GetComponent<TrailRenderer>().emitting = false;
SoundManager.instance.playChipBounce();
CompleteChipLanding();
}
}
private void ChipFallProcess()
{
velocityY += GameManager.instance.chipAcceleration * Time.deltaTime;
float delta = velocityY * Time.deltaTime;
chipTransform.position = Vector2.MoveTowards(chipTransform.position, targetPosition, delta);
chipTransform.transform.Rotate(0, 0, angularSpeed * Time.deltaTime);
}
private void CompleteChipLanding()
{
chipTransform.position = targetPosition;
GameManager.fieldModel.FieldArray[rowIndex, targetColumn] = GameManager.instance.currentPlayer;
GameManager.instance.setChipTransformToArray(rowIndex, targetColumn, chipTransform);
GameManager.instance.board.AttachChipToGrid(chip, targetColumn, targetRow);
StateRouter.RouteAfterTurn();
}
public void exit()
{
velocityY = 0;
AnnouncePlayerTurn();
}
@ -92,7 +73,6 @@ public class ChipFallingState : IState
{
yield return new WaitForSeconds(startDelay);
CacheFields();
PrepareForFalling();
InitialSound();

View File

@ -1,58 +0,0 @@
using UnityEngine;
public static class FieldCleaner
{
const string SORTLAYER_BACKGROUND = "Background";
const float EXPLOSION_FORCE = 30;
static readonly Vector3 EXPLOSION_ORIGIN = new Vector3(0, -2, -5);
const float EXPLOSION_RADIUS = 50;
const float TIME_TO_DESTROY = 5;
static Transform[,] field;
//передаем переходим мы в меню или нет. Если нет, то переход отсюда в новый раунд
//Надо еще сделать в конструкторе чтобы nextState указывать а то ж непонятно вообще
public static void Clear()
{
field = GameManager.instance.chipTransforms;
SoundManager.instance.playExplosion();
if (GameManager.instance.currentChip != null)
{
Object.Destroy(GameManager.instance.currentChip);
}
GameManager.fieldModel.makeEmptyField(width: GameManager.instance.Cols, height: GameManager.instance.Rows);
GameManager.instance.chipTransforms = new Transform[GameManager.instance.Rows, GameManager.instance.Cols];
Explode();
}
private static void Explode()
{
for (int i = 0; i < GameManager.instance.Rows; i++)
{
for (int j = 0; j < GameManager.instance.Cols; j++)
{
Transform chipTransform = field[i, j];
if (chipTransform != null)
{
Rigidbody rb = chipTransform.GetComponent<Rigidbody>();
rb.isKinematic = false;
rb.AddExplosionForce(EXPLOSION_FORCE, EXPLOSION_ORIGIN, EXPLOSION_RADIUS, upwardsModifier: 1, ForceMode.Impulse);
chipTransform.GetComponent<TrailRenderer>().sortingLayerName = SORTLAYER_BACKGROUND;
chipTransform.GetChild(0).GetComponent<SpriteRenderer>().sortingLayerName = SORTLAYER_BACKGROUND;
Object.Destroy(chipTransform.gameObject, TIME_TO_DESTROY + Random.Range(-1f, 1f));//чтобы уничтожались не одновременно
}
}
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ae3604a5803730846bbf06830500a11e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -34,8 +34,7 @@ public class LeaderboardState : IState
if (In.GetButtonDownAnyPlayer(PlayerAction.left) && In.GetButtonDownAnyPlayer(PlayerAction.right))
{
FieldCleaner.Clear();
//GameManager.instance.stateMachine.ChangeState(new MenuState(fromGameplay: true));
GameManager.instance.board.MakeClearField();
GameManager.instance.stateMachine.ChangeState(new MenuState());
}
}

View File

@ -1,49 +1,59 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
public class PositioningState : IState
{
GameManager gm;
GameObject chip;
private GameManager gm;
private Chip chip;
private Board board;
private ChipPointer pointer;
int index;
int position;
bool chipOnPosition;
private int indexValidArr;
private int columnIndex;
private bool chipOnPosition;
private int[] validPositions;
const int DEFAULT_SPEED = 50;
List<int> validPositions;
private Vector2 stickedPosition;
private Vector2 targetPosition;
public void enter()
{
gm = GameManager.instance;
board = gm.board;
pointer = gm.chipPointer;
validPositions = board.GetNonFullColumns();
int centralIndex = validPositions.Length / 2;
indexValidArr = centralIndex;
columnIndex = validPositions[centralIndex];
stickedPosition = board.GetStickedPosition(validPositions[indexValidArr]);
targetPosition = board.GetTargetPosition(validPositions[indexValidArr]);
chip = gm.currentChip;
chip.transform.position = stickedPosition;
chipOnPosition = true;
validPositions = GameManager.fieldModel.CollectNonFullCols();
pointer.Show();
pointer.SetColorByPlayer(gm.currentPlayer);
pointer.SetPosition(targetPosition);
int centralIndex = validPositions.Count / 2;
index = centralIndex;
position = validPositions[centralIndex];
gm.currentColumnIndex = validPositions[centralIndex];
if (gm.gameMode == GameMode.pvp)
{
gm.pvpPointer.SetColor(gm.currentPlayer);
gm.pvpPointer.SetVisibility(true);
gm.pvpPointer.MoveTo(stickedPosition);
}
float offsety = gm.startY;
if (gm.gameMode == GameMode.pvp) offsety = gm.startY + 5;//повыше
float x = gm.slotLeftTop.position.x + validPositions[index] * gm.stepX;
float y = gm.startY + offsety;
chip.transform.position = new Vector3(x, y, 0);
chip.SetActive(true);
gm.chipPointer.Show();
gm.chipPointer.SetColorByPlayer(gm.currentPlayer);
if (gm.gameMode == GameMode.pve)
gm.StartVsBotTimer();
}
public void exit()
{
gm.pvpPointer.SetVisibility(false);
gm.chipPointer.Hide();
gm.StopVsBotTimer();
pointer.Hide();
}
public void update()
@ -51,29 +61,9 @@ public class PositioningState : IState
// вычисление ввода в зависимости от игрового режима
var input = GetInputs();
if (gm.gameMode == GameMode.pve) gm.vsBotThinkTime += Time.deltaTime;
HandleChipMovement(input.direction);
Vector2 stickedPosition = GetStickedPosition();
Vector2 targetPosition = GetTargetPosition();
gm.chipPointer.SetPosition(targetPosition);
if (gm.gameMode == GameMode.pvp)
{
gm.pvpPointer.SetColor(gm.currentPlayer);
gm.pvpPointer.SetVisibility(true);
gm.pvpPointer.MoveTo(stickedPosition);
stickedPosition += Vector2.up * 5;//повыше
}
chip.transform.position = Vector2.MoveTowards(chip.transform.position, stickedPosition, DEFAULT_SPEED * Time.deltaTime);
if ((Vector2)chip.transform.position == stickedPosition)
chipOnPosition = true;
else
chipOnPosition = false;
chipOnPosition = chip.MoveToLinear(stickedPosition);
if (HandleDrop(input.action)) return;
if (HandleExitToMenu()) return;
@ -81,23 +71,30 @@ public class PositioningState : IState
private void HandleChipMovement(int direction)
{
if (!chipOnPosition) return;
if (direction == 0 || !chipOnPosition) return;
indexValidArr += direction;
indexValidArr = Mathf.Clamp(indexValidArr, 0, validPositions.Length - 1);
columnIndex = validPositions[indexValidArr];
stickedPosition = gm.board.GetStickedPosition(columnIndex);
targetPosition = gm.board.GetTargetPosition(columnIndex);
//перемещение указателей
pointer.SetPosition(targetPosition);
if (gm.gameMode == GameMode.pvp)
gm.pvpPointer.MoveTo(stickedPosition);
index = Mathf.Clamp(index + direction, 0, validPositions.Count - 1);
int prevPos = position;
position = validPositions[index];
int dist = Mathf.Abs(position - prevPos);
gm.chipXSpeed = dist * DEFAULT_SPEED;//скорость зануляется
gm.currentColumnIndex = position;
SoundManager.instance.playSwitch();
}
private bool HandleExitToMenu()
{
bool exitPressed = In.GetButtonDown(ButtonPinMapping.startOnePlayer) || In.GetButtonDown(ButtonPinMapping.startTwoPlayers);
if (exitPressed && !gm.moveMade)
if (exitPressed && gm.canReturnToMenu)
{
FieldCleaner.Clear();
gm.board.MakeClearField();
PaymentSystem.ReturnCredits(gm.gameMode);
GameManager.instance.timerManager.StopAllTimers();
GameManager.instance.stateMachine.ChangeState(new MenuState());
@ -110,49 +107,27 @@ public class PositioningState : IState
{
if (!action) return false;
//todo: посмотреть нахуя currentColumnIndex зарыто в gm. разрыть.
bool canDropInCurrentColumn = GameManager.fieldModel.GetColumnHeight(gm.currentColumnIndex) != -1;
bool canDropInCurrentColumn = board.CanDrop(columnIndex);
if (!(chipOnPosition && canDropInCurrentColumn))
{
SoundManager.instance.playWrong();
return false;
}
float delayBeforeStartFalling = 0;
if (gm.gameMode == GameMode.pve) gm.vsBotMoves += 1;
float delayBeforeStartFalling = 0;
if (gm.gameMode == GameMode.pvp)
{
AvatarEventBus.Instance.OnTurnEnd?.Invoke(gm.currentPlayer);
delayBeforeStartFalling = DualAvatarController.Instance.CurrentAvatar.ChipSpawnTime;
}
gm.moveMade = true;
Vector2 targetPosition = GetTargetPosition();
gm.stateMachine.ChangeState(new ChipFallingState(startDelay: delayBeforeStartFalling, gm.currentColumnIndex));
gm.canReturnToMenu = false;
gm.stateMachine.ChangeState(new ChipFallingState(startDelay: delayBeforeStartFalling, columnIndex));
return true;
}
private Vector2 GetStickedPosition()
{
float targetX = gm.slotLeftTop.position.x +
gm.currentColumnIndex *
gm.stepX;
float targetY = gm.startY;
return new Vector2(targetX, targetY);
}
private Vector2 GetTargetPosition()
{
float targetX = gm.slotLeftTop.position.x +
gm.currentColumnIndex *
gm.stepX;
float targetY = GameManager.instance.slotLeftTop.transform.position.y - GameManager.instance.stepY * GameManager.fieldModel.GetColumnHeight(gm.currentColumnIndex);
return new Vector2(targetX, targetY);
}
private (int direction, bool action) GetInputs()
{
bool left = false,

View File

@ -8,15 +8,8 @@ public class ShowWinnerState : IState
Color empty = new Color(0, 0, 0, 0);
CoinCounter coinCounter;
private GameManager gm;
GameManager GameManager
{
get
{
if (gm == null) gm = GameManager.instance;
return gm;
}
}
private GameManager gm = GameManager.instance;
public enum ShowWinnerSubstates { PanelFalling, HandlingInputs, PanelRising, ExitByTime }
public ShowWinnerSubstates subState;
@ -35,7 +28,7 @@ public class ShowWinnerState : IState
List<SpriteRenderer> winningChips;
Color orange = new Color(1, 0.537794f, 0, 1f);
Color blue = new Color(0, 0.7181487f, 1, 0.5f);
TextMeshProUGUI TimerLabel;
TextMeshProUGUI ToMenuLabel;
@ -48,7 +41,7 @@ public class ShowWinnerState : IState
public ShowWinnerState()
{
this.result = GameManager.lastResult;
this.result = gm.lastResult;
subState = ShowWinnerSubstates.PanelFalling;
GameManager.instance.ToMenuLabel.gameObject.SetActive(true);
}
@ -61,22 +54,22 @@ public class ShowWinnerState : IState
public void enter()
{
coinCounter = GameObject.FindAnyObjectByType<CoinCounter>();
ToMenuLabel = GameManager.ToMenuLabel;
TimerLabel = GameManager.TimerLabel;
ToMenuLabel = gm.ToMenuLabel;
TimerLabel = gm.TimerLabel;
//таймер
GameManager.timerManager.StopAllTimers();
gm.timerManager.StopAllTimers();
panel = GameManager.EngamePanel;
left = GameManager.ReplayButton;
right = GameManager.MenuButton;
panel = gm.EngamePanel;
left = gm.ReplayButton;
right = gm.MenuButton;
InitPanel();
if (result.Draw)
{
GameManager.DrawVisual.Show();
gm.DrawVisual.Show();
}
if (GameManager.gameMode == GameMode.pvp)
if (gm.gameMode == GameMode.pvp)
{
if (!result.Draw)
{
@ -84,39 +77,39 @@ public class ShowWinnerState : IState
winningChips = new List<SpriteRenderer>();
CollectChipsList(result);
if (GameManager.player1score == 5)//полная победа 1 игрока
if (gm.player1score == 5)//полная победа 1 игрока
{
//обнулить очки и выдать приз
GameManager.player1score = 0;
GameManager.player2score = 0;
gm.player1score = 0;
gm.player2score = 0;
//переход в приз
}
else if (GameManager.player2score == 5)//полная победа 2 игрока
else if (gm.player2score == 5)//полная победа 2 игрока
{
//обнулить очки и выдать приз
GameManager.player1score = 0;
GameManager.player2score = 0;
gm.player1score = 0;
gm.player2score = 0;
//переход в приз
}
}
}
else if (GameManager.gameMode == GameMode.pve)
else if (gm.gameMode == GameMode.pve)
{
if (!result.Draw)
{
winningChips = new List<SpriteRenderer>();
CollectChipsList(result);
if (GameManager.currentPlayer == CellState.Player1)//Последный держал фишку игрок
if (gm.currentPlayer == CellState.Player1)//Последный держал фишку игрок
{
if (GameManager.vsBotScore == 5)//5 побед над ботом
if (gm.vsBotScore == 5)//5 побед над ботом
{
GameManager.vsBotScore = 0;
gm.vsBotScore = 0;
}
}
}
@ -129,7 +122,7 @@ public class ShowWinnerState : IState
ToMenuLabel.gameObject.SetActive(false);
if (result.Draw)
{
GameManager.DrawVisual.Hide();
gm.DrawVisual.Hide();
return;
}
//вернуть альфу фишкам
@ -179,7 +172,7 @@ public class ShowWinnerState : IState
//чистимся и топаем дальше в след раунд
FieldCleaner.Clear();
gm.board.MakeClearField();
//Фишка ходит первой если ее не побеждали сегодня еще
//текущий бот - последний
@ -239,7 +232,7 @@ public class ShowWinnerState : IState
if (panel.localPosition == targetUpPosition)//панель дошла до верха
{
if (GameManager.lastResult != null && !GameManager.lastResult.Draw)
if (gm.lastResult != null && !gm.lastResult.Draw)
{
foreach (SpriteRenderer chip in winningChips)
{
@ -250,16 +243,16 @@ public class ShowWinnerState : IState
switch (option)
{
case EndOption.Restart://чистим поле и перезапуск. Меняем игрока
AvatarEventBus.Instance.OnNewRoundStarted?.Invoke(GameManager.currentPlayer);
FieldCleaner.Clear();
AvatarEventBus.Instance.OnNewRoundStarted?.Invoke(gm.currentPlayer);
gm.board.MakeClearField();
CellState nextPlayer = GameManager.currentPlayer == CellState.Player1 ? CellState.Player2 : CellState.Player1;
CellState nextPlayer = gm.currentPlayer == CellState.Player1 ? CellState.Player2 : CellState.Player1;
gm.PrepareRound(nextPlayer);
break;
case EndOption.Menu://чистим поле и переходим в меню с параметром чтобы панельки съехались обратно
CharacterController.HideCharacter();
DualAvatarController.Instance.HideCharacters();
FieldCleaner.Clear();
gm.board.MakeClearField();
//GameManager.instance.stateMachine.ChangeState(new MenuState(fromGameplay: true));
GameManager.instance.stateMachine.ChangeState(new MenuState());
break;
@ -343,12 +336,12 @@ public class ShowWinnerState : IState
right.transform.GetChild(0).GetComponent<Image>().color = empty;
GameManager.RestartButton.text = NeedToPay ? "Еще раз!" : "Продолжить!";
gm.RestartButton.text = NeedToPay ? "Еще раз!" : "Продолжить!";
}
private void DropPanel()
{
panel = GameManager.EngamePanel;
panel = gm.EngamePanel;
panel.transform.localPosition = Vector3.MoveTowards(panel.transform.localPosition, targetDownPosition, speedY * Time.deltaTime);
speedY += acceleration * Time.deltaTime;
@ -370,8 +363,8 @@ public class ShowWinnerState : IState
foreach (var index in result.WinningIndexes)
{
GameManager.chipTransforms[index.row, index.col].rotation = Quaternion.identity;
var renderer = GameManager.chipTransforms[index.row, index.col].GetChild(0).GetComponent<SpriteRenderer>();
gm.chipTransforms[index.row, index.col].rotation = Quaternion.identity;
var renderer = gm.chipTransforms[index.row, index.col].GetChild(0).GetComponent<SpriteRenderer>();
winningChips.Add(renderer);
renderer.gameObject.AddComponent<SinRotator>().speed = 8;
}

View File

@ -6,7 +6,7 @@ public static class StateRouter
private static GameManager gm => GameManager.instance;
public static void RouteAfterTurn()
{
var checkResult = GameManager.fieldModel.Check(GameManager.instance.currentPlayer);
var checkResult = FieldChecker.Check(GameManager.instance.currentPlayer);
gm.lastResult = checkResult;//это неправильно. Нужно при проверке записывать в поле.
TurnEndingResult turnResult = EndOfTurnHandler.Evaluate(checkResult, gm.gameMode, gm.currentPlayer);
@ -149,7 +149,7 @@ public static class StateRouter
public static IState ToMenu()
{
FieldCleaner.Clear();
gm.board.MakeClearField();
return new MenuState();
}

View File

@ -15,8 +15,7 @@ public class GameManager : MonoBehaviour
[Header("General")]
public GameStateMachine stateMachine;
public Transform slotLeftTop;
public static FieldModel fieldModel;
public Board board;
public static GameManager instance;
public GameObject AdminPanel, NumberPanel;
public TimerManager timerManager;
@ -28,7 +27,7 @@ public class GameManager : MonoBehaviour
public GameMode gameMode;
public Transform
coinPanel,
board,
boardTransform,
noPrizeLabel;
public UiManager menuUi;
@ -36,6 +35,7 @@ public class GameManager : MonoBehaviour
[Header("Scores")]
public int player1score = 0, player2score = 0, vsBotScore = 0;
private bool increaseVsBotTimer = false;
public int vsBotMoves;
public float vsBotThinkTime;
@ -49,7 +49,8 @@ public class GameManager : MonoBehaviour
public GameObject player1Chip;
public GameObject player2Chip;
public GameObject botChip;
[HideInInspector] public GameObject currentChip;
public Chip chipPrefab;
[HideInInspector] public Chip currentChip;
public RectTransform EngamePanel;
public RectTransform smallPrizesOut;
@ -64,15 +65,8 @@ public class GameManager : MonoBehaviour
[HideInInspector] public CellState currentPlayer = CellState.Player2;
public int currentColumnIndex = 0;
public float stepX = 1.215f;
public float stepY = 1.24f;
public float startY;
public bool moveMade = false;
public float chipXSpeed = 10,
chipAcceleration = 20;
public bool canReturnToMenu = false; //todo: разобраться нафига эта переменная
public Transform[,] chipTransforms;
@ -111,15 +105,13 @@ public class GameManager : MonoBehaviour
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
Instantiate(new GameObject()).AddComponent(typeof(VfxPrefab));
soundManager.Initialize();
if (instance == null)
{
Application.targetFrameRate = DEFAULT_FRAME_RATE;
instance = this;
fieldModel = new FieldModel(Cols, Rows);
board.Init(Cols, Rows);
chipTransforms = new Transform[Rows, Cols];
}
@ -138,7 +130,6 @@ public class GameManager : MonoBehaviour
ComWrapper.PaymentReceived += ProcessDifficultyCounter;
SettingsManager.OnSettingsChanged.AddListener(ProcessDifficultyCounter);
soundManager.Initialize();
GetComponent<NotificationSystem>().Initialize();
@ -256,9 +247,9 @@ public class GameManager : MonoBehaviour
}
#if UNITY_EDITOR
private void Update()
{
#if UNITY_EDITOR
if (Input.GetKeyDown(KeyCode.G))
{
PrizeSystemManager.GivePrize(PrizeUtils.CreatePrize(CountablePrizeType.Hopper, 1));
@ -267,8 +258,12 @@ public class GameManager : MonoBehaviour
{
PlayerPrefs.SetInt("PrizeGivenBuffer", 1);
}
}
#endif
if (increaseVsBotTimer) vsBotThinkTime += Time.deltaTime;
}
public void StartVsBotTimer() => increaseVsBotTimer = true;
public void StopVsBotTimer() => increaseVsBotTimer = false;
public void SetupCoinPanel()
@ -285,7 +280,8 @@ public class GameManager : MonoBehaviour
chipToSpawn = currentPlayer == CellState.Player1 ? player1Chip : botChip;
currentChip = Instantiate(chipToSpawn, new Vector2(0, 20), Quaternion.identity);
currentChip = Instantiate(chipPrefab, new Vector2(0, 20), Quaternion.identity);
currentChip.Team = currentPlayer;
if (currentPlayer == CellState.Player2)
currentChip.GetComponentInChildren<SpriteRenderer>().sprite = CharacterController.CurrentChipImage;
}
@ -346,22 +342,6 @@ public class GameManager : MonoBehaviour
}
}
public int GetMovesCount()
{
if (chipTransforms == null) return 0;
int count = 0;
int rows = chipTransforms.GetLength(0);
int cols = chipTransforms.GetLength(1);
for (int r = 0; r < rows; r++)
for (int c = 0; c < cols; c++)
if (chipTransforms[r, c] != null)
count++;
return count;
}
public void ProcessDifficultyCounter()//вызывается каждый раз, когда приходит COIN с платы или обновились настройки
{
string previous = PlayerPrefs.GetString("PreviousBaseBotDifficulty", "Обычная");
@ -445,6 +425,7 @@ public class GameManager : MonoBehaviour
public void ResetGameSession()
{
vsBotThinkTime = 0;
StopVsBotTimer();
vsBotMoves = 0;
movesAndTimeCounter.SetVisibility(false);
@ -460,7 +441,7 @@ public class GameManager : MonoBehaviour
VitrinaView.Instance.Deactivate();
moveMade = false;
canReturnToMenu = true;
}
IEnumerator AddBotRecordEvery2Days()
@ -481,4 +462,6 @@ public class GameManager : MonoBehaviour
}
}
}

View File

@ -54,7 +54,6 @@ public class SoundManager : MonoBehaviour
{
Destroy(gameObject);
}
Instantiate(new GameObject()).AddComponent(typeof(VfxPrefab));
}
private void Start()

View File

@ -19,15 +19,15 @@ public class BackToMenuButton : MonoBehaviour
{
canvasGroup = GetComponent<CanvasGroup>();
gm = GameManager.instance;
ActualState = gm.moveMade;
ActualState = !gm.canReturnToMenu;
}
void Update()
{
if (ActualState != gm.moveMade)
if (ActualState == gm.canReturnToMenu)
{
ActualState = gm.moveMade;
ActualState = !gm.canReturnToMenu;
StopAllCoroutines();
StartCoroutine(changeState());
}

View File

@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using UnityEngine;
public class Board : MonoBehaviour
{
//визуал
[SerializeField] Transform topLeftCell;
[SerializeField] ChipPointer pointer;
[SerializeField] Vector2 cellOffset = new(1.444f, 1.48f);
[SerializeField] float stickedY = 5f;
//состояние
public int columns;
public int rows;
public Chip[,] grid;
public int MovesCount => GetMovesCount();
public void Init(int columns, int rows)
{
this.columns = columns;
this.rows = rows;
MakeClearField();
}
public Vector2 GetStickedPosition(int column) => new Vector2(GetXPosition(column), stickedY);
public Vector2 GetTargetPosition(int column) => new Vector2(GetXPosition(column), GetYPosition(column));
public void MakeClearField()
{
PerformClear();
grid = new Chip[columns, rows];
}
public bool CanDrop(int column) => grid[column, 0] == null;
public void AttachChipToGrid(Chip chip, int column, int row)
{
if (column < 0 || column >= columns)
{
Debug.LogError($"Попытка поставить фишку в колонку {column}. Колонок: {columns}");
return;
}
if (row < 0 || row >= rows)
{
Debug.LogError($"Попытка поставить фишку в ряд {row}. Рядов: {rows}");
return;
}
grid[column, row] = chip;
}
public int[] GetNonFullColumns()
{
List<int> temp = new();
for (int column = 0; column < columns; column++)
if (CanDrop(column))
temp.Add(column);
return temp.ToArray();
}
public int GetLowestEmptyRow(int colIndex)
{
if (colIndex < 0 || colIndex >= columns)
throw new ArgumentOutOfRangeException($"Попытка проверить колонку {colIndex}. Колонок: {columns}");
for (int row = rows - 1; row >= 0; row--)
if (grid[colIndex, row] == null)
return row;
return -1;
}
private float GetXPosition(int column) => topLeftCell.position.x + cellOffset.x * column;
private float GetYPosition(int column) => topLeftCell.position.y - GetLowestEmptyRow(column) * cellOffset.y;
private void PerformClear()
{
SoundManager.instance.playExplosion();
GameManager.instance.currentChip?.RemoveFromField();
if (grid == null) return;
foreach (Chip chip in grid)
chip?.RemoveFromField();
}
private int GetMovesCount()
{
if (grid == null) return 0;
int count = 0;
foreach (Chip chip in grid)
if (chip != null) count++;
return count;
}
public CellState[,] GridToTeam()
{
CellState[,] res = new CellState[columns, rows];
for (int col = 0; col < columns; col++)
{
for (int row = 0; row < rows; row++)
{
var chip = grid[col, row];
if (chip == null) res[col, row] = CellState.Empty;
else res[col, row] = chip.Team;
}
}
return res;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 040b26fb5ec466e4893b26086fd3f23f

View File

@ -0,0 +1,42 @@
using UnityEngine;
public class Chip : MonoBehaviour
{
public CellState Team;
[SerializeField] float linearSpeed = 50f;
[SerializeField] float acceleration = 200f;
[SerializeField] float maxFallingRotationSpeed = 500;
private float chipVelocity = 0;
private float rotationSpeed = 0;
public virtual void RemoveFromField()
{
Destroy(gameObject);
}
public bool MoveToLinear(Vector2 target)
{
transform.position = Vector2.MoveTowards(transform.position, target, linearSpeed * Time.deltaTime);
if((Vector2)transform.position == target)
return true;
return false;
}
public bool MoveToAccelerated(Vector2 target)
{
transform.position = Vector2.MoveTowards(transform.position, target, chipVelocity * Time.deltaTime);
chipVelocity += acceleration * Time.deltaTime;
if ((Vector2)transform.position == target)
{
acceleration = 0;
return true;
}
return false;
}
public void SetRandomRotationSpeed() => rotationSpeed = Random.Range(-maxFallingRotationSpeed, maxFallingRotationSpeed);
public void Rotate() => transform.Rotate(Vector3.forward * rotationSpeed * Time.deltaTime);
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: aa727783246783d45abdace8138c97fd

View File

@ -5,29 +5,15 @@ public enum CellState
{
Empty, Player1, Player2
}
public class FieldModel
public static class FieldChecker
{
//двумерный массив для поля
public CellState[,] FieldArray;
public int Height;
public int Width;
public int TargetLineLength = 4;
static GameManager gm => GameManager.instance;
public static Chip[,] FieldArray => gm.board.grid;
public static int Height => gm.board.rows;
public static int Width => gm.board.columns;
public static int TargetLineLength = 4;
public FieldModel(int width, int height)
{
//0 индекс для строк, 1 индекс для столбцов
Width = width;
Height = height;
makeEmptyField(width, height);
}
public void makeEmptyField(int width, int height)
{
FieldArray = new CellState[height, width];
Array.Clear(FieldArray, 0, FieldArray.Length);
}
public CheckResult Check(CellState lastPlayer)
public static CheckResult Check(CellState lastPlayer)
{
HashSet<(int row, int col)> WinningIndexes = new();
@ -55,7 +41,7 @@ public class FieldModel
isDraw: true,
WinningIndexes);
}
else
else
{
return new CheckResult(end: false,
isDraw: false,
@ -65,7 +51,7 @@ public class FieldModel
}
private (bool hasWin, HashSet<(int row, int col)> winningIndexes) checkAllRows(CellState targetCellState)
private static (bool hasWin, HashSet<(int row, int col)> winningIndexes) checkAllRows(CellState targetTeam)
{
var winningCells = new HashSet<(int row, int col)>();
@ -76,7 +62,8 @@ public class FieldModel
for (int col = 0; col <= Width; col++) // теперь проходим до Width включительно
{
// Проверяем, не вышли ли за границы массива
bool isMatch = col < Width && FieldArray[row, col] == targetCellState;
var chip = FieldArray[col, row];
bool isMatch = col < Width && chip != null && chip.Team == targetTeam;
if (isMatch && start == -1)
start = col;
@ -96,7 +83,7 @@ public class FieldModel
return (winningCells.Count > 0, winningCells);
}
private (bool hasWin, HashSet<(int row, int col)> winningIndexes) checkAllColumns(CellState targetCellState)
private static (bool hasWin, HashSet<(int row, int col)> winningIndexes) checkAllColumns(CellState targetTeam)
{
var winningCells = new HashSet<(int row, int col)>();
@ -106,7 +93,8 @@ public class FieldModel
for (int row = 0; row <= Height; row++)
{
bool isMatch = row < Height && FieldArray[row, col] == targetCellState;
var chip = FieldArray[col, row];
bool isMatch = row < Height && chip != null && chip.Team == targetTeam;
if (isMatch && start == -1)
start = row;
@ -127,7 +115,7 @@ public class FieldModel
return (winningCells.Count > 0, winningCells);
}
private (bool hasWin, HashSet<(int row, int col)> winningIndexes) checkAllDiagonals(CellState targetCellState)
private static (bool hasWin, HashSet<(int row, int col)> winningIndexes) checkAllDiagonals(CellState targetCellState)
{
var winningCells = new HashSet<(int row, int col)>();
@ -154,7 +142,7 @@ public class FieldModel
return (winningCells.Count > 0, winningCells);
}
private void CheckDiagonalStartingAt(int startRow, int startCol, int rowStep, int colStep,
private static void CheckDiagonalStartingAt(int startRow, int startCol, int rowStep, int colStep,
CellState targetCellState, HashSet<(int, int)> winningCells)
{
int rows = Height;
@ -168,7 +156,8 @@ public class FieldModel
while (currentRow >= 0 && currentRow < rows &&
currentCol >= 0 && currentCol < cols)
{
bool isMatch = FieldArray[currentRow, currentCol] == targetCellState;
var chip = FieldArray[currentCol, currentRow];
bool isMatch = chip != null && chip.Team == targetCellState;
if (isMatch)
{
@ -196,35 +185,13 @@ public class FieldModel
currentCol += colStep;
}
}
public int GetColumnHeight(int colIndex)
{
for (int row = Height - 1; row >= 0; row--)
{
if (FieldArray[row, colIndex] == CellState.Empty)
{
return row;
}
}
return -1;//если не нашли, то больше добавить нельзя
}
public bool checkDraw()
public static bool checkDraw()
{
for (int col = 0; col < Width; col++)
{
if (GetColumnHeight(col) != -1) return false;
if (gm.board.GetLowestEmptyRow(col) != -1) return false;
}
return true;
}
public List<int> CollectNonFullCols()
{
var positions = new List<int>();
for (int i = 0; i < Width; i++)
if (GetColumnHeight(i) != -1)
positions.Add(i);
return positions;
}
}
}

View File

@ -83,7 +83,7 @@ public class UiManager : MonoBehaviour
while (parametr < 1)
{
parametr += Time.deltaTime * 2;
gm.board.localPosition = Vector3.Lerp(sBoard, eBoard, parametr);
gm.boardTransform.localPosition = Vector3.Lerp(sBoard, eBoard, parametr);
gm.noPrizeLabel.localPosition = Vector3.Lerp(sNoPrize + Vector2.left * 3500, eNoPrize, parametr);
yield return null;
@ -107,7 +107,7 @@ public class UiManager : MonoBehaviour
float parametr = 1;
while (parametr >= 0)
{
gm.board.localPosition = Vector3.Lerp(sBoard, eBoard, parametr);
gm.boardTransform.localPosition = Vector3.Lerp(sBoard, eBoard, parametr);
gm.noPrizeLabel.localPosition = Vector3.Lerp(eNoPrize + Vector2.left * 3500, eNoPrize, parametr);
parametr -= Time.deltaTime * 2;
yield return null;