Make an ASCII bat fly around an ASCII moon

05AB1E, 69 62 60 bytes

Saved 2 bytes thanks to Adnan.

3ð×…^o^)U13FNV0379730vð5y>;ï-y_+×N(Y-12%_Xè'my×NY-12%_y&XèJ,

Try it online!

Explanation

3ð×…^o^)U stores the list [" ","^o^"] in X for later use.

13FNV loops over the 13 stages [0 .. 12] and stores the current iteration index in Y.

0379730v loops over the rows of each stage,
where N is the row index and y is the current number of m's.

We start by adding floor(5/(y+1))-(y==0) spaces to each row with ð5y>;ï-y_+×.

We then determine if there should be a bat or 3 spaces before the m's.
If (-N-Y)%12 == 0 is true we add a bat, else 3 spaces.
This expression (N(Y-12%_Xè) will place bats in stages 0,6-12.

Then we place y m's with 'my×.

Now we determine if there should be a bat or 3 spaces after the m's.
The code NY-12%_y&Xè will place a bat if ((N-Y)%12 == 0) and y!=0 is true, else 3 spaces.
This will place the bats on stages 1-5.

Finally we join the whole row into a string and print with a newline: J,.


JavaScript (ES6), 109 144 140 138 bytes

f=(k=13,b=y=>(y-k)%12?'   ':'^o^')=>k--?[0,3,7,9,7,3,0].map((n,y)=>' '.repeat(5-n/2+!n)+b(y)+'m'.repeat(n)+b(n?-y:.1)).join`
`+`
`+f(k):''

console.log(f());

Animated version

f=(k,b=y=>(y-k)%12?'   ':'^o^')=>[0,3,7,9,7,3,0].map((n,y)=>' '.repeat(5-n/2+!n)+b(-y)+'m'.repeat(n)+b(n?y:.1)).join`
`

var k =0;
setInterval(function() { o.innerHTML = f(k++) }, 150);
<pre id=o></pre>


HTML+JS, 153 149 bytes

n=setInterval(_=>o.innerText=`zzd
zc3e
 b7f
a9g
 l7h
zk3i
zzj`.replace(/\S/g,c=>parseInt(c,36)-n%12-10?`m`.repeat(c)||`   `:`^o^`,n++),1e3)
<pre id=o>

Edit: Saved a bunch of bytes thanks to @RickHitchcock. The boring version that just returns the 13 multiline strings in an array is 132 131 bytes:

_=>[...Array(13)].map((_,n)=>`zza
zl3b
 k7c
j9d
 i7e
zh3f
zzg`.replace(/\S/g,c=>parseInt(c,36)-n%12-10?`m`.repeat(c)||`   `:`^o^`))