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 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 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); } } } }