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); } } } }
public void DrawRay(Block block, int x, double rayAngle, float dist, float textureX, Vector2 collision) { if (block == null) { return; } if (sprites.Count <= block.blockType) { return; } double height = viewDist / (dist * Math.Cos(player.angle - rayAngle)) + 1; int offsetHeight = (int)((GAME_HEIGHT - height) / 2 + headBob); float brightness = GetBrightness(collision.X, collision.Y); for (int y = (offsetHeight < 0) ? -offsetHeight : 0; y < height; y++) { if (y + offsetHeight > GAME_HEIGHT) { break; } TextureData sprite = sprites[block.blockType]; int pixelY = (int)(y / height * sprite.height); int pixelX = (int)(textureX * sprite.width); Color pixel = sprite.GetPixel(pixelX, pixelY); if (collision.X % 1 == 0) { TextureData.Darken(ref pixel, brightness * .9f); } else { TextureData.Darken(ref pixel, brightness); } ctx.SetPixel(x, y + offsetHeight, pixel); ctx.SetZIndex(x, y + offsetHeight, dist); } }
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); } } } }