IMO anything, ANYTHING you can do in OOP you can do procedureally.
However, for me, OOP comes into its own on larger projects. I definately agree with those who would question its use on small programs unless they were intended as the building blocks for classes that would be used in larger programs.
To build big you really need structure & code re-use.
In gaming terms, and to give a practical example one might think of something like a Sprite "object".
It would be defined to have certain "properties" or "member variables" including the bitmap that represents it.
It would probably have Position coords, Velocities, a Collision bounding box rectangle etc. It might also have its own Update() and Draw() methods where it could be programmed to display itself on a given (or global) device/surface/whatever. You would build your sprite bit by bit, testing each aspect as you go.
You have this working class now and you're writing a new (bigger) game but you need more functionality in your sprite, say the ability to animate the bitmap image or/and calcule the collision bounds in different way.
A procedural approach might be to go back to the original (working) code and tinker with it, possibly breaking something else down the chain. Or, worse, a copy might be made of the original functions and THEN tinkered with to add the new functionality. As soon as you do this you'll lose control.
In OOP you would just subclasss your (working) sprite class and Add new "properties" & methods or "Override" existing ones. Thus you get the best of both worlds - you have a codebase you can depend on, but it's not "ring fenced" you can still subclass and create new types of Sprite to extend and enhance the abilities of the object.
Much later you discover a bug in the code of your base Sprite class. This bug once discovered has been seen in all the games you've used your Sprite or subclasses of it. With OOP you can be confident that if you change the code in just one place, and test just one Sprite object successfully that all other sprites will inherit this bug fix. This saves you time both in fixing the bug and in testing the fix.
So, one might think of the ancient "Lucy" as an Abstract Data Type, or rather the first instance of an ADT, which with each generation was subclassed down the generations to us, all being subclasses of the original (working) version (but different and unique). If some subclasses had bugs in where they had overridden methods of the original to do things their own sweet way, then natural selection saw them off. Only the Subclasses that improved on the original design would flourish
lol
"My ignorance amuses me..."
http://www.victory-road.co.uk