public void UpdateMapShader() { var game = GameObject.FindObjectOfType <Game>(); var map = GameObject.FindObjectOfType <Map>(); MapShader.SetInt("Width", map.Width); MapShader.SetInt("Height", map.Height); var PlayerDirs = new List <float>(); var MapPixels = GetMapTilePixels(map.Width, map.Height); var GamePixels = GetGameTilePixels(map.Width, map.Height); var TempColour = new Color32(0, 0, 0, 1); System.Action <int2, PopperMan.Tile> SetMapTile = (int2 xy, PopperMan.Tile Tile) => { TempColour.r = (byte)Tile; MapPixels [(xy.y * _MapTiles.width) + xy.x] = TempColour; }; System.Action <int2, PopperMan.Tile> SetGameTile = (int2 xy, PopperMan.Tile Tile) => { TempColour.r = (byte)Tile; GamePixels [(xy.y * _GameTiles.width) + xy.x] = TempColour; }; map.ForEachTile((Tile, xy) => { SetMapTile(xy, Tile); } ); { var xy = new int2(0, 0); for (xy.y = 0; xy.y < map.Height; xy.y++) { for (xy.x = 0; xy.x < map.Width; xy.x++) { SetGameTile(xy, PopperMan.Tile.None); } } foreach (var Player in game.Players) { var PlayerIndex = game.Players.IndexOf(Player); var GameTile = PopperMan.GetPlayerTile(PlayerIndex); SetGameTile(Player.xy, GameTile); } } /* * ForEachTile * for ( int i=0; i<map.Width*map.Height; i++ ) * { * var xy = map.GetMapXy(i); * var MapTile = map[xy]; * var GameTile = PopperMan.Tile.None; * * { * var Player = game.GetPlayerAt(xy); * if ( Player ) * { * var PlayerIndex = game.Players.IndexOf(Player); * GameTile = PopperMan.GetPlayerTile(PlayerIndex); * } * } * * SetMapTile (xy, MapTile); * SetGameTile (xy, GameTile); * } */ for (int i = 0; i < game.Players.Count; i++) { var Player = game.Players[i]; if (Player.Alive) { PlayerDirs.Add((float)Player.Direction); } else { PlayerDirs.Add(DIR_DEAD); } } _MapTiles.SetPixels32(MapPixels); _GameTiles.SetPixels32(GamePixels); _MapTiles.Apply(); _GameTiles.Apply(); MapShader.SetTexture("MapTiles", _MapTiles); MapShader.SetTexture("GameTiles", _GameTiles); MapShader.SetFloatArray("PlayerDirs", PlayerDirs); var ShakeOffset = new Vector4(ExplodeShakeX.Evaluate(ShakeTime), ExplodeShakeX.Evaluate(ShakeTime), 0, 0); MapShader.SetVector("ShakeOffset", ShakeOffset); #if UNITY_EDITOR { if (!Application.isPlaying) { UnityEditor.SceneView.RepaintAll(); } } #endif }
public void Tick() { if (Frame == 0) { OnGameStart.Invoke(); } Frame++; // move each player var map = GameObject.FindObjectOfType <Map>(); // pre-calc all player new-head positions for head-head collision var OldPlayerHeads = new int2[Players.Count]; var NewPlayerHeads = new int2[Players.Count]; for (int p = 0; p < Players.Count; p++) { var player = Players[p]; var NewPos = player.xy; NewPos.x += PopperMan.GetDelta(player.Direction).x; NewPos.y += PopperMan.GetDelta(player.Direction).y; OldPlayerHeads [p] = player.xy; NewPlayerHeads [p] = NewPos; } // find map crashes var MapCollision = new bool[Players.Count]; for (int p = 0; p < Players.Count; p++) { var MapTile = map [NewPlayerHeads[p]]; var Crash = (MapTile != PopperMan.Tile.Floor); MapCollision[p] = Crash; // the current/last frame head hasn't been written to the map, but we still need to collide with it for (int q = 0; q < Players.Count; q++) { if (p == q) { continue; } if (NewPlayerHeads [p] == OldPlayerHeads [q]) { MapCollision [p] = true; } } } // find head-head coliisoins var HeadCollision = new bool[Players.Count]; for (int p = 0; p < Players.Count; p++) { for (int q = p + 1; q < Players.Count; q++) { if (!Players [p].Alive) { continue; } if (!Players [q].Alive) { continue; } var Collision = NewPlayerHeads [p] == NewPlayerHeads [q]; if (Collision) { Debug.Log("Collision between " + p + " and " + q); } HeadCollision[p] |= Collision; HeadCollision[q] |= Collision; } } // kill players for (int p = 0; p < Players.Count; p++) { var player = Players [p]; if (!player.Alive) { continue; } var Collision = HeadCollision [p] || MapCollision [p]; if (!Collision) { continue; } player.Alive = false; if (HeadCollision [p]) { OnPlayerHeadbutt.Invoke(player); } else { OnPlayerExplode.Invoke(player); } // erase from map var PlayerTile = PopperMan.GetPlayerTile(p); map.ForEachTile((Tile, xy) => { if (Tile != PlayerTile) { return; } map [xy] = PopperMan.Tile.Floor; } ); } // move live players for (int p = 0; p < Players.Count; p++) { var player = Players [p]; if (player.Alive) { // burn old pos to map try { map [player.xy] = PopperMan.GetPlayerTile(p); } catch {}; player.xy = NewPlayerHeads [p]; } } // detect end of game { int AliveCount = 0; int AlivePlayer = -1; for (int p = 0; p < Players.Count; p++) { var player = Players [p]; player.ClearInput(); if (player.Alive) { AliveCount++; AlivePlayer = p; } } if (AliveCount == 0) { EndGame_Draw(); } else if (AliveCount == 1) { EndGame_Win(Players [AlivePlayer]); } } OnTickEnd.Invoke(); }