Congratulations for having progressed so far.
Context, first analysis
Your explanation:
I am using a z-buffer, with one stored length to a wall for the x coordinate of each ray.
Means the z-buffer is currently one-dimension.
One dimension is enough in the first case (your first two images) but not in the second case. To see why, imagine that the red tomato sprite was closer to the player, such that the left half of it would be partially obscured by the first wall (bottom left). Since the top of that wall is projected to a diagonal line, it means that the property "is pixel P of the sprite obscured?" does not only depend on X but also on Y.
So, in the exact setup you have, a 1D Z-buffer is definitely not capable of performing the clipping you want.
Options
From that on, here are a few options:
- switch to a 2D z-buffer (slower)
- switch to painter's algorithm (slower)
- switch to a 2D-based occlusion algorithm
- study how Doom did it
Your geometry seems similar to Doom. It is probably a very good investment for you to study how the Doom rendering engine works. It clips sprites (called "things") using a 1D criterion, then refines. One area has only one floor height and one ceiling height. This is very important and it looks like your geometry is similar.
Solution
The solution, to summarize, is to keep not only a 1D z-buffer, but actually a structure keeping for each sector (in doom parlance) the lines that make the limit and their parameters (like the a and b in y=ax+b).
Then, when you want to draw the sprite, clip X with 1D criterion but depending on the sector the sprite is in, and then limit the Y range of pixels drawn based on the y=ax+b of the sector just in front of it.
I don't know what data structure you currently have in your program. If this seems totally unreachable, then you need to rethink the data structure you keep while drawing.
If you haven't yet, you should read (sorry if you did already) https://doomwiki.org/wiki/Doom_rendering_engine#Rendering and the pages behind the links there, perhaps run their code in slow motion or see a video where someone shows/explains how it works. This one lacks explanations but might help your intuition: https://www.youtube.com/watch?v=gfM6NpxmVGg .
Hope this helps. Keep up the good work!