public void Render(Player player, List<Ball> balls, List<Monster> monsters) { Gdk.Window canvas = area.GdkWindow; if (canvas != null) { using (Cairo.Context context = Gdk.CairoHelper.Create (canvas)) { canvas.BeginPaintRegion (new Gdk.Region ()); context.SetSourceSurface (background, 0, 0); context.Paint (); foreach (Field field in player.Trail) { paintTrail (context, field.X * fieldSize, field.Y * fieldSize); } foreach (Ball ball in balls) { context.SetSourceRGB (1, 0, 0); paintCircle (context, ball.X, ball.Y); } foreach (Monster monster in monsters) { paintMonster (context, monster); } context.SetSourceRGB (0, 0, 1); paintPlayer (context, player); canvas.EndPaint (); } } }
// checks for player - level collisions, moves player out of colliding state if necessary private void correctPlayerPosition(Player player, Vector3 playerLastPosition) { // query collisions LinkedList<Vector3> arenaCollisions = new LinkedList<Vector3>(); LinkedList<Face> arenaCollidingFaces = new LinkedList<Face>(); mArena.CollisionData.collisions(player.boundingSphere, arenaCollidingFaces, arenaCollisions); if (arenaCollisions.Count == 0) return; // get average face normal of colliding faces, and average collision point Vector3 avgNormal = Vector3.Zero; Vector3 avgCollPt = Vector3.Zero; Vector3 closestNormal = Vector3.Zero; float closestDistance = float.MaxValue; LinkedListNode<Vector3> curNode = arenaCollisions.First; foreach (Face f in arenaCollidingFaces) { avgNormal += f.faceNormal; avgCollPt += curNode.Value; float d = (player.position - curNode.Value).LengthSquared(); if (d < closestDistance) { closestDistance = d; closestNormal = f.faceNormal; } curNode = curNode.Next; } // this can happen at very thin walls for example (two normals pointing in the opposite direction) if (avgNormal == Vector3.Zero) { avgNormal = closestNormal; } avgNormal.Normalize(); avgCollPt /= arenaCollisions.Count; // collision direction Vector3 avgColVec = player.position - avgCollPt; Vector3 r = Vector3.Normalize(-avgColVec); r *= player.boundingSphere.Radius; // move player out of colliding state player.position += (-r - avgColVec); }
Matrix[] mSpherePositionBuffer; // cache for model matrices of all simulated spheres #endregion Fields #region Constructors public BounceGame() { mGraphicsManager = new GraphicsDeviceManager(this); // define USE_PERFHUD to enable the use of perfhud on nvidia graphics cards #if USE_PERFHUD mGraphicsManager.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings); #endif Content.RootDirectory = "Content"; mPlayer = new Player(); mArena = new Arena(); mRenderer = new Renderer(); // default window size mGraphicsManager.PreferredBackBufferWidth = 1280; mGraphicsManager.PreferredBackBufferHeight = 720; mGraphicsManager.PreferMultiSampling = true; // predefined light positions mLightPositions = new Vector3[3]; mLightPositions[0] = new Vector3(843, 1986, -55); mLightPositions[1] = new Vector3(1865, 121, -21); mLightPositions[2] = new Vector3(0, 20, 00); mLightRotationY = 0.0f; // init player position and orientation to sensitive defaults mPlayer.position = new Vector3(0, 10, 0); mPlayer.rotationX = -0.0610865131f; mPlayer.rotationY = -1.6057024f; mSpherePositionBuffer = new Matrix[MaximumSimulatedSpheres]; mOverlay = new Overlay(); mCollidingFacesBuffer = new Dictionary<Face, uint>(); }
protected void paintPlayer(Cairo.Context context, Player player) { context.SetSourceRGB (0, 0, 1); paintArrow (context, player.Direction, player.X, player.Y); }
public void Clear() { balls = new List<Ball> (); monsters = new List<Monster> (); fields = new Field[Width, Height]; for (int i = 0; i < Width; i++) { for (int j = 0; j < Height; j++) { fields [i, j] = new Field (); if (i == 0 || j == 0 || i + 1 == Width || j + 1 == Height) { fields [i, j].Full = true; } else { fields [i, j].Full = false; } fields [i, j].X = i; fields [i, j].Y = j; } } Player = new Player (0, 0); Player.BaseField = fields [0, 0]; renderer.RefreshBackground (fields); }