public virtual void Draw(TextureData ctx, Entity player, int headBob) { // sprite doesnt exist for this entity if (CoreGame.sprites.Count <= id) return; TextureData spriteData = CoreGame.sprites[id]; // Translate position to viewer space Vector2 dist = pos - player.pos; float distance = dist.Length(); // Sprite angle relative to viewing angle double spriteAngle = Math.Atan2(dist.Y, dist.X) - player.angle; // Size of the sprite int size = (int)(CoreGame.viewDist / (Math.Cos(spriteAngle) * distance)); // X-position on screen int left = (int)(Math.Tan(spriteAngle) * CoreGame.viewDist); left = (CoreGame.GAME_WIDTH / 2 + left - size / 2); int top = (CoreGame.GAME_HEIGHT - size) / 2 + headBob; for(int x = (left < 0) ? -left : 0; x < size; x++) { if (x + left >= CoreGame.GAME_WIDTH) break; for (int y = (top < 0) ? -top : 0; y < size; y++) { if (y + top >= CoreGame.GAME_HEIGHT) break; int pixelX = x * spriteData.width / size; int pixelY = y * spriteData.height / size; Color pixel = spriteData.GetPixel(pixelX, pixelY); // draw if the alpha is greater than zero if(pixel.A > 0) ctx.SetPixel(x + left, y + top, distance, pixel); } } }
void SendSprite(TextureData sprite, IPEndPoint IP) { //sprite data byte[] spriteData = sprite.GetBytes(); // protocol size + sprite size byte[] message = new byte[1 + spriteData.Length]; //protocol message[0] = (byte)Protocol.SEND_SPRITE; // data spriteData.CopyTo(message, 1); //send data NewConnections.Send(message, message.Length, IP); }
private void Listen() { while (manager.Available > 0) { try { byte[] response = manager.Receive(ref HostIP); //new update lastUpdate = 0; byte protocol = response[0]; response = response.Skip(1).ToArray(); switch (protocol) { case (byte)Protocol.UPDATE_ID: Dungeon.task = "UPDATING CLIENT ID"; id = BitConverter.ToInt32(response, 0); break; case (byte)Protocol.UPDATE_ENTITY_DATA: Dungeon.task = "FETCHING ENTITIES"; UpdateEntities(response); break; case (byte)Protocol.MAP_CHANGE: Dungeon.task = "UPDATING DUNGEON"; Dungeon.LoadFromData(response); Input.lockMouse = true; loading = false; break; case (byte)Protocol.UPDATE_PLAYER: Dungeon.task = "GETTING PLAYER DATA"; player.CopyBytes(response); break; case (byte)Protocol.SEND_SPRITE: Dungeon.task = "DOWNLOADING ASSETS"; TextureData data = new TextureData(response); sprites.Add(data); spriteNames.Add("?"); break; } } catch (Exception) { } } }
void FloorCast(double rayAngle, int x) { Matrix transform = Matrix.CreateRotationZ((float)rayAngle); double offsetAngle = Math.Cos(player.angle - rayAngle); for (int y = -Math.Abs(headBob) - 1; y < GAME_HEIGHT / 2 + headBob; y++) { if (ctx.GetPixel(x, y + headBob) == Color.Transparent) { float slope = GAME_HEIGHT / 2 - y; Color roofPixel = Color.Black; Color floorPixel = Color.Black; float slopeIntercept = float.MaxValue; if (slope != 0) { Vector2 texturePos = Vector2.Zero; slopeIntercept = (float)(viewDist / 2 / slope / offsetAngle); texturePos.X = (float)(Math.Cos(rayAngle) * slopeIntercept); texturePos.Y = (float)(Math.Sin(rayAngle) * slopeIntercept); texturePos += player.pos; Block block = Dungeon.GetBlockAt(texturePos.X, texturePos.Y); float brightness = GetBrightness(texturePos.X, texturePos.Y); if (block != null) { if (block.blockType < sprites.Count) { texturePos.X %= 1; texturePos.Y %= 1; TextureData sprite = sprites [block.blockType]; int spriteX = (int)(texturePos.X * sprite.width); int spriteY = (int)(texturePos.Y * sprite.height); floorPixel = sprite.GetPixel(spriteX, spriteY); TextureData.Darken(ref floorPixel, brightness); spriteX = (int)(texturePos.X * roofTextureData.width); spriteY = (int)(texturePos.Y * roofTextureData.height); roofPixel = roofTextureData.GetPixel(spriteX, spriteY); TextureData.Darken(ref roofPixel, brightness); } } } ctx.SetPixel(x, y + headBob, roofPixel); ctx.SetZIndex(x, y + headBob, slopeIntercept); if (ctx.GetPixel(x, -y + headBob + GAME_HEIGHT - 2) == Color.Transparent) { ctx.SetPixel(x, -y + headBob + GAME_HEIGHT - 2, floorPixel); ctx.SetZIndex(x, -y + headBob + GAME_HEIGHT - 2, slopeIntercept); } } } }